add sound reader code
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
#ifndef RAGE_SOUND_READER_H
|
||||
#define RAGE_SOUND_READER_H
|
||||
|
||||
/* A sound reader is a source for a RageSound. It's usually just a convenience
|
||||
* wrapper around SDL_Sound. */
|
||||
class SoundReader {
|
||||
mutable string error;
|
||||
|
||||
protected:
|
||||
void SetError(string e) const { error = e; }
|
||||
|
||||
public:
|
||||
virtual bool Open(CString filename) = 0;
|
||||
virtual int GetLength() const = 0; /* ms */
|
||||
virtual int GetLength_Fast() const { return GetLength(); } /* ms */
|
||||
virtual int SetPosition_Accurate(int ms) = 0;
|
||||
virtual int SetPosition_Fast(int ms) { return SetPosition_Accurate(ms); }
|
||||
virtual int Read(char *buf, unsigned len) = 0;
|
||||
virtual ~SoundReader() { }
|
||||
|
||||
bool Error() const { return !error.empty(); }
|
||||
string GetError() const { return error; }
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,144 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
/*
|
||||
* Known problems:
|
||||
* I hear a click in one speaker at the beginning of some MP3s. This is probably
|
||||
* something wrong with my SDL_sound MAD wrapper ...
|
||||
*/
|
||||
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "SDL_sound-1.0.0/lib/sdl_sound_static_d.lib")
|
||||
#else
|
||||
#pragma comment(lib, "SDL_sound-1.0.0/lib/sdl_sound_static.lib")
|
||||
#endif
|
||||
|
||||
#include "RageSoundReader_SDL_Sound.h"
|
||||
|
||||
const int channels = 2;
|
||||
const int samplesize = 2 * channels; /* 16-bit */
|
||||
const int samplerate = 44100;
|
||||
|
||||
/* The amount of data to read from SDL_sound at once. */
|
||||
const int read_block_size = 1024;
|
||||
|
||||
bool SoundReader_SDL_Sound::Open(CString filename)
|
||||
{
|
||||
inbuf = NULL;
|
||||
avail = 0;
|
||||
|
||||
Sound_AudioInfo sound_desired;
|
||||
sound_desired.channels = channels;
|
||||
sound_desired.format = AUDIO_S16SYS;
|
||||
sound_desired.rate = samplerate;
|
||||
|
||||
Sample = Sound_NewSampleFromFile(filename.GetString(),
|
||||
&sound_desired, read_block_size);
|
||||
|
||||
if(Sample)
|
||||
return true;
|
||||
|
||||
SetError(Sound_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
int SoundReader_SDL_Sound::GetLength() const
|
||||
{
|
||||
int len = Sound_Length(Sample);
|
||||
if(len == -1 && Sample->flags & SOUND_SAMPLEFLAG_EAGAIN) {
|
||||
/* This indicates the length check will take a little while; call
|
||||
* it again to confirm. */
|
||||
len = Sound_Length(Sample);
|
||||
}
|
||||
|
||||
if(len < 0)
|
||||
{
|
||||
SetError(Sound_GetError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int SoundReader_SDL_Sound::GetLength_Fast() const
|
||||
{
|
||||
int ret = Sound_Length(Sample);
|
||||
|
||||
Sound_Rewind(Sample);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SoundReader_SDL_Sound::SetPosition(int ms, bool accurate)
|
||||
{
|
||||
if(ms == 0)
|
||||
{
|
||||
Sound_Rewind(Sample);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret;
|
||||
if(accurate)
|
||||
ret = Sound_AccurateSeek(Sample, ms);
|
||||
else
|
||||
ret = Sound_FastSeek(Sample, ms);
|
||||
|
||||
if(Sample->flags & SOUND_SAMPLEFLAG_ERROR)
|
||||
{
|
||||
SetError(Sound_GetError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If the seek function returned false but didn't set error, it's a
|
||||
* recoverable error. We probably seeked past end of file. */
|
||||
if(!ret)
|
||||
{
|
||||
/* Past EOF. Rewind. */
|
||||
Sound_Rewind(Sample);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
return ms;
|
||||
}
|
||||
|
||||
int SoundReader_SDL_Sound::Read(char *buf, unsigned len)
|
||||
{
|
||||
int bytes_read = 0;
|
||||
while(len)
|
||||
{
|
||||
if(!avail)
|
||||
{
|
||||
/* Don't read at all if we've already hit EOF (it'll whine). */
|
||||
if(Sample->flags & SOUND_SAMPLEFLAG_EOF)
|
||||
return bytes_read; /* EOF */
|
||||
|
||||
int cnt = Sound_Decode(Sample);
|
||||
|
||||
if(Sample->flags & SOUND_SAMPLEFLAG_EOF)
|
||||
return bytes_read; /* EOF */
|
||||
|
||||
if(Sample->flags & SOUND_SAMPLEFLAG_ERROR)
|
||||
{
|
||||
SetError(Sound_GetError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
avail = cnt;
|
||||
inbuf = (const char *) Sample->buffer;
|
||||
}
|
||||
|
||||
unsigned size = min(avail, len);
|
||||
memcpy(buf, inbuf, size);
|
||||
buf += size;
|
||||
len -= size;
|
||||
inbuf += size;
|
||||
avail -= size;
|
||||
bytes_read += size;
|
||||
}
|
||||
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
SoundReader_SDL_Sound::~SoundReader_SDL_Sound()
|
||||
{
|
||||
Sound_FreeSample(Sample);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef RAGE_SOUND_READER_SDL_SOUND
|
||||
#define RAGE_SOUND_READER_SDL_SOUND
|
||||
|
||||
#include "RageSoundReader.h"
|
||||
#include "SDL_sound-1.0.0/SDL_sound.h"
|
||||
|
||||
class SoundReader_SDL_Sound: public SoundReader {
|
||||
Sound_Sample *Sample;
|
||||
const char *inbuf;
|
||||
unsigned avail;
|
||||
int SetPosition(int ms, bool accurate);
|
||||
|
||||
public:
|
||||
bool Open(CString filename);
|
||||
int GetLength() const;
|
||||
int GetLength_Fast() const;
|
||||
int SetPosition_Accurate(int ms) { return SetPosition(ms, true); }
|
||||
int SetPosition_Fast(int ms) { return SetPosition(ms, false); }
|
||||
int Read(char *buf, unsigned len);
|
||||
~SoundReader_SDL_Sound();
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user