![]() |
中国DOS联盟-- 联合DOS 推动DOS 发展DOS --联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum |
| 游客 | 登录 | 注册 | 会员 | 搜索 | 中国DOS联盟 |
|
中国DOS联盟论坛 现在时间是 2026-10-31 15:32 |
共 47,815 主题排行 / 349,930 发帖 / 今日 0 篇 / 48,290 会员排行 |
| DOS开发编程 & 发展交流 (开发室) » 哪位懂WIN-TC(或TC2.0)加入音频播放的仁兄能不能帮一下忙? |
| 可打印版本 1,611 / 4 |
| 第1楼 GOTOmsdos | 发表于 2005-01-19 00:00 |
| 铂金会员 发帖 1,827 积分 5,154 | |
|
哪位懂WIN-TC(或TC2.0)加入音频播放的仁兄能不能帮一下忙? 哪位懂WIN-TC(或TC2.0)加入音频播放的仁兄能不能帮一下忙?
这几天用WINTC做了个小程序,急需加入WAV音频,但WINTC TC没有音频函数,下了ALLEGRO,但好象要在DJGPP下,我没用过,现在又很急, 弄了个NEO SDK , 仅仅单独播放音频可以,但加入到带图形的C程序中就冲突,编译通不过! 禁用了相关的宏定义也没用.. 不知哪位仁兄有在WINTC TC2.0下能兼容的音频函数? 帮我解决这个难题? (通宵了几夜了,都没弄成,非常失望!..) 传到论坛也行, 也可EMAIL我, [email protected] 感谢了... |
|
| 第2楼 Loff | 发表于 2005-02-01 00:00 |
| 中级用户 发帖 59 积分 286 | |
|
几点问题要说明:
1. Allegro也可以在Windows平台下的、GCC、VC等编译器下使用。 2. 无论是DJGPP还是TC,都是DOS下的编译器,一般都是产生DOS程序的(用来写Windows程序的步骤比较复杂),而你要在DOS下发声,需要DOS下的声卡驱动程序,否则即使给你音频API函数,还是不行。 3. 在DOS下编写音频程序,如果没有相应声卡厂商提供的SDK的话,就只能自己写端口来实现,比如以前Adlib兼容芯片的控制就是通过写0x388、0x389端口。同样,前提是必须有声卡驱动。所以,劝楼主打消这个念头,或者在虚拟机下编写,不过速度可能很慢。 |
|
| 第3楼 GOTOmsdos | 发表于 2005-04-29 00:00 |
| 铂金会员 发帖 1,827 积分 5,154 | |
|
我是假定装了SB16DOS驱动的情况下的调用一个音频函数就可解决的那种...苦于TC2没有音频函数!!
|
|
| 第4楼 郭恒 | 发表于 2005-05-10 00:00 |
| 中级用户 发帖 39 积分 225 | |
|
// 我以前有一个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; 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 != 'R' || mRiffFormat.bysFormat != 'I' || mRiffFormat.bysFormat != 'F' || mRiffFormat.bysFormat != '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 != 'W' || mRiffFormat.bysFormat != 'A' || mRiffFormat.bysFormat != 'V' || mRiffFormat.bysFormat != '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 == 'f' || mRiffFormat.bysFormat == 'F' &&(mRiffFormat.bysFormat == 'a' || mRiffFormat.bysFormat == 'A' &&(mRiffFormat.bysFormat == 'c' || mRiffFormat.bysFormat == 'C' &&(mRiffFormat.bysFormat == 't' || mRiffFormat.bysFormat == '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 != 'f' && mRiffFormat.bysFormat != 'F' || mRiffFormat.bysFormat != 'm' && mRiffFormat.bysFormat != 'M' || mRiffFormat.bysFormat != 't' && mRiffFormat.bysFormat != 'T' || mRiffFormat.bysFormat != ' ' && mRiffFormat.bysFormat != ' ' ![]() { 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 == 'f' || mRiffFormat.bysFormat == 'F' &&(mRiffFormat.bysFormat == 'a' || mRiffFormat.bysFormat == 'A' &&(mRiffFormat.bysFormat == 'c' || mRiffFormat.bysFormat == 'C' &&(mRiffFormat.bysFormat == 't' || mRiffFormat.bysFormat == '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 != 'd' && mRiffFormat.bysFormat != 'D'|| mRiffFormat.bysFormat != 'a' && mRiffFormat.bysFormat != 'A' || mRiffFormat.bysFormat != 't' && mRiffFormat.bysFormat != 'T' || mRiffFormat.bysFormat != 'a' && mRiffFormat.bysFormat != '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; 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); } |
|
| 第5楼 GOTOmsdos | 发表于 2005-05-12 00:00 |
| 铂金会员 发帖 1,827 积分 5,154 | |
|
问一下,你这个是怎么用的? 是作为头文件,还是作为函数?具体说一下,怎么调用? 好么?
|
|
|
[ 联系联盟系统管理团队 -
中国DOS联盟 -
标准版 ] Sponsored by ifanr Inc | © 2001–2023 |