• Advertisement
Sign in to follow this  

Sound not working

This topic is 3319 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

For some reason my sound code is not working at all, I try to play the sound but nothing plays :(. There are no errors reported either as to why its not doing anything... audio.cpp
...
//CONSTRUCT/DESTRUCT
Audio::Audio(AudioDll *_dll)
:dll(_dll), refCnt(0), currentOpSet(1), paused(false)
{
	dll->AddRef();
	//start com
	if(FAILED(CoInitializeEx(NULL, COINIT_MULTITHREADED)))
		throw exception::Error(L"Failed to start COM");
	//flags
	unsigned flags = 0;
#	ifdef _DEBUG
		flags |= XAUDIO2_DEBUG_ENGINE;
#	endif
	//create
	if(FAILED(XAudio2Create(&xaudio2, flags)))
	{
		CoUninitialize();
		throw exception::Error(L"Failed to create xaudio2");
	}
	//info
	XAUDIO2_DEVICE_DETAILS info;
	xaudio2->GetDeviceDetails(0, &info);
	//create master voice
	if(FAILED(xaudio2->CreateMasteringVoice(&masterVoice)))
	{
		xaudio2->Release();
		CoUninitialize();
		throw exception::Error(L"Failed to create the master voice");
	}
}
Audio::~Audio()
{
	StopAll();
	masterVoice->DestroyVoice();
	xaudio2->Release();
	dll->Release();
}
...
unsigned Audio::GetCurrentOpSet()
{
	return currentOpSet;
}
...
void Audio::AddSourceVoice(SourceVoice *voice)
{
	voice->AddRef();
	playing.insert(voice);
}
//UPDATE, called once after each game logic update
void Audio::Update()
{
	//commit changes
	xaudio2->CommitChanges(currentOpSet);
	if(!++currentOpSet)currentOpSet = 1;//skip 0
	//handle playing
	XAUDIO2_VOICE_STATE state;
	for(std::set<SourceVoice*>::iterator it=playing.begin();it!=playing.end();++it)
	{
		(*it)->GetVoice()->GetState(&state);
		if(state.BuffersQueued <= 0)
			finished.push_back(*it);
	}
	//clean up
	for(std::vector<SourceVoice*>::iterator it=finished.begin();it!=finished.end();++it)
	{
		playing.erase(*it);
		(*it)->Release();
	}
	finished.clear();
}

sound.h
#pragma once

class Audio;
class SourceVoice;
class SoundData;
class Sound : public ISound
{
public:
	virtual int AddRef();
	virtual int Release();
	virtual int GetRefCnt();

	virtual void StopAll();
	virtual ISourceVoice* Play(float volume=1.0f, bool looped=false);
	virtual ISourceVoice* Play(bool looped);
	
	Sound(Audio *audio, const std::wstring &file);
	virtual ~Sound();
private:
	int refCnt;
	Audio *audio;
	SoundData *soundData;
	unsigned char *data;
};

sound.cpp
#include "precompiled.h"
#include "sound.h"
#include "sound_data.h"
#include "audio.h"
#include "source_Voice.h"
//REFRENCE COUNTING
int Sound::AddRef()
{
	return ++refCnt;
}
int Sound::Release()
{
	int r = --refCnt;
	if(!r)delete this;
	return r;
}
int  Sound::GetRefCnt()
{
	return refCnt;
}
//CONSTRUCT/DESTRUCT
Sound::Sound(Audio *_audio, const std::wstring &file)
:refCnt(0), audio(_audio), soundData(0), data(0)
{
	audio->AddRef();
	try
	{
		soundData = new SoundData(file);
		data = new unsigned char[soundData->GetSize()];
		soundData->Read(data, soundData->GetSize());
	}
	catch(...)
	{
		delete soundData;
		delete data;
		audio->Release();
		throw;
	}
}
Sound::~Sound()
{
	delete data;
	delete soundData;
	audio->Release();
}
//PLAY
ISourceVoice *Sound::Play(bool looped)
{
	return Play(1.0f, looped);
}
ISourceVoice *Sound::Play(float volume, bool looped)
{
	//create voice
	IXAudio2SourceVoice* voice;
	if(FAILED(audio->GetXAudio2()->CreateSourceVoice(
		&voice, soundData->GetFormat())))
		throw exception::Error(L"Failed to create source voice.");
	//create buffer
	XAUDIO2_BUFFER buffer = {0};
	buffer.pAudioData     = data;
	buffer.Flags          = XAUDIO2_END_OF_STREAM;
	buffer.AudioBytes     = soundData->GetSize();
	//set other stuff
	voice->SetVolume(volume, audio->GetCurrentOpSet());
	//looped
	if(looped)
		buffer.LoopCount = XAUDIO2_LOOP_INFINITE;
	//create voice object
	SourceVoice *voiceOut = new SourceVoice(audio, this, voice, looped);
	//start
	audio->AddSourceVoice(voiceOut);
	voice->Start(0, audio->GetCurrentOpSet());
	return voiceOut;
}
void Sound::StopAll()
{
	audio->StopAllSound(this);
}


sound_data.h
#pragma once
class SoundData
{
public:
	WAVEFORMATEX * GetFormat(){return format;}
	unsigned       GetSize()  {return size;}
	int            Read(unsigned char *data, unsigned bytes);
	
	SoundData(const std::wstring &file);
	virtual ~SoundData();
protected:
	unsigned size;
	unsigned read;
	WAVEFORMATEX *format;
	std::ifstream in;
	void loadWAV();
	void loadPCM(unsigned formatSize);
	int  readPCM(unsigned char *data, unsigned bytes);
	
};

sound_data.cpp
SoundData::SoundData(const std::wstring &file)
:read(0)
{
	std::wstring ext;
	size_t pos = file.find_last_of(L'.');
	if(pos == file.npos)
		throw exception::InvalidArg(L"File has no extension");
	ext = file.substr(pos);

	in.open(file.c_str(), std::ios::in | std::ios::binary);
	if(!in.good())
		throw exception::Error(L"Failed to open file");
	if(ext == L".wav")
		loadWAV();
}
SoundData::~SoundData()
{
	delete format;
}
int SoundData::Read(unsigned char *data, unsigned bytes)
{
	switch(format->wFormatTag)
	{
	case WAVE_FORMAT_PCM:
		return readPCM(data, bytes);
	default:
		return 0;
	}
}
//WAVE FILES
void SoundData::loadWAV()
{
	char id[5];
	id[4] = '\0';
	//valid media file
	in.read(id,4);
	if(strcmp(id, "RIFF")!=0)
		throw exception::Error(L"Not a valid media file");
	//skip 4 bytes
	in.seekg(4, std::ios::cur);
	//is wave
	in.read(id, 4);
	if(strcmp(id, "WAVE")!=0)
		throw exception::Error(L"Not a valid wave file");
	//skip over _fmt
	in.seekg(4, std::ios::cur);
	//read format section
	unsigned size;
	unsigned short formatTag;
	in.read((char*)&size,      4);
	in.read((char*)&formatTag, 2);
	//decide what format we have
	switch(formatTag)
	{
	case WAVE_FORMAT_PCM:
		loadPCM(size);
		break;
	default:
		throw exception::Error(
			L"Unsupported wav format: "+boost::lexical_cast<std::wstring>(formatTag));
	}
}
void SoundData::loadPCM(unsigned formatSize)
{
	if(formatSize < 16)
		throw exception::Error(L"Unknown format size, less than 16");
	format = new WAVEFORMATEX;
	format->cbSize     = formatSize - 16;
	format->wFormatTag = WAVE_FORMAT_PCM;
	//FORMAT CHUNK
	in.read((char*)&format->nChannels,       2);
	in.read((char*)&format->nSamplesPerSec,  4);
	in.read((char*)&format->nAvgBytesPerSec, 4);
	in.read((char*)&format->nBlockAlign,     2);
	in.read((char*)&format->wBitsPerSample,  2);
	//skip to end of format section
	in.seekg(formatSize-16,std::ios::cur);
	//DATA
	char str[5];
	str[4] = '\0';
	unsigned csize;
	while(true)
	{
		in.read(str,4);//chunck name
		in.read((char*)&csize,4);
		if(strcmp(str, "data")==0)break;//data section
		
		in.seekg(csize,std::ios::cur);//skip chunk
		if(!in.good())//failed, eg eof
			throw exception::Error(L"Failed to find data section");
	}
	size = csize;
}
int SoundData::readPCM(unsigned char *data, unsigned int bytes)
{
	if(bytes > size-read)
		bytes = size-read;
	
	in.read((char*)data, bytes);
	if(!in.good())
		throw exception::Error(L"Input stream read failed");
	read += bytes;
	return bytes;
}

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement