[疑难] d语言如何处理声音?

l.yun 2009-06-14
最近小弟在学习d语言
现有一难题就是如何处理播放mp3 wav 等声音。
window linux 下有何不同?

还望不吝指教一二,感激不尽!
hurd 2009-06-14
libsdl的包装可以处理声音和跨平台。
http://www.dsource.org/projects/derelict
l.yun 2009-06-14
我去看看   
ideage 2009-06-14
我用Win32API:PlaySound函数.

PlaySound(songz ,null,SND_FILENAME | SND_SYNC);
bleet 2009-06-15
我也来关注一下
kuan 2009-06-21
使用SDL_MIXER或FMOD,這兩個庫都有C的接口,D語言是可以引用的.

以前寫的FMOD.d: http://kyovbdx.myweb.hinet.net/tutorials/D/lesson01/fmod.d(v3.7.3)
l.yun 2009-08-11

2009-08-11
D语言播放音乐

import derelict.sdl.sdl;
import derelict.sdl.mixer;

import tango.io.Stdout;
import tango.util.Convert;
import tango.stdc.stringz;
import tango.sys.win32.CodePage;


Mix_Music *music ;

char[][] musics;
int music_index;
bool isplaying = false;

void main() {
    Stdout("使用SDL_Mixer 进行音乐播放 支持mp3 ogg...").newline();
    Stdout("允许我打印这篇文章的出处  http://lyun.iteye.com").newline();
    Stdout("如有建议请发邮件到  liangyun.cn@gmail.com").newline();
    Stdout("good luck").newline();
    Stdout("==================优美的分隔线====================").newline();

    init();
    scope(exit) cleanup();  // when we exit, perform cleanup

    SDL_Surface *screen;
    SDL_Event event;

    int done = 0;

    /* We're going to be requesting certain things from our audio
    device, so we set them up beforehand */
    int audio_rate = 22050;
    Uint16 audio_format = AUDIO_S16; /* 16-bit stereo */
    int audio_channels = 2;
    int audio_buffers = 4096;


    /* This is where we open up our audio device.  Mix_OpenAudio takes
    as its parameters the audio format we'd /like/ to have. */
    if(Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers)) {
        Stdout("Unable to open audio!\n");
    }

    nextMusic();//马上进行播放下一曲

    /* We're going to be using a window onscreen to register keypresses
    in.  We don't really care what it has in it, since we're not
    doing graphics, so we'll just throw something up there. */
    screen = SDL_SetVideoMode(320, 240, 0, 0);
    while(!done) {
        while(SDL_PollEvent(&event)) {
            switch(event.type) {
                case SDL_QUIT:
                    done = 1;
                break;
                case SDL_KEYDOWN:
                case SDL_KEYUP:
                    //按下P键进行播放、暂停切换
                    if(event.key.keysym.sym==SDLK_p&&event.key.type == SDL_KEYDOWN) {
                        if(isplaying){
                            pauseMusic();
                        }else{
                            resumeMusic();
                        }
                    }
                break;
                default:
                break;
            }
        }

        /* So we don't hog the CPU */
        SDL_Delay(50);
    }

}

void init() {
    //load lib
    DerelictSDL.load();
    DerelictSDLMixer.load();

    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);

    musics = ["E:\\music\\mp3\\刘德华\\刘德华 - 我恨我痴心.mp3",
    "E:\\music\\mp3\\刘德华\\刘德华 - 笨小孩.mp3",
    "E:\\music\\mp3\\刘德华\\刘德华 - 孤星泪.mp3"];
    music_index = musics.length;

}

void cleanup() {
    // tell SDL to quit
    SDL_Quit();
    // release shared libs
    DerelictSDLMixer.unload();
    DerelictSDL.unload();
}


void playMusic(char[] file) {
    /********注意********/
    //SDL_Mixter的字符串的编码是ansi 但是d语言的默认编码是utf8,需要进行转码
    //将utf8编码转成ansi  使用tango.sys.win32.CodePage  这里只在win32下有效 linux请使用iconve
    //char[] temp = new char[file.length];
    //char[] result = CodePage.into(file,temp);
    //char * music_path = toStringz(result);
    char * music_path = toStringz(CodePage.into(file,new char[file.length]));

    /* Here we're going to have the 'm' key toggle the music on and
        off.  When it's on, it'll be loaded and 'music' will point to
        something valid.  If it's off, music will be NULL. */
    if(music == null) {
        /* Actually loads up the music */
        //music = Mix_LoadMUS("music.ogg");//可以播放
        //music = Mix_LoadMUS("music.mp3");//可以播放
        music = Mix_LoadMUS(music_path);
  
        SDL_Delay(100);
      
        if(music == null){
            Stdout(" 加载音乐失败! ").newline();
            Stdout(" 播放下一首! ").newline();
            nextMusic();
        }

        /* This begins playing the music - the first argument is a
           pointer to Mix_Music structure, and the second is how many
           times you want it to loop (use -1 for infinite, and 0 to
           have it just play once) */
        if(Mix_PlayMusic(music, 0)==-1){
            Stdout(" 播放音乐失败! ").newline();
            Stdout(" 播放下一首! ").newline();
            nextMusic();
        }

        /* We want to know when our music has stopped playing so we
           can free it up and set 'music' back to NULL.  SDL_Mixer
           provides us with a callback routine we can use to do
           exactly that */
        Mix_HookMusicFinished(&musicDone);

        isplaying = true;
    }

}

void pauseMusic() {
    isplaying = false;
    Mix_PauseMusic();
}

void resumeMusic(){
    Mix_ResumeMusic();
    isplaying =true;
}

void stopMusic(){
    if(music != null) {
        /* Stop the music from playing */
        Mix_HaltMusic();

        /* Unload the music from memory, since we don't need it anymore */
        Mix_FreeMusic(music);

        music = null;
    }
}

extern(C) void musicDone() {
        stopMusic() ;
        Stdout("play finished ").newline();
      
        Stdout("play next").newline();
        nextMusic();
}

void nextMusic(){
  
    if(music_index<musics.length-1)
    {
        music_index = music_index + 1;
        Stdout("next music ").newline();
    }
    else
    {
        music_index = 0;
        Stdout("back fist music ").newline();
    }
  
    Stdout("ready music:["~to!(char[])(music_index)~"/"~to!(char[])(musics.length) ~"] "~musics[music_index]).newline();

    playMusic(musics[music_index]);
  
}







//编译环境 dmd1.043 + tango 0.99.7 + dsss 0.75

//D类库 derelict

//C类库 sdl sdl_mixer


l.yun 2009-08-11
前段时间比较忙 这个星期专心的弄了下 可以播放了,谢谢大家的帮忙
lifc 2009-08-11
去年用D做过一个支持高清播放的家庭多媒体中心,调用gstreamer播放音、视频都比较方便,而且支持多种输入源的编码和采集。
Global site tag (gtag.js) - Google Analytics