中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS开发编程 & 发展交流 (开发室) » 哪位懂WIN-TC(或TC2.0)加入音频播放的仁兄能不能帮一下忙?
作者:
标题: 哪位懂WIN-TC(或TC2.0)加入音频播放的仁兄能不能帮一下忙? 上一主题 | 下一主题
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『楼 主』:  哪位懂WIN-TC(或TC2.0)加入音频播放的仁兄能不能帮一下忙?

哪位懂WIN-TC(或TC2.0)加入音频播放的仁兄能不能帮一下忙? 这几天用WINTC做了个小程序,急需加入WAV音频,但WINTC TC没有音频函数,下了ALLEGRO,但好象要在DJGPP下,我没用过,现在又很急, 弄了个NEO SDK , 仅仅单独播放音频可以,但加入到带图形的C程序中就冲突,编译通不过! 禁用了相关的宏定义也没用.. 不知哪位仁兄有在WINTC TC2.0下能兼容的音频函数? 帮我解决这个难题? (通宵了几夜了,都没弄成,非常失望!..) 传到论坛也行, 也可EMAIL我, tdaim@sina.com 感谢了...

[此贴子已经被作者于2005-1-19 16:46:12编辑过]



2005-1-19 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
Loff
中级用户




积分 286
发帖 59
注册 2003-4-8
状态 离线
『第 2 楼』:  

几点问题要说明: 1. Allegro也可以在Windows平台下的、GCC、VC等编译器下使用。 2. 无论是DJGPP还是TC,都是DOS下的编译器,一般都是产生DOS程序的(用来写Windows程序的步骤比较复杂),而你要在DOS下发声,需要DOS下的声卡驱动程序,否则即使给你音频API函数,还是不行。 3. 在DOS下编写音频程序,如果没有相应声卡厂商提供的SDK的话,就只能自己写端口来实现,比如以前Adlib兼容芯片的控制就是通过写0x388、0x389端口。同样,前提是必须有声卡驱动。所以,劝楼主打消这个念头,或者在虚拟机下编写,不过速度可能很慢。


2005-2-1 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『第 3 楼』:  

我是假定装了SB16DOS驱动的情况下的调用一个音频函数就可解决的那种...苦于TC2没有音频函数!!


2005-4-29 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
郭恒
中级用户




积分 225
发帖 39
注册 2004-10-6
状态 离线
『第 4 楼』:  

// 我以前有一个C++版本的函数,且数据是放在“扩展内存”里的,是可行的。//现在我改成C语言的版本,并且波形数据从“文件”里读,未经测试,故仅作参考!#include <Dos.h> #include <Stdio.h> #include <Stdlib.h> #include <io.h> #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif#ifndef NULL #define NULL 0 #endif typedef int BOOL; typedef unsigned int WORD; typedef unsigned long DWORD; typedef unsigned char BYTE;typedef struct waveformat_tag{ WORD wFormatTag; WORD nChannels; DWORD nSamplesPerSec; DWORD nAvgBytesPerSec; WORD nBlockAlign; } WAVEFORMAT; typedef struct pcmwaveformat_tag{ WAVEFORMAT wf; WORD wBitsPerSample; } PCMWAVEFORMAT;typedef struct riffformat_tag { BYTE bysFormat[4]; DWORD dwSize; }RIFFFORMAT;//从声卡的DSP中读数据 BYTE ReadSound16_DSP(int nBase) { unsigned int i; for (i = 0; i < 3000u; i++) { if (0 != (inportb(nBase + 0xE) & (1<<7))) { return (inportb(nBase + 0xA)); } } return(0); }//往声卡的DSP写数据 BOOL WriteSound16_DSP(int nBase, unsigned char nCh) { while (0 != (inportb(nBase + 0xC) & (1<<7))) { } outportb(nBase + 0xC , nCh); return(FALSE); }//往声卡的DSP写基本参数 void WriteSound16_Const(int nBase, int nChannels, WORD wSampling) { WORD wConst = 65536L - (256000000L/(1L * ((WORD)nChannels) * wSampling)); WriteSound16_DSP(nBase, 0x40); WriteSound16_DSP(nBase, wConst >> 8); }//设置声卡的采样率 void WriteSound16_Sampling(int nBase, WORD wSampling, BOOL bOutput) { //HI = 0x56, LO =0x22 while wSample = 22050 WriteSound16_DSP(nBase, (bOutput)?0x41:0x42); WriteSound16_DSP(nBase, wSampling >> 8); WriteSound16_DSP(nBase, wSampling & 0xFF); return; }//声卡复位 BOOL ResetSound16_DSP(int nBase) { int i; outportb(nBase + 0x6, 1); delay(3); outportb(nBase + 0x6, 0); for (i = 0; i < 300; i++) { if (ReadSound16_DSP(nBase) != (BYTE)0xAA) { delay(1); continue; } return(TRUE); } return(FALSE); }//声卡播放文件 --- 8位立即数方式播入。 //入口参数:int nBase ------ 声卡基地址 //******** WORD wDelay ----- 播入每一数据时的软件延迟时间 //******** char* pStrFile -- WAVE文件名 BOOL PlayWaveFile(int nBase, WORD wDelay, char* pStrFile) { int nData; WORD p; long i, lgLeft; FILE* pFile = NULL; BYTE* pBuffer; BYTE* pLinBuffer; BYTE byData; RIFFFORMAT mRiffFormat; PCMWAVEFORMAT pcmWaveFormat; //打开文件 if (NULL == (pFile = fopen(pStrFile, "rb")) { return(FALSE); } //获得文件长度 long lgSize = filelength(fileno(pFile)); //验证文件长度的合法性 if (lgSize < 3L * sizeof(RIFFFORMAT)) { fclose(pFile); return(FALSE); } //读 "RIFF" 控制块 if (sizeof(RIFFFORMAT) != fread((void *)&mRiffFormat, 1, sizeof(RIFFFORMAT), pFile)) { fclose(pFile); return(FALSE); } //验证“RIFF”控制块 if (mRiffFormat.bysFormat[0] != 'R' || mRiffFormat.bysFormat[1] != 'I' || mRiffFormat.bysFormat[2] != 'F' || mRiffFormat.bysFormat[3] != 'F') { fclose(pFile); return(FALSE); } //验证文件长度的合法性 if (mRiffFormat.dwSize + 4L + 4L != lgSize) { fclose(pFile); return(FALSE); } //读“WAVE”控制块 if (4 != fread((void *)&mRiffFormat, 1, 4, pFile)) { fclose(pFile); return(FALSE); } //验证“WAVE”控制块 if (mRiffFormat.bysFormat[0] != 'W' || mRiffFormat.bysFormat[1] != 'A' || mRiffFormat.bysFormat[2] != 'V' || mRiffFormat.bysFormat[3] != 'E') { fclose(pFile); return(FALSE); } //读“FACT”或“FMT ”控制块 if (sizeof(RIFFFORMAT) != fread((void *)&mRiffFormat, 1, sizeof(RIFFFORMAT), pFile)) { fclose(pFile); return(FALSE); } //验证“FACT”控制块 if ((mRiffFormat.bysFormat[0] == 'f' || mRiffFormat.bysFormat[0] == 'F') && (mRiffFormat.bysFormat[1] == 'a' || mRiffFormat.bysFormat[1] == 'A') && (mRiffFormat.bysFormat[2] == 'c' || mRiffFormat.bysFormat[2] == 'C') && (mRiffFormat.bysFormat[3] == 't' || mRiffFormat.bysFormat[3] == 'T')) { lgLeft = mRiffFormat.dwSize; for (i = 0; i < lgLeft; i++) { if (1 != fread((void *)&mRiffFormat, 1, 1, pFile)) { fclose(pFile); return(FALSE); } } //读“FMT ”控制块 if (sizeof(RIFFFORMAT) != fread((void *)&mRiffFormat, 1, sizeof(RIFFFORMAT), pFile)) { fclose(pFile); return(FALSE); } } //验证“FMT ”控制块 if (mRiffFormat.bysFormat[0] != 'f' && mRiffFormat.bysFormat[0] != 'F' || mRiffFormat.bysFormat[1] != 'm' && mRiffFormat.bysFormat[1] != 'M' || mRiffFormat.bysFormat[2] != 't' && mRiffFormat.bysFormat[2] != 'T' || mRiffFormat.bysFormat[3] != ' ' && mRiffFormat.bysFormat[3] != ' ') { fclose(pFile); return(FALSE); } //读波形数据格式控制块 if (sizeof(PCMWAVEFORMAT) != fread((void *)&pcmWaveFormat, 1, sizeof(PCMWAVEFORMAT), pFile)) { fclose(pFile); return(FALSE); } //读其它不关心用途的控制块 lgLeft = mRiffFormat.dwSize - sizeof(PCMWAVEFORMAT); for (i = 0; i < lgLeft; i++) { if (1 != fread((void *)&byData, 1, 1, pFile)) { fclose(pFile); return(FALSE); } } //验证波形数据格式控制块的合法性 if (pcmWaveFormat.wBitsPerSample > 6 * 8) { //fclose(pFile); //return(FALSE); } //读“data”控制块 if (sizeof(RIFFFORMAT) != fread((void *)&mRiffFormat, 1, sizeof(RIFFFORMAT), pFile)) { fclose(pFile); return(FALSE); } // !!!!!可能是拷贝时,重复了的代码,忘了起什么作用! if ((mRiffFormat.bysFormat[0] == 'f' || mRiffFormat.bysFormat[0] == 'F') && (mRiffFormat.bysFormat[1] == 'a' || mRiffFormat.bysFormat[1] == 'A') && (mRiffFormat.bysFormat[2] == 'c' || mRiffFormat.bysFormat[2] == 'C') && (mRiffFormat.bysFormat[3] == 't' || mRiffFormat.bysFormat[3] == 'T')) { //读其它不关心用途的控制块 lgLeft = mRiffFormat.dwSize; for (long i = 0; i < lgLeft; i++) { if (1 != fread((void *)&mRiffFormat, 1, 1, pFile)) { fclose(pFile); return(FALSE); } } //读“data”控制块 if (sizeof(RIFFFORMAT) != fread((void *)&mRiffFormat, 1, sizeof(RIFFFORMAT), pFile)) { fclose(pFile); return(FALSE); } } //验证“data”控制块 if (mRiffFormat.bysFormat[0] != 'd' && mRiffFormat.bysFormat[0] != 'D'|| mRiffFormat.bysFormat[1] != 'a' && mRiffFormat.bysFormat[1] != 'A' || mRiffFormat.bysFormat[2] != 't' && mRiffFormat.bysFormat[2] != 'T' || mRiffFormat.bysFormat[3] != 'a' && mRiffFormat.bysFormat[3] != 'A') { fclose(pFile); return(FALSE); } //验证波形数据的长度 if (mRiffFormat.dwSize > lgSize - ftell(pFile)) { fclose(pFile); return(FALSE); } //验证文件的合法性 if (pcmWaveFormat.wf.wFormatTag != 1 || ((pcmWaveFormat.wf.nChannels * pcmWaveFormat.wBitsPerSample/8 != pcmWaveFormat.wf.nBlockAlign) || ((mRiffFormat.dwSize % pcmWaveFormat.wf.nBlockAlign) != 0 ))) { fclose(pFile); return(FALSE); } //初始化SB16声卡 ResetSound16_DSP(nBase); //初始化采样率 WriteSound16_Sampling(nBase, (WORD)pcmWaveFormat.wf.nSamplesPerSec, TRUE); WriteSound16_Const(nBase, pcmWaveFormat.wf.nChannels, (WORD)pcmWaveFormat.wf.nSamplesPerSec); //分配1024字节的数据缓冲区 pBuffer = new BYTE[1024]; pLinBuffer = pBuffer; for (i = 0; i < mRiffFormat.dwSize; i++) { //将波形数据读入到pBuffer缓冲区中 if ((i % 1024) == 0) { pLinBuffer = pBuffer; fread(pBuffer, 1, 1024, pFile); } //根据波形数据的数据位进行 switch (pcmWaveFormat.wBitsPerSample) { case 4: //4位波形数据 { byData = *(pLinBuffer++); WriteSound16_DSP(nBase, 0x10); WriteSound16_DSP(nBase, byData); break; } case 8: //4位波形数据 { byData = *(pLinBuffer++); WriteSound16_DSP(nBase,0x10); WriteSound16_DSP(nBase, byData); if (pcmWaveFormat.wf.nChannels >= 2) //双通道 { i++; byData = *(pLinBuffer++); WriteSound16_DSP(nBase,0x10); WriteSound16_DSP(nBase, byData); } break; } case 16: //16位波形数据 { *(((BYTE *)&nData) + 0)= *(pLinBuffer++); *(((BYTE *)&nData) + 1)= *(pLinBuffer++); //将16位数据转成8位数据 byData = (BYTE)(0.5f + 1.0f * (255 - 0) / (32757.0f - (-32768.0f)) * (1.0f * nData + (-32768.0f))); WriteSound16_DSP(nBase,0x10); WriteSound16_DSP(nBase,byData); i++; if (pcmWaveFormat.wf.nChannels >= 2) ////双通道 { *(((BYTE *)&nData) + 0)= *(pLinBuffer++); *(((BYTE *)&nData) + 1)= *(pLinBuffer++); //将16位数据转成8位数据 byData = (BYTE)(0.5f + 1.0f * (255 - 0) / (32757.0f - (-32768.0f)) * (1.0f * nData + (-32768.0f))); WriteSound16_DSP(nBase,0x10); WriteSound16_DSP(nBase,byData); i += 2; } break; } }//Switch (pcmWaveFormat.wBitsSample) //因为是立即数播放,故需要用软件来作延迟 for (p = 0; p < wDelay; p++) { } } //释入缓冲区 delete pBuffer; //关闭文件 fclose(pFile); return(TRUE); }


2005-5-10 00:00
查看资料  发送邮件  访问主页  发短消息 网志   编辑帖子  回复  引用回复
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『第 5 楼』:  

问一下,你这个是怎么用的? 是作为头文件,还是作为函数?具体说一下,怎么调用? 好么?


2005-5-12 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: