本文介绍了带有一个wave的简单Waveout API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

亲爱的朋友们,

我使用C ++进行编程,并且在我的PC上运行waveout API时遇到问题。任何人都可以帮助我获得正确的代码以使其正常工作吗?我正在使用VSC ++ Express!我已经包含了stdio.h,windows.h和winmm.lib!我会饶有帮助!





Dear friends,
I am programming in C++ and have a problem with waveout API to run on my PC. Could anybody help me to get the code right to get it work properly please ? I am using VSC++ Express! I have included stdio.h, windows.h, and winmm.lib ! I will apreciated evry help !


#define SOUNDBUFF 65536;
WAVEFORMATEX wf;
WAVEHDR whdr;
HWAVEOUT hWaveOut;
LPSTR lpData;
float clpData[65536];

int main(void)
{

FILE *f = fopen("c:/JP8080.wav","rb")
fwrite(&clpdata, 2, 1, sizeof(clpdata), f);

wf.wFormatTag=WAVE_FORMAT_PCM;
wf.nChannels=2;
wf.nSamplesPerSec=44100;
wf.nAvgBytesPerSec=(44100*4);
wf.nBlockAlign=(2*16)/8;
wf.wBitsPerSample=16;
wf.cbSize=0;

whdr.lpData = clpData;
whdr.dwBufferLength = SOUNDBUFF;
whdr.dwFlags = 0;
whdr.dwLoops = 0;

do {
} while (!(whdr.dwFlags & WHDR_DONE));

waveOutOpen(&hWaveOut,WAVE_MAPPER,&wf,0,0,CALLBACK_NULL);
waveOutPrepareHeader(hWaveOut,&whdr,sizeof(whdr));
waveOutWrite(hWaveOut,&whdr,sizeof(whdr));

do {
} while (!(whdr.dwFlags & WHDR_DONE));

waveOutUnprepareHeader(hWaveOut,&whdr,sizeof(whdr));
waveOutClose(hWaveOut);

return 0;
}

推荐答案

#include <windows.h>
#include <mmsystem.h>
#include <stdio.h>

typedef struct wavFileHeader
{
    long chunkId;           //"RIFF" (0x52,0x49,0x46,0x46)
    long chunkSize;         // (fileSize - 8)  - could also be thought of as bytes of data in file following this field (bytesRemaining)
    long riffType;          // "WAVE" (0x57415645)
};

typedef struct fmtChunk
{
    long chunkId;                       // "fmt " - (0x666D7420)
    long chunkDataSize;                 // 16 + extra format bytes
    short compressionCode;              // 1 - 65535
    short numChannels;                  // 1 - 65535
    long sampleRate;                    // 1 - 0xFFFFFFFF
    long avgBytesPerSec;                // 1 - 0xFFFFFFFF
    short blockAlign;                   // 1 - 65535
    short significantBitsPerSample;     // 2 - 65535
    short extraFormatBytes;             // 0 - 65535
};

typedef struct wavChunk
{
    long chunkId;
    long chunkDataSize;
};



char *readFileData(char *szFilename, long &dataLengthOut)
{
    FILE *fp = fopen(szFilename, "rb");
    long len;
    char *buffer;
    fseek(fp, 0, SEEK_END);
    len = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    buffer = (char*) calloc(1, len+1);
    fread(buffer, 1, len, fp);
    fclose(fp);
    dataLengthOut = len;
    return buffer;
}

void parseWav(char *data)
{
    long *mPtr;
    void *tmpPtr;

    char *buffer;

    WAVEFORMATEX wf;
    WAVEHDR wh;
    HWAVEOUT hWaveOut;

    fmtChunk mFmtChunk;
    wavChunk mDataChunk;

    mPtr = (long*)data;

    if ( mPtr[0] == 0x46464952) //  little endian check for 'RIFF'
    {
        mPtr += 3;
        if (mPtr[0] == 0x20746D66)  // little endian for "fmt "
        {
           // printf("Format chunk found\n");

            tmpPtr = mPtr;
            memcpy(&mFmtChunk, tmpPtr, sizeof(mFmtChunk));
            tmpPtr += 8;
            tmpPtr += mFmtChunk.chunkDataSize;

            mPtr = (long*)tmpPtr;
            if (mPtr[0] == 0x61746164)        // little endian for "data"
            {
            //    printf("Data chunk found\n");

                tmpPtr = mPtr;
                memcpy(&mDataChunk, tmpPtr, sizeof(mDataChunk));
                mPtr += 2;

                buffer = (char*) malloc(mDataChunk.chunkDataSize);
                memcpy(buffer, mPtr, mDataChunk.chunkDataSize);

                printf("sampleRate: %d\n", mFmtChunk.sampleRate);

                wf.wFormatTag = mFmtChunk.compressionCode;
                wf.nChannels = mFmtChunk.numChannels;
                wf.nSamplesPerSec = mFmtChunk.sampleRate;
                wf.nAvgBytesPerSec = mFmtChunk.avgBytesPerSec;
                wf.nBlockAlign = mFmtChunk.blockAlign;
                wf.wBitsPerSample = mFmtChunk.significantBitsPerSample;
                wf.cbSize = mFmtChunk.extraFormatBytes;

                wh.lpData = buffer;
                wh.dwBufferLength = mDataChunk.chunkDataSize;
                wh.dwFlags = 0;
                wh.dwLoops = 0;

                waveOutOpen(&hWaveOut,WAVE_MAPPER,&wf,0,0,CALLBACK_NULL);
                waveOutPrepareHeader(hWaveOut,&wh,sizeof(wh));
                waveOutWrite(hWaveOut,&wh,sizeof(wh));

                do {}
                while (!(wh.dwFlags & WHDR_DONE));

                waveOutUnprepareHeader(hWaveOut,&wh,sizeof(wh));
                waveOutClose(hWaveOut);

                free(buffer);
            }
        }

    }

    else
        printf("INvalid WAV\n");
}


int main()
{
    char *filename = "c:/windows/media/tada.wav";
    char *buffer;
    long fileSize;

    buffer = readFileData(filename, fileSize);
    parseWav(buffer);

    free(buffer);

    return 0;
}







编辑:我刚刚玩了这个代码,发现了很多我的恐怖 - 在发布版本运行后播放声音时程序挂起 - (从未将其作为调试版本翻过来)



似乎编译器正在优化空的do while循环 - 没有意识到我的源代码之外的代码将修改wh.dwFlags



解决方案是这样添加volatile关键字:




I just played with this code some more, discovering much to my horror - that the program hung after playing the sound when the release version was run -(never flicked it over from being a debug build)

It seems that the compiler was optimizing the empty do while loop - not realizing that code outside of my source was going to modify wh.dwFlags

The solution was to add the volatile keyword thusly:

volatile WAVEHDR wh;



和任何使用& wh的用法如下:


and to cast any use of &wh like so:

(wavehdr_tag*)&wh


if (mPtr[0] == 0x5453494C) {       // little endian for "LIST"
    // skip info chunk
    memcpy(&mDataChunk, tmpPtr, sizeof(mDataChunk));
    tmpPtr = (void*) (((char*) tmpPtr ) + 8 + mDataChunk.chunkDataSize);
    mPtr = (long*)tmpPtr;
}

if (mPtr[0] == 0x61746164)





我的编译器( Borland CBuilder 6)抱怨这一行的语法:



Also my compiler (Borland CBuilder 6) complained about the syntax of this line:

tmpPtr += 8;



我必须将其更改为:


I had to change it to:

tmpPtr = (void*) ((char*) tmpPtr ) + 8;


这篇关于带有一个wave的简单Waveout API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 10:59