-
2004-04-18
Winamp插件研究[转自CSDN] - [C++Builder技术文档]
版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
近来想做一个播放器,找了很久一直都找不到理想的解码器,不过最后还是想到winamp的插件。。。 [face10]既然winamp基于插件来完成解码,那么它就一定有解码器,只要找到它的接口就可以是使用了 去官方网站下载winamp的SDK,终于得知它的解码工作交给相应的Input插件模块。 在 Pulgin 文件夹中有很多的 DLL(动态链接库)文件,其中的in_mp3.dll就是mp3的解码插件,这个插件可以解码AAC/Mpeg1/mpeg2/mpeg3的音频,还有一个in_wm.dll自然就是解码WMA的了 从SDK文档中得知,每种插件都具有固定的数据结构,如Input模块的数据结构(In_Module ),Output模块的(Out_Module ),同时每种插件的dll都具有约定的入口函数,对于Input插件,其入口函数为 __declspec( dllexport ) In_Module * winampGetInModule2() 其结构体: typedef struct { int nVer; // 模块版本号 char *szDesc; //模块描述信息 HWND hMainWnd; // Winamp的主窗体句柄(由Winamp来填写) HINSTANCE hDllInstance; // DLL实例句柄(由Winamp来填写) char *szFileExt; // 扩展名过滤器,格式参见GetOpenFileName int nIsSeekable; // 是否可索引媒体,是-你可以拖动进度条,否-反之 int UsesOutputPlug; // 是否使用输出插件?你想在这个模块里搞定一切? // 下面都是函数指针,将被Winamp调用 void (*Config)(HWND hwndParent); // 配置对话框 void (*About)(HWND hwndParent); // 关于对话框 void (*Init)(); // 初始化 void (*Quit)(); // 退出 // szFile - 传入的文件名,szTitle - 传出的标题,nLen - 转出的时间长度,毫秒。 // 如果szFile传NULL,则返回当前播放文件的信息 void (*GetFileInfo)(char *szFile, char *szTitle, int *nLen); int (*InfoBox)(char *szFile, HWND hwndParent); // 弹出文件信息对话框 int (*IsOurFile)(char *szFile); // 检查文件格式 int (*Play)(char *szFile); // 开始播放文件szFile,返回0正常,-1错误 void (*Pause)(); // 暂停处理 void (*UnPause)(); // 取消暂停 int (*IsPaused)(); // 是否斩停?1是暂停,0不是 void (*Stop)(); // 停止播放 int (*GetLength)(); // 取得长度,毫秒单位 int (*GetOutputTime)(); // 获取当前时间,一般调用out模块的同名函数即可 void (*SetOutputTime)(int nTime); // 索引到某一时刻 void (*SetVolume)(int volume); // 音量调节,从0 - 255 void (*SetPan)(int pan); // 左右声道平衡,从-127 - 127 //下面的函数多和AVS、可视化效果、均衡器等有关,具体咱们用不到,就暂时不讲了。 void (*SAVSAInit)(int maxlatency_in_ms, int srate); void (*SAVSADeInit)(); // call in Stop() void (*SAAddPCMData)(void *PCMData, int nch, int bps, int timestamp); int (*SAGetMode)(); void (*SAAdd)(void *data, int timestamp, int csa); void (*VSAAddPCMData)(void *PCMData, int nch, int bps, int timestamp); int (*VSAGetMode)(int *specNch, int *waveNch); void (*VSAAdd)(void *data, int timestamp); void (*VSASetInfo)(int nch, int srate); int (*dsp_isactive)(); int (*dsp_dosamples)(short int *samples, int numsamples, int bps, int nch, int srate); void (*EQSet)(int on, char data[10], int preamp); void (*SetInfo)(int bitrate, int srate, int stereo, int synched); Out_Module *outMod; // 看看,Winamp终于露出马脚了吧? } In_Module; 这样通过这个入口函数,就可以轻易的得到了Input插件的 In_Module结构体,接下来的事情自然也就很容易了,有了这个结构体,插件的所有功能都可以调用了。 不过单凭这个Input插件还是不能放出声音来的,因为Input插件虽然能完成mp3或者WMA的解码,但却没有把他们输出来,所以,就得自己写输出模块。不过,winamp有个OutPut插件可以完成输出功能,这就是Out_Wave.dll,加上这个插件,那么播放mp3就非常容易了。 OutPut插件得入口函数 __declspec( dllexport ) Out_Module * winampGetOutModule() 其结构体为:Out_Module typedef struct { // 下面有些和In_Module一样,就不赘述了。 int nVer; char *szDesc; int nId; // 自己给一个ID,不知道有什么用,反正大于65536就行了。 HWND hMainWindow; HINSTANCE hDllInstance; void (*Config)(HWND hwndParent); void (*About)(HWND hwndParent); void (*Init)(); void (*Quit)(); // nSample - 采样率, nChannels - 声道数,1或2 // nBitPerSamp - 每采样的位率,nBufLen、nPreBufLen - 缓冲长度,咱们用不到 // 返回大于0正常播放,小于0失败 int (*Open)(int nSample, int nChannels, int nBitPerSamp, int nBufLen, int nPreBufLen); void (*Close)(); // 关闭输出设备 // pBuf - 内存数据块,nLen - 数据块的长度 int (*Write)(char *pBuf, int len); // 返回0成功
http://jiamingsoft.yourblog.org/logs/152294.html
随机文章:
BCB中管道应用示例 2005-09-03皮肤技术研究 2004-04-24LRC格式歌词分解程序 2004-04-11Unicode编码文件的读取 2004-04-11C语言写的贪吃蛇 2004-04-03
收藏到:Del.icio.us





