大佬教程收集整理的这篇文章主要介绍了c – 为OpenAL加载.WAV文件,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
struct RIFF_Header { char chunkID[4]; long chunkSize;//size not including chunkSize or chunkID char format[4]; }; /* * Struct to hold fmt subchunk data for WAVE files. */ struct WAVE_Format { char subChunkID[4]; long subChunkSize; short audioFormat; short numChAnnels; long sampleRate; long byteRate; short blockAlign; short bitsPerSample; }; /* * Struct to hold the data of the wave file */ struct WAVE_Data { char subChunkID[4]; //should contain the word data long subChunk2Size; //Stores the size of the data block }; bool loadWavFile(std::string filename,ALuint* buffer,ALsizei* size,ALsizei* frequency,ALenum* format) { //Local Declarations FILE* soundFile = NULL; WAVE_Format wave_format; RIFF_Header riff_header; WAVE_Data wave_data; unsigned char* data; *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; } try { soundFile = fopen(filename.c_str(),"rb"); if (!soundFilE) throw (fileName); // Read in the first chunk into the struct fread(&riff_header,sizeof(RIFF_Header),1,soundFilE); //check for RIFF and WAVE tag in memeory 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"); //Read in the 2nd chunk for the wave info fread(&wave_format,sizeof(WAVE_Format),soundFilE); //check for fmt tag in memory if (wave_format.subChunkID[0] != 'f' || wave_format.subChunkID[1] != 'm' || wave_format.subChunkID[2] != 't' || wave_format.subChunkID[3] != ' ') throw ("Invalid Wave Format"); //check for extra parameters; if (wave_format.subChunkSize > 16) fseek(soundFile,sizeof(short),SEEK_CUR); //Read in the the last byte of data before the sound file fread(&wave_data,sizeof(WAVE_Data),soundFilE); //check for data tag in memory 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"); //Allocate memory for data data = new unsigned char[wave_data.subChunk2Size]; // Read in the sound data into the soundData variable if (!fread(data,wave_data.subChunk2Size,soundFilE)) throw ("error loading WAVE data into struct!"); //Now we set the variables that we passed in with the //data from the structs *size = wave_data.subChunk2Size; *frequency = wave_format.sampleRate; //The format is worked out by looking at the number of //chAnnels and the bits per sample. 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; } //create our openAL buffer and check for success alGenBuffers(2,buffer); if(alGetError() != AL_NO_ERROR) { std::cerr << alGetError() << std::endl; } //Now we put our data into the openAL buffer and //check for success alBufferData(*buffer,*format,(void*)data,*size,*frequency); if(alGetError() != AL_NO_ERROR) { std::cerr << alGetError() << std::endl; } //clean up and return true if successful fclose(soundFilE); @R_@R_489_11287@_9421@e data; return true; } catch(const char* error) { //our catch statement for if we throw a String std::cerr << error << " : trying to load " << filename << std::endl; //clean up memory if wave loading fails if (soundFile != NULL) fclose(soundFilE); //return false to inDicate the failure to load wave @R_@R_489_11287@_9421@e data; return false; } } int main() { ALuint buffer,source; ALint state; ALsizei size; ALsizei frequency; ALenum format; ALCcontext *context; ALCdevice *device; device = alcOpenDevice(nullptr); if (device == NULL) { cerr << "Error finding default Audio Output Device" << endl; } context = alcCreateContext(device,null); alcMakeContextCurrent(context); alGetError(); loadWavFile("test.wav",&buffer,&size,&frequency,&format); alGensources(1,&sourcE); alsourcei(source,AL_BUFFER,buffer); // Play alsourcePlay(sourcE); // Wait for the song to complete do { alGetsourcei(source,AL_sourcE_STATE,&statE); } while (state == AL_PLAYING); // Clean up sources and buffers al@R_@R_489_11287@_9421@esources(1,&sourcE); al@R_@R_489_11287@_9421@eBuffers(1,&buffer); return 0; }
我有几个大约50kb的WAV文件.他们加载和播放就好了.但是,当我尝试加载整首歌曲(是的,我验证文件使用VLC Media Player和MusicBee正确格式化)时,它会返回“无效数据标题:尝试加载test.wav”,这是由此块引起的:
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");
我怀疑这是与尺寸相关的东西正在抛弃那个标题,因为看起来只有不到1000kb的工作(还没有完全测试过,很难找到在我的电脑和互联网上漂浮的完美尺寸的声音文件).这只是猜测,我真的不知道发生了什么.感谢帮助!
//http://www.youtube.com/user/thecplusplusguy //Playing 3D sound with OpenAL,and loading a wav file manually #include <iostream> #include <fstream> #include <cString> #include <al.h> #include <alc.h> bool isBigendian() { int a = 1; return !((char*)&a)[0]; } int convertToInt(char* buffer,int len) { int a = 0; if (!isBigendian()) for (int i = 0; i<len; i++) ((char*)&a)[i] = buffer[i]; else for (int i = 0; i<len; i++) ((char*)&a)[3 - i] = buffer[i]; return a; } char* loadWAV(const char* fn,int& chan,int& samplerate,int& bps,int& sizE) { char buffer[4]; std::ifstream in(fn,std::ios::binary); in.read(buffer,4); if (strncmp(buffer,"RIFF",4) != 0) { std::cout << "this is not a valid WAVE file" << std::endl; return NULL; } in.read(buffer,4); in.read(buffer,4); //WAVE in.read(buffer,4); //fmt in.read(buffer,4); //16 in.read(buffer,2); //1 in.read(buffer,2); chan = convertToInt(buffer,2); in.read(buffer,4); samplerate = convertToInt(buffer,2); bps = convertToInt(buffer,4); //data in.read(buffer,4); size = convertToInt(buffer,4); char* data = new char[size]; in.read(data,sizE); return data; } int main(int argc,char** argv) { int chAnnel,sampleRate,bps,size; char* data = loadWAV("C:/Users/Gizego/Desktop/Youtube/Músicas/TheFatRat+-+Time+Lapse.wav",chAnnel,sizE); ALCdevice* device = alcOpenDevice(null); if (device == NULL) { std::cout << "cAnnot open sound card" << std::endl; return 0; } ALCcontext* context = alcCreateContext(device,null); if (context == NULL) { std::cout << "cAnnot open context" << std::endl; return 0; } alcMakeContextCurrent(context); unsigned int bufferid,format; alGenBuffers(1,&bufferid); if (chAnnel == 1) { if (bps == 8) { format = AL_FORMAT_MONO8; } else { format = AL_FORMAT_MONO16; } } else { if (bps == 8) { format = AL_FORMAT_STEREO8; } else { format = AL_FORMAT_STEREO16; } } alBufferData(bufferid,format,data,size,sampleRatE); unsigned int sourcEID; alGensources(1,&sourcEID); alsourcei(sourcEID,bufferid); alsourcePlay(sourcEID); while (true) { } al@R_@R_489_11287@_9421@esources(1,&sourcEID); al@R_@R_489_11287@_9421@eBuffers(1,&bufferid); alcDestroyContext(context); alcCloseDevice(devicE); @R_@R_489_11287@_9421@e[] data; return 0; }
以上是大佬教程为你收集整理的c – 为OpenAL加载.WAV文件全部内容,希望文章能够帮你解决c – 为OpenAL加载.WAV文件所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。