请ak_2005大侠解答关于C对声卡的编程调用wav,好吗?非常感谢 ( 积分: 30 )

  • 主题发起人 主题发起人 linuxcici
  • 开始时间 开始时间
L

linuxcici

Unregistered / Unconfirmed
GUEST, unregistred user!
#include<stdio.h>
#include<string.h>
#include<process.h>
#include<dos.h>
#include<alloc.h>
#define NumberOfTimes1 50
#define NumberOfTimes2 100
#define OldTimerInt 0x60
#ifdef __cplusplus
#define __CPPARGS ...
#else
#define __CPPARGS
#endif
unsigned long Counter;
unsigned CounterInt8,fpI8;
unsigned Port=0x210;
char Found=0;
unsigned Cnt1,Cnt2;
FILE *fp;
long num;
int smp1;
unsigned char a[64000];

struct wavhead
{
char riffid[4];
long cksize;
char fcctype[4];
char fmtid[4];
long ck16;
unsigned fortag;
unsigned nchan;
long nsamps;
long navgbgs;
unsigned nblocka;
unsigned wbpsam;
char dataid[4];
long datalen;
}wfhead;

void Testsb();
void PlayWavBg();
void interrupt NewTimer(__CPPARGS);
void SetTimer(void interrupt(*Rout)(__CPPARGS),unsigned freq);
void RestoreTimer();

void main(int argc,char *argv[])
{
argc=2;
argv[1]="a.wav";
if(argc<2)
{
printf("/nUsage:display filename.wav!!!");
exit(0);
}
if(!(strstr(argv[1],".wav")||strstr(argv[1],".WAV")))
{
printf("/ntype of the file is wrong!please insert *.wav/n");
exit(0);
}
if((fp=fopen(argv[1],"r+b"))==NULL)
{
printf("cannot open the file/n");
exit(0);
}
fseek(fp,22L,0);
fread(&wfhead.nchan,sizeof(int),1,fp);
fseek(fp,24L,0);
fread(&wfhead.nsamps,sizeof(long),1,fp);
fseek(fp,34L,0);
fread(&wfhead.wbpsam,sizeof(int),1,fp);
fseek(fp,40L,0);
fread(&num,sizeof(long),1,fp);
fread(a, sizeof(unsigned char), 64000, fp);
Testsb();
PlayWavBg();
while(!kbhit())
printf(".");
fclose(fp);
RestoreTimer();
}

void Testsb()
{
Cnt1=NumberOfTimes1;
while((Port<=0x260)&&!Found)
{
outportb(Port+0x6,1);
outportb(Port+0x6,0);
Cnt2=NumberOfTimes2;
while((Cnt2>0)&&(inportb(Port+0xE)<128))
--Cnt2;
if((Cnt2==0)||(inportb(Port+0xA)!=0xAA))
{
--Cnt1;
if(Cnt1==0)
{
Cnt1=NumberOfTimes1;
Port=Port+0x10;
}
}
else
Found=1;
}
if(!Found)
{
printf("Nobase port found!/n");
printf("/nDSP not reseted!/n");
exit(0);
}
}

void PlayWavBg()
{
smp1=44100/wfhead.nsamps;
Counter=1;
fseek(fp,44L,0);
if(wfhead.wbpsam==16)
num=num/2;
SetTimer(NewTimer,44100);
}

void SetTimer(void interrupt(*Rout)(__CPPARGS),unsigned freq)
{
int ICnt;
unsigned char intreg21;
fpI8=(freq+9)/18;
intreg21=inportb(0x21);
outportb(0x21,255);
ICnt=1193180/freq;
outportb(0x43,0x36);
outportb(0x40,ICnt&255);
outportb(0x40,ICnt>>8);
setvect(OldTimerInt,getvect(8));
setvect(8,Rout);
outportb(0x21,intreg21);
}

void RestoreTimer()
{
unsigned char intreg21;
intreg21=inportb(0x21);
outportb(0x21,255);
outportb(0x43,0x36);
outportb(0x40,0);
outportb(0x40,0);
setvect(8,getvect(OldTimerInt));
outportb(0x21,intreg21);
}

void interrupt NewTimer(__CPPARGS)
{
struct REGPACK R;
static long i=0;
Counter++;
if((Counter>=smp1&&i<num)||i==0)
{
i++;
outportb(Port+0xC,0x10);
while(inportb(Port+0xC)&0x80);
outportb(Port+0xC,a[i%64000]);
Counter=0;
}

if(--CounterInt8==0)
{
intr(OldTimerInt,&R);
CounterInt8=fpI8;
}
else outportb(0x20,0x20);
}

以上程序是<C游戏从入门到高手>复过来的,效果就是播放背景音乐,
例用时间中断令程序和音乐可以同部播放,但程序没有效果.
我学了一个学期的C,对硬件不太熟,可以利用你保贵的时间给我调一调吗?
小弟万分感谢了.


#include "ALLOC.H"
#include "DOS.H"
#include "CONIO.H"
#include "STDIO.H"
#include<graphics.h>
void playwav(char wavefile[14],float delaytime);
struct WaveData {
unsigned int SoundLength, Frequency;
char *Sample;
};
struct HeaderType {
long RIFF;
char NI1 [18];
unsigned int Channels;
long Frequency;
char NI2 [6];
char BitRes;
char NI3 [12];
} Header;
struct WaveData Voice;
unsigned int Base;
char WaveFile [25];



int ResetDSP(unsigned int Test)
{

outportb (Test + 0x6, 1);
delay(10);
outportb (Test + 0x6, 0);
delay(10);

if ((inportb(Test + 0xE) & 0x80 == 0x80) && (inportb(Test + 0xA) == 0xAA))
{

Base = Test;
return (1);
}
else

return (0);
}



void WriteDSP(unsigned char Value)
{
while ((inportb(Base + 0xC) & 0x80) == 0x80);
outportb (Base + 0xC, Value);
}



void PlayBack (struct WaveData *Wave)
{
long LinearAddress;
unsigned int Page, OffSet;
unsigned char TimeConstant;
TimeConstant = (65536 - (256000000 / Wave->Frequency)) >> 8;
WriteDSP(0x40);
WriteDSP(TimeConstant);
LinearAddress = FP_SEG (Wave->Sample);
LinearAddress = (LinearAddress << 4) + FP_OFF (Wave->Sample);
Page = LinearAddress >> 16;
OffSet = LinearAddress & 0xFFFF;

outportb (0x0A, 5);
outportb (0x0C, 0);
outportb (0x0B, 0x49);

outportb (0x02, OffSet & 0x100);
outportb (0x02, OffSet >> 8);
outportb (0x83, Page);
outportb (0x03, Wave->SoundLength & 0x100);
outportb (0x03, Wave->SoundLength >> 8);
outportb (0x0A, 1);
WriteDSP(0x14);
WriteDSP(Wave->SoundLength & 0xFF);
WriteDSP(Wave->SoundLength >> 8);
}



int LoadVoice (struct WaveData *Voice, char *FileName)
{
FILE *WAVFile;
WAVFile = fopen(FileName, "rb");
if (WAVFile == NULL) {
return (0);
}
fseek(WAVFile, 0L, SEEK_END);

Voice->SoundLength = ftell (WAVFile) - 48;

fseek(WAVFile, 0L, SEEK_SET);

if (Voice->SoundLength > 32000) {

if (Voice->SoundLength > 64000) {

Voice->SoundLength = 64000;
}
}
free(Voice->Sample);
Voice->Sample = (char *)malloc(Voice->SoundLength);

if (!Voice->Sample) {

return (0);
}
fread(&Header, 46, 1, WAVFile);

if (Header.RIFF != 0x46464952) {

printf ("Not a wave file/n");

return (0);
}
if (Header.Channels != 1) {
printf ("Not a mono wave file/n");
return (0);
}
if (Header.BitRes != 8) {
printf ("Not an 8-bit wave file/n");
return (0);
}
Voice->Frequency = Header.Frequency;
fread(Voice->Sample, Voice->SoundLength + 2, 1, WAVFile);
fclose (WAVFile);
return (1);
}





void playwav(char wavefile[14], float delaytime)
{

if (ResetDSP (0x220)) {

printf ("");
} else {
if (ResetDSP (0x240)) {

printf ("");
} else {

printf ("");
return;
}
}

if (LoadVoice (&Voice, wavefile)) {

PlayBack (&Voice);
delay(delaytime*1000);

WriteDSP (0xD0);
}
}







main()
{
clrscr();
playwav("why1.wav",90000);


}
以上程序是网上找的,可以播放WAV,但是就不能够同步播放
 
#include<stdio.h>
#include<string.h>
#include<process.h>
#include<dos.h>
#include<alloc.h>
#define NumberOfTimes1 50
#define NumberOfTimes2 100
#define OldTimerInt 0x60
#ifdef __cplusplus
#define __CPPARGS ...
#else
#define __CPPARGS
#endif
unsigned long Counter;
unsigned CounterInt8,fpI8;
unsigned Port=0x210;
char Found=0;
unsigned Cnt1,Cnt2;
FILE *fp;
long num;
int smp1;
unsigned char a[64000];

struct wavhead
{
char riffid[4];
long cksize;
char fcctype[4];
char fmtid[4];
long ck16;
unsigned fortag;
unsigned nchan;
long nsamps;
long navgbgs;
unsigned nblocka;
unsigned wbpsam;
char dataid[4];
long datalen;
}wfhead;

void Testsb();
void PlayWavBg();
void interrupt NewTimer(__CPPARGS);
void SetTimer(void interrupt(*Rout)(__CPPARGS),unsigned freq);
void RestoreTimer();

void main(int argc,char *argv[])
{
argc=2;
argv[1]="a.wav";
if(argc<2)
{
printf("/nUsage:display filename.wav!!!");
exit(0);
}
if(!(strstr(argv[1],".wav")||strstr(argv[1],".WAV")))
{
printf("/ntype of the file is wrong!please insert *.wav/n");
exit(0);
}
if((fp=fopen(argv[1],"r+b"))==NULL)
{
printf("cannot open the file/n");
exit(0);
}
fseek(fp,22L,0);
fread(&wfhead.nchan,sizeof(int),1,fp);
fseek(fp,24L,0);
fread(&wfhead.nsamps,sizeof(long),1,fp);
fseek(fp,34L,0);
fread(&wfhead.wbpsam,sizeof(int),1,fp);
fseek(fp,40L,0);
fread(&num,sizeof(long),1,fp);
fread(a, sizeof(unsigned char), 64000, fp);
Testsb();
PlayWavBg();
while(!kbhit())
printf(".");
fclose(fp);
RestoreTimer();
}

void Testsb()
{
Cnt1=NumberOfTimes1;
while((Port<=0x260)&&!Found)
{
outportb(Port+0x6,1);
outportb(Port+0x6,0);
Cnt2=NumberOfTimes2;
while((Cnt2>0)&&(inportb(Port+0xE)<128))
--Cnt2;
if((Cnt2==0)||(inportb(Port+0xA)!=0xAA))
{
--Cnt1;
if(Cnt1==0)
{
Cnt1=NumberOfTimes1;
Port=Port+0x10;
}
}
else
Found=1;
}
if(!Found)
{
printf("Nobase port found!/n");
printf("/nDSP not reseted!/n");
exit(0);
}
}

void PlayWavBg()
{
smp1=44100/wfhead.nsamps;
Counter=1;
fseek(fp,44L,0);
if(wfhead.wbpsam==16)
num=num/2;
SetTimer(NewTimer,44100);
}

void SetTimer(void interrupt(*Rout)(__CPPARGS),unsigned freq)
{
int ICnt;
unsigned char intreg21;
fpI8=(freq+9)/18;
intreg21=inportb(0x21);
outportb(0x21,255);
ICnt=1193180/freq;
outportb(0x43,0x36);
outportb(0x40,ICnt&255);
outportb(0x40,ICnt>>8);
setvect(OldTimerInt,getvect(8));
setvect(8,Rout);
outportb(0x21,intreg21);
}

void RestoreTimer()
{
unsigned char intreg21;
intreg21=inportb(0x21);
outportb(0x21,255);
outportb(0x43,0x36);
outportb(0x40,0);
outportb(0x40,0);
setvect(8,getvect(OldTimerInt));
outportb(0x21,intreg21);
}

void interrupt NewTimer(__CPPARGS)
{
struct REGPACK R;
static long i=0;
Counter++;
if((Counter>=smp1&&i<num)||i==0)
{
i++;
outportb(Port+0xC,0x10);
while(inportb(Port+0xC)&0x80);
outportb(Port+0xC,a[i%64000]);
Counter=0;
}

if(--CounterInt8==0)
{
intr(OldTimerInt,&R);
CounterInt8=fpI8;
}
else outportb(0x20,0x20);
}

以上程序是<C游戏从入门到高手>复过来的,效果就是播放背景音乐,
例用时间中断令程序和音乐可以同部播放,但程序没有效果.
我学了一个学期的C,对硬件不太熟,可以利用你保贵的时间给我调一调吗?
小弟万分感谢了.


#include "ALLOC.H"
#include "DOS.H"
#include "CONIO.H"
#include "STDIO.H"
#include<graphics.h>
void playwav(char wavefile[14],float delaytime);
struct WaveData {
unsigned int SoundLength, Frequency;
char *Sample;
};
struct HeaderType {
long RIFF;
char NI1 [18];
unsigned int Channels;
long Frequency;
char NI2 [6];
char BitRes;
char NI3 [12];
} Header;
struct WaveData Voice;
unsigned int Base;
char WaveFile [25];



int ResetDSP(unsigned int Test)
{

outportb (Test + 0x6, 1);
delay(10);
outportb (Test + 0x6, 0);
delay(10);

if ((inportb(Test + 0xE) & 0x80 == 0x80) && (inportb(Test + 0xA) == 0xAA))
{

Base = Test;
return (1);
}
else

return (0);
}



void WriteDSP(unsigned char Value)
{
while ((inportb(Base + 0xC) & 0x80) == 0x80);
outportb (Base + 0xC, Value);
}



void PlayBack (struct WaveData *Wave)
{
long LinearAddress;
unsigned int Page, OffSet;
unsigned char TimeConstant;
TimeConstant = (65536 - (256000000 / Wave->Frequency)) >> 8;
WriteDSP(0x40);
WriteDSP(TimeConstant);
LinearAddress = FP_SEG (Wave->Sample);
LinearAddress = (LinearAddress << 4) + FP_OFF (Wave->Sample);
Page = LinearAddress >> 16;
OffSet = LinearAddress & 0xFFFF;

outportb (0x0A, 5);
outportb (0x0C, 0);
outportb (0x0B, 0x49);

outportb (0x02, OffSet & 0x100);
outportb (0x02, OffSet >> 8);
outportb (0x83, Page);
outportb (0x03, Wave->SoundLength & 0x100);
outportb (0x03, Wave->SoundLength >> 8);
outportb (0x0A, 1);
WriteDSP(0x14);
WriteDSP(Wave->SoundLength & 0xFF);
WriteDSP(Wave->SoundLength >> 8);
}



int LoadVoice (struct WaveData *Voice, char *FileName)
{
FILE *WAVFile;
WAVFile = fopen(FileName, "rb");
if (WAVFile == NULL) {
return (0);
}
fseek(WAVFile, 0L, SEEK_END);

Voice->SoundLength = ftell (WAVFile) - 48;

fseek(WAVFile, 0L, SEEK_SET);

if (Voice->SoundLength > 32000) {

if (Voice->SoundLength > 64000) {

Voice->SoundLength = 64000;
}
}
free(Voice->Sample);
Voice->Sample = (char *)malloc(Voice->SoundLength);

if (!Voice->Sample) {

return (0);
}
fread(&Header, 46, 1, WAVFile);

if (Header.RIFF != 0x46464952) {

printf ("Not a wave file/n");

return (0);
}
if (Header.Channels != 1) {
printf ("Not a mono wave file/n");
return (0);
}
if (Header.BitRes != 8) {
printf ("Not an 8-bit wave file/n");
return (0);
}
Voice->Frequency = Header.Frequency;
fread(Voice->Sample, Voice->SoundLength + 2, 1, WAVFile);
fclose (WAVFile);
return (1);
}





void playwav(char wavefile[14], float delaytime)
{

if (ResetDSP (0x220)) {

printf ("");
} else {
if (ResetDSP (0x240)) {

printf ("");
} else {

printf ("");
return;
}
}

if (LoadVoice (&Voice, wavefile)) {

PlayBack (&Voice);
delay(delaytime*1000);

WriteDSP (0xD0);
}
}







main()
{
clrscr();
playwav("why1.wav",90000);


}
以上程序是网上找的,可以播放WAV,但是就不能够同步播放
 
你太抬举我了,我大一时学的C啊,好久都没搞了,现在改用delphi了。
这么晚了还不睡啊,我看看吧,不打包票。
 
非常谢谢你了,我下学期要用C参加学校比赛,关键就难在这里了.
 
to linuxcici:
不知道你在什么系统下运行的?
第一个程序可能与系统权限有关系,我是在XP下运行的,编译没问题,运行提示Abnormal Program Termination.一行都不执行.你可以装个98试试, 把运行结果告诉我.因为98的DOS才是纯DOS,2000以上只是一个假的命令系统,所有操作都会受系统控制,特别对于硬件的操作,每一项都有权限的(典型的比如关机 ).
关于第二个,这个程序没用系统定时,当然不能同步播放,一定要用定时器(可以参照第一个程序).
 
喔.我用的也是window XP第二版系统,也是运行提示Abnormal Program Termination.

至于windows98我还要去试一试,请问那第一个有中断的程序按道理可以有效果的吗?
我在学校机房的window 2000 试过都不行啊.

ak_2005大侠请你发你的e-mail给我的woshiwo1985@21cn.com联系比较放便啊


以下:
#include "ALLOC.H"
#include "DOS.H"
#include "CONIO.H"
#include "STDIO.H"
#include<graphics.h>
void playwav(char wavefile[14],float delaytime);
struct WaveData {
unsigned int SoundLength, Frequency;
char *Sample;
};
struct HeaderType {
long RIFF;
char NI1 [18];
unsigned int Channels;
long Frequency;
char NI2 [6];
char BitRes;
char NI3 [12];
} Header;
struct WaveData Voice;
unsigned int Base;
char WaveFile [25];



int ResetDSP(unsigned int Test)
{

outportb (Test + 0x6, 1);
delay(10);
outportb (Test + 0x6, 0);
delay(10);

if ((inportb(Test + 0xE) & 0x80 == 0x80) && (inportb(Test + 0xA) == 0xAA))
{

Base = Test;
return (1);
}
else

return (0);
}



void WriteDSP(unsigned char Value)
{
while ((inportb(Base + 0xC) & 0x80) == 0x80);
outportb (Base + 0xC, Value);
}



void PlayBack (struct WaveData *Wave)
{
long LinearAddress;
unsigned int Page, OffSet;
unsigned char TimeConstant;
TimeConstant = (65536 - (256000000 / Wave->Frequency)) >> 8;
WriteDSP(0x40);
WriteDSP(TimeConstant);
LinearAddress = FP_SEG (Wave->Sample);
LinearAddress = (LinearAddress << 4) + FP_OFF (Wave->Sample);
Page = LinearAddress >> 16;
OffSet = LinearAddress & 0xFFFF;

outportb (0x0A, 5);
outportb (0x0C, 0);
outportb (0x0B, 0x49);

outportb (0x02, OffSet & 0x100);
outportb (0x02, OffSet >> 8);
outportb (0x83, Page);
outportb (0x03, Wave->SoundLength & 0x100);
outportb (0x03, Wave->SoundLength >> 8);
outportb (0x0A, 1);
WriteDSP(0x14);
WriteDSP(Wave->SoundLength & 0xFF);
WriteDSP(Wave->SoundLength >> 8);
}



int LoadVoice (struct WaveData *Voice, char *FileName)
{
FILE *WAVFile;
WAVFile = fopen(FileName, "rb");
if (WAVFile == NULL) {
return (0);
}
fseek(WAVFile, 0L, SEEK_END);

Voice->SoundLength = ftell (WAVFile) - 48;

fseek(WAVFile, 0L, SEEK_SET);

if (Voice->SoundLength > 32000) {

if (Voice->SoundLength > 64000) {

Voice->SoundLength = 64000;
}
}
free(Voice->Sample);
Voice->Sample = (char *)malloc(Voice->SoundLength);

if (!Voice->Sample) {

return (0);
}
fread(&Header, 46, 1, WAVFile);

if (Header.RIFF != 0x46464952) {

printf ("Not a wave file/n");

return (0);
}
if (Header.Channels != 1) {
printf ("Not a mono wave file/n");
return (0);
}
if (Header.BitRes != 8) {
printf ("Not an 8-bit wave file/n");
return (0);
}
Voice->Frequency = Header.Frequency;
fread(Voice->Sample, Voice->SoundLength + 2, 1, WAVFile);
fclose (WAVFile);
return (1);
}





void playwav(char wavefile[14], float delaytime)
{

if (ResetDSP (0x220)) {

printf ("");
} else {
if (ResetDSP (0x240)) {

printf ("");
} else {

printf ("");
return;
}
}

if (LoadVoice (&Voice, wavefile)) {

PlayBack (&Voice);
delay(delaytime*1000);

WriteDSP (0xD0);
}
}







main()
{
clrscr();
playwav("why1.wav",90000);


}


我试过可以在windowx xp运行.这段代码只是播音乐,只能是单声道的.但是如果把一首mp3转换成wav就播放不了.

总结:我们的老师说可能是声卡的兼容问题,你说呢?
 
第二个程序没用中断,当然可以了。我认为不是声卡的兼容问题,是音乐的格式问题。
WAV格式是“原汁原味”的,没经过压缩的,而MP3是经过压缩处理过的。
 
>>请问那第一个有中断的程序按道理可以有效果的吗?
再次看了第一个程序,有问题,mian函数里面一句也不回执行(你可以设断点,再单步跟踪),到底是什么原因呢?
 
大哥我不懂怎么单步调试啊,因为我没有试过,真的很对不起,我学了C只有半个学期.......
 
设断点(Ctrl+F8),单步执行(F7),查看联机帮助(Help->Index)...
 
ak_2005大侠我发了e-mail给你了,请看看.小弟现在能上网真的很不容易了,求你帮个忙
 
后退
顶部