游戏开发论坛

 找回密码
 立即注册
搜索
查看: 908|回复: 0

求助:诚心向各位大哥请教下面几个问题,谢谢!

[复制链接]

37

主题

67

帖子

73

积分

注册会员

Rank: 2

积分
73
发表于 2006-2-23 15:32:00 | 显示全部楼层 |阅读模式
//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]
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-23 17:40

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表