2015-06-22 32 views
0

我正在使用OpenAL和ALUT工作。我需要从缓冲区获取波形。我正在使用alutLoadWAVFile将数据加载到缓冲区中。当我输出缓冲器的每个项目,我得到的是这样的:如何从OpenAL缓冲区获取波形?

enter image description here

这不是波形,因为波形看起来像这样在Audacity中:

enter image description here

我的代码(无论如何相关部分):

unsigned char* alBuffer; 
... 
alutLoadWAVFile((ALbyte*)("test2.wav"), &alFormatBuffer, 
    (void **)&alBuffer, (ALsizei*)&alBufferLen, &alFreqBuffer, &alLoop); 
... 
for (int i = 0; i < (alBufferLen>5000?5000:alBufferLen); i++) { 
    log << (int)data[i] << "\n"; 
} 

回答

1

我在想你所期望的是缓冲区d ata正是你在Audacity中看到的。如果wav是8Bit Mono以外的东西(我认为无论如何,它已经有一段时间了),情况并非如此。另外,你似乎将数据[i]从unsigned char转换为int,这可能是另一个问题。

另外,您可能想要尝试手动读取wav文件而不是使用ALUT。 ALUT是一个让你虚弱的拐杖。 :)

这是一个程序,读取和播放没有ALUT的wav。有了它,你将能够找出wav文件的单声道/立体声和频率。希望从那里你可以直接开始和缓冲区混合并输出你想要的东西。

#include <stdio.h> 
#include <AL\al.h> 
#include <AL\alc.h> 

struct RIFF_Header { 
    char chunkID[4]; 
    long chunkSize; 
    char format[4]; 
}; 

struct WAVE_Format { 
    char subChunkID[4]; 
    long subChunkSize; 
    short audioFormat; 
    short numChannels; 
    long sampleRate; 
    long byteRate; 
    short blockAlign; 
    short bitsPerSample; 
}; 

struct WAVE_Data { 
    char subChunkID[4]; 
    long subChunk2Size; 
}; 

bool loadWavFile(const char* filename, ALuint* buffer, 
       ALsizei* size, ALsizei* frequency, 
       ALenum* format) { 
    FILE* soundFile = NULL; 
    WAVE_Format wave_format; 
    RIFF_Header riff_header; 
    WAVE_Data wave_data; 
    unsigned char* data; 

    try { 
    soundFile = fopen(filename, "rb"); 
    if (!soundFile) 
     throw (filename); 

    fread(&riff_header, sizeof(RIFF_Header), 1, soundFile); 

    if ((riff_header.chunkID[0] != 'R' || 
     riff_header.chunkID[1] != 'I' || 
     riff_header.chunkID[2] != 'F' || 
     riff_header.chunkID[3] != 'F') && 
     (riff_header.format[0] != 'W' || 
     riff_header.format[1] != 'A' || 
     riff_header.format[2] != 'V' || 
     riff_header.format[3] != 'E')) 
      throw ("Invalid RIFF or WAVE Header"); 

    fread(&wave_format, sizeof(WAVE_Format), 1, soundFile); 

    if (wave_format.subChunkID[0] != 'f' || 
     wave_format.subChunkID[1] != 'm' || 
     wave_format.subChunkID[2] != 't' || 
     wave_format.subChunkID[3] != ' ') 
      throw ("Invalid Wave Format"); 

    if (wave_format.subChunkSize > 16) 
     fseek(soundFile, sizeof(short), SEEK_CUR); 

    fread(&wave_data, sizeof(WAVE_Data), 1, soundFile); 

    if (wave_data.subChunkID[0] != 'd' || 
     wave_data.subChunkID[1] != 'a' || 
     wave_data.subChunkID[2] != 't' || 
     wave_data.subChunkID[3] != 'a') 
      throw ("Invalid data header"); 

    data = new unsigned char[wave_data.subChunk2Size]; 

    if (!fread(data, wave_data.subChunk2Size, 1, soundFile)) 
     throw ("error loading WAVE data into struct!"); 

    *size = wave_data.subChunk2Size; 
    *frequency = wave_format.sampleRate; 

    if (wave_format.numChannels == 1) { 
     if (wave_format.bitsPerSample == 8) 
      *format = AL_FORMAT_MONO8; 
     else if (wave_format.bitsPerSample == 16) 
      *format = AL_FORMAT_MONO16; 
    } else if (wave_format.numChannels == 2) { 
     if (wave_format.bitsPerSample == 8) 
      *format = AL_FORMAT_STEREO8; 
     else if (wave_format.bitsPerSample == 16) 
      *format = AL_FORMAT_STEREO16; 
    } 

    alGenBuffers(1, buffer); 
    alBufferData(*buffer, *format, (void*)data, 
       *size, *frequency); 
    fclose(soundFile); 
    return true; 
    } catch(char* error) { 
    if (soundFile != NULL) 
     fclose(soundFile); 
    return false; 
    } 
} 

int main(){ 

    //Sound play data 
    ALint state;       // The state of the sound source 
    ALuint bufferID;      // The OpenAL sound buffer ID 
    ALuint sourceID;      // The OpenAL sound source 
    ALenum format;       // The sound data format 
    ALsizei freq;       // The frequency of the sound data 
    ALsizei size;       // Data size 

    ALCdevice* device = alcOpenDevice(NULL); 
    ALCcontext* context = alcCreateContext(device, NULL); 
    alcMakeContextCurrent(context); 

    // Create sound buffer and source 
    alGenBuffers(1, &bufferID); 
    alGenSources(1, &sourceID); 

    // Set the source and listener to the same location 
    alListener3f(AL_POSITION, 0.0f, 0.0f, 0.0f); 
    alSource3f(sourceID, AL_POSITION, 0.0f, 0.0f, 0.0f); 

    loadWavFile("..\\wavdata\\YOURWAVHERE.wav", &bufferID, &size, &freq, &format); 

    alSourcei(sourceID, AL_BUFFER, bufferID); 

    alSourcePlay(sourceID); 

    do{ 
     alGetSourcei(sourceID, AL_SOURCE_STATE, &state); 
    } while (state != AL_STOPPED); 


    alDeleteBuffers(1, &bufferID); 
    alDeleteSources(1, &sourceID); 
    alcDestroyContext(context); 
    alcCloseDevice(device); 

    return 0; 
}