|
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 |
|
|