sdlmixer.cpp
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- Createmixer
- sdlaudio_callback
- open
- Mix
- Sync
- close
#include "sdlmixer.h"
// -- factory method
mymixer* mymixer_factory::Createmixer()
/* [<][>][^][v][top][bottom][index][help] */
{
return new sdlmixer();
}
void sdlaudio_callback(void* m, Uint8* stream, int len)
/* [<][>][^][v][top][bottom][index][help] */
{
sdlmixer* me = reinterpret_cast<sdlmixer*>(m);
if(me->bufsize != len){
fprintf(stderr, "warning: buffer size for callback differs.(%d)\n", len);
delete[] me->buf;
me->bufsize = len;
me->buf = new Uint8[len];
}
int mlen;
mlen = me->ring.Get(me->buf, len);
if(mlen == 0) return;
SDL_MixAudio(stream, me->buf, mlen, SDL_MIX_MAXVOLUME);
}
int sdlmixer::open(int rate = 44100)
/* [<][>][^][v][top][bottom][index][help] */
{
if(SDL_Init(SDL_INIT_AUDIO) < 0) return -1;
fmt.freq = rate;
fmt.format = AUDIO_S16;
fmt.channels = 2;
fmt.samples = 512;
fmt.callback = sdlaudio_callback;
fmt.userdata = this;
bufsize = fmt.samples * 32;
buf = new Uint8[bufsize];
if(SDL_OpenAudio(&fmt, NULL) < 0) return -1;
ring.bufInit(rate * 2 * 2 * 2); // 16bit 2ch 1sec
SDL_PauseAudio(1);
}
void sdlmixer::Mix(short* _buf, int samples)
/* [<][>][^][v][top][bottom][index][help] */
{
int remain = samples * sizeof(short);
int ret;
int ofs;
Uint8* ptr = reinterpret_cast<Uint8*>(_buf);
if(SDL_GetAudioStatus() != SDL_AUDIO_PLAYING){
if(ring.Capacity() > 30) SDL_PauseAudio(0);
}
ofs = 0;
while(1){
if(ring.Capacity() > 50) SDL_Delay(10);
SDL_LockAudio();
ret = ring.Put(ptr + ofs, remain);
SDL_UnlockAudio();
remain -= ret;
if(remain == 0) break;
ofs += ret;
}
}
void sdlmixer::Sync()
/* [<][>][^][v][top][bottom][index][help] */
{
fprintf(stderr, "Wait for ring buffer empty.\n");
while(!ring.isEmpty()) SDL_Delay(100);
}
void sdlmixer::close()
/* [<][>][^][v][top][bottom][index][help] */
{
SDL_CloseAudio();
}