使用openal播放WAV音频

Posted GreenArrowMan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用openal播放WAV音频相关的知识,希望对你有一定的参考价值。

 欢迎关注公众号可以查看更多完整文章

 

下载openal sdk,alut源文件:

OpenAL1.1SDK_OpenAL驱动1.1-C++工具类资源-CSDN下载

不使用alut,只使用openal播放WAV文件:

#include <al.h>
#include <alc.h>

struct WAVE_Data 
	char subChunkID[4]; //should contain the word data
	long subChunk2Size; //Stores the size of the data block
;

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

struct RIFF_Header 
	char chunkID[4];
	long chunkSize;//size not including chunkSize or chunkID
	char format[4];
;

bool loadWavFile(const 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;

	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), 1, 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), 1, 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, 1, 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(1, buffer);
		//errorCheck();
		//now we put our data into the openAL buffer and
		//check for success
		alBufferData(*buffer, *format, (void*)data,
			*size, *frequency);
		//errorCheck();
		//clean up and return true if successful
		fclose(soundFile);
		return true;
	
	catch (std::string 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
		return false;
	

ALuint alSource;
ALuint source;
ALsizei size2;
ALsizei frequent;
ALenum format;

void main()

    alcMakeContextCurrent(alcCreateContext(alcOpenDevice(NULL), NULL));

	//openal播放音频1
	loadWavFile("shengdao.wav", &alSource, &size2, &frequent, &format);
	alGenSources(1, &source);
	alSourcei(source, AL_BUFFER, alSource);
	alSourcePlay(source);

以上是关于使用openal播放WAV音频的主要内容,如果未能解决你的问题,请参考以下文章

使用 Haskell 播放 wav 文件

Android使用AudioTrack播放WAV音频文件

AVAudioPlayer 无法播放使用 ExtAudioFileWriteAsync 编写的音频 (.wav) 文件

多浏览器播放wav格式的音频文件

PyDub 从变量播放音频

如何在 Windows 上使用 gstreamer 播放 .wav 音频文件?