|
|
//WAV声音结构
typedef struct pcm_sound_typ
{
LPDIRECTSOUNDBUFFER dsbuffer;
int state;
int rate;
int size;
int id;
} pcm_sound, *pcm_sound_ptr;
#define MAX_SOUNDS 256 //最大声音数
#define SOUND_NULL 0
#define SOUND_LOADED 1
#define SOUND_PLAYING 2
#define SOUND_STOPPED 3
extern pcm_sound sound_fx[MAX_SOUNDS];
////////////////////////////////////////////////
////// 读取WAV文件 /////////
////////////////////////////////////////////////
int DSoundLoadWAV(char *filename,
int control_flags)
{
HMMIO hwav; //文件句柄
MMCKINFO parent,
child;
WAVEFORMATEX wfmtx; //WAV 结构
int sound_id = -1,
index;
UCHAR *snd_buffer, //缓冲
*audio_ptr_1=NULL, //第一写指针
*audio_ptr_2=NULL; //第一写指针
DWORD audio_length_1=0, //第一缓冲
audio_length_2=0; //第一缓冲
//初始化
for (index=0; index < MAX_SOUNDS; index++)
{
//声音是否被使用
if (sound_fx[index].state==SOUND_NULL)
{
sound_id = index;
break;
}
}
//id 是否被使用
if (sound_id==-1)
return(-1);
//设置结构
parent.ckid =(FOURCC)0;
parent.cksize =0;
parent.fccType =(FOURCC)0;
parent.dwDataOffset=0;
parent.dwFlags =0;
//复制数据
child = parent;
//打开 WAV 文件
if ((hwav = mmioOpen(filename, NULL, MMIO_READ | MMIO_ALLOCBUF)) == NULL)
//RIFF
parent.fccType = mmioFOURCC('W', 'A', 'V', 'E');
if (mmioDescend(hwav,&parent,NULL,MMIO_FINDRIFF))
{
//关闭
mmioClose(hwav,0);
return(-1);
}
//WAVEfmt
child.ckid = mmioFOURCC('f', 'm', 't', ' ');
if (mmioDescend(hwav, &child, &parent, 0))
{
//关闭
mmioClose(hwav, 0);
return(-1);
}
//读取格式
if (mmioRead(hwav, (char *)&wfmtx, sizeof(wfmtx)) != sizeof(wfmtx))
{
//关闭
mmioClose(hwav, 0);
return(-1);
}
//是否PCM格式
if (wfmtx.wFormatTag != WAVE_FORMAT_PCM)
{
//关闭
mmioClose(hwav, 0);
return(-1);
}
//data chunk
if (mmioAscend(hwav, &child, 0))
{
//关闭
mmioClose(hwav, 0);
return(-1);
}
//确定data chunk
child.ckid = mmioFOURCC('d', 'a', 't', 'a');
if (mmioDescend(hwav, &child, &parent, MMIO_FINDCHUNK))
{
//关闭
mmioClose(hwav, 0);
return(-1);
}
//分配空间
snd_buffer = (UCHAR *)malloc(child.cksize);
//读取WAV数据
mmioRead(hwav, (char *)snd_buffer, child.cksize);
//关闭
mmioClose(hwav, 0);
//设置频率
sound_fx[sound_id].rate = wfmtx.nSamplesPerSec;
sound_fx[sound_id].size = child.cksize;
sound_fx[sound_id].state = SOUND_LOADED;
//设置结构
memset(&pcmwf, 0, sizeof(WAVEFORMATEX));
pcmwf.wFormatTag = WAVE_FORMAT_PCM; // pulse code modulation
pcmwf.nChannels = 2; // mono
pcmwf.nSamplesPerSec = 22050; // always this rate
pcmwf.nBlockAlign = 4;
pcmwf.nAvgBytesPerSec = pcmwf.nSamplesPerSec * pcmwf.nBlockAlign;
pcmwf.wBitsPerSample = 16;
pcmwf.cbSize = 0;
//描述创建缓冲
dsbd.dwSize = sizeof(DSBUFFERDESC);
if(control_flags == 0)
dsbd.dwFlags = DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME |
DSBCAPS_CTRLFREQUENCY | DSBCAPS_STATIC | DSBCAPS_LOCSOFTWARE;
dsbd.dwBufferBytes = child.cksize;
dsbd.lpwfxFormat = &pcmwf;
//创建缓冲
if (FAILED(lpDSound->CreateSoundBuffer(&dsbd,&sound_fx[sound_id].dsbuffer,NULL)))
{
//释放
free(snd_buffer);
return(-1);
}
//拷贝数据
if (FAILED(sound_fx[sound_id].dsbuffer->Lock(0,
child.cksize,
(void **) &audio_ptr_1,
&audio_length_1,
(void **)&audio_ptr_2,
&audio_length_2,
DSBLOCK_FROMWRITECURSOR)))
return(0);
//复制第一循环缓冲
memcpy(audio_ptr_1, snd_buffer, audio_length_1);
//复制第二循环缓冲
memcpy(audio_ptr_2, (snd_buffer+audio_length_1),audio_length_2);
//解锁
if (FAILED(sound_fx[sound_id].dsbuffer->Unlock(audio_ptr_1,
audio_length_1,
audio_ptr_2,
audio_length_2)))
return(0);
//释放临时缓冲
free(snd_buffer);
return(sound_id);
}
请教:
问题1:
HMMIO hwav; //文件句柄
HMMIO 是专门定义 WVA 文件的,是吗?
问题2;
MMCKINFO parent,
child;
MMCKINFO 是什么类型的结构?
问题3:
int sound_id = -1,
index;
请教这里为什么要把 sound_id 初始为 -1 呢?
问题4:
//设置结构
parent.ckid =(FOURCC)0;
parent.cksize =0;
parent.fccType =(FOURCC)0;
parent.dwDataOffset=0;
parent.dwFlags =0;
各位大哥帮我解释一下上面几句,好吗?
问题5:
//复制数据
child = parent;
各位大哥,为什么要这样做?
问题6:
//RIFF
//WAVEfmt
这分别是什么意思啊?
为什么 //RIFF 用的是:
parent.fccType
而 //WAVEfmt 用的 child.ckid?
各位大哥,//WAVEfmt 可不可以用 parent.ckid?
问题7:
//创建缓冲
if (FAILED(lpDSound->CreateSoundBuffer(&dsbd,&sound_fx[sound_id].dsbuffer,NULL)))
{
//释放
free(snd_buffer);
return(-1);
}
为什么要释放 free(snd_buffer) 呢?
谢谢 各位大哥!
[em3] [em20] |
|