PDA

View Full Version : KOS sound streaming



GPF
December 2nd, 2004, 23:14
I am currently also trying to figure out how to convert SDL sound to KOS sound streaming but don't know where to start. Is there any examples anywhere? All the kos examples are for sndvorbis and mp3/wav playback.

My code has the stereo sound in a buffer and then dac sound effects in another buffer, and its using

SDL_BuildAudioCVT(&acvt, AUDIO_U8, 1, 8000, DEFAULT_FORMAT,DEFAULT_CHANNELS, samplerate)

and
SDL_ConvertAudio(&acvt)

then its mixing the both streams into one

SDL_MixAudio(sound_buffer+sound_frame_write, dac_data, bpf, SDL_MIX_MAXVOLUME);

how would I replace this with KOS calls? use multiple channels? Any examples or help is appreciated.

Thanks,

Troy

DanPotter
December 3rd, 2004, 00:39
Actually you kinda answered your own question. :) Take a look at the liboggvorbisplay/libtremor examples and it shows how to set up and use the streaming. In SVN KOS you can have as many streaming channels as you want, in addition to mono or stereo.

Oh also I guess you meant you need sound effects. That's done with the snd_sfx_* calls.

kernel/arch/dreamcast/include/dc/sound/sfxmgr.h

GPF
December 3rd, 2004, 08:28
oops I forgot to mention it was for an emulator port, so there are no sound files to load.

I was looking for an example that used the sound callback and sound polling. Closest example I could find was the Modplug example, but still don't understand how I use it :)

here is a simple psuedo code of what I am trying to do.

initbuffers(1 buffer is stereo sound, and 2nd buffer is mono sound effectsl) and start sound streaming - how do I set up the multiple channels? do I need multiple callbacks?

emulator calls a sound_update function with a number of frames of sound to play, that then calls 2 different core functions to get sound data into the 2 buffers.
do I add snd_stream_poll(...); to this section?

when does the callback function get called and what actually should be in the function.

Thanks I am new to sound other the loading a file and letting the arm play it.

Troy

JMD
December 3rd, 2004, 09:57
If found an exemple of emulator sound streaming in the stef genPlus source he posted on this topic (http://www.dcemu.co.uk/cgi-bin/yabb/YaBB.pl?board=dcemu;action=display;num=1083323639; start=120).

I'm still working on the implementation of the sound streaming in my own project with this exemple + the KOS oggvorbis exemple.
My code already does something : it crash :) ....
That's a (good ?) begining.

quzar
December 3rd, 2004, 12:18
i'm having a similar problem. Trying to replace this code:



int init_sdl_audio(void)
{

if(SDL_InitSubSystem(SDL_INIT_AUDIO)) { fprintf(stderr,"Couldn't Start Sound.\n"); }

desired.freq = SAMPLE_RATE;
desired.samples = NB_SAMPLES;
desired.format = AUDIO_S16;
desired.channels = 2;
desired.callback = update_sdl_stream;
desired.userdata = NULL;
SDL_OpenAudio(&desired, NULL);
streams_sh_start();
YM2610_sh_start();
SDL_PauseAudio(0);

return 1;
}

I tried replacing it with this:


int init_sdl_audio(void)
{

snd_stream_init(update_sdl_stream);
snd_stream_queue_enable();
snd_stream_start(SAMPLE_RATE, 1);
//hangs here ^^^
streams_sh_start();
YM2610_sh_start();
return 1;
}


but it hangs at the point where I marked, within the init function, not between the two. Maybe I have to fill my buffers first? Of course, my effort is not aided by the fact that the original SDL code gives no sound on the Dreamcast either =\ (works fine on PC).

DanPotter
December 3rd, 2004, 13:01
I think maybe you misunderstand what the "queue" functions do. When you enable queueing it fills up all the buffers, loads it into SPU RAM, and generally gets ready to hit the ground running. When you tell it to go, sound starts coming out instantly. I did that for the timing in FoF.

I'd recommend removing the queue calls to see if that makes it go for now.

Also I'm sure you've realized this, but the function decl for the SDL callback is almost assuredly different than the KOS one, so you will have to change that too.

quzar
December 3rd, 2004, 13:26
the queue functions i added later, it didnt work without them either. Ill look at the callback, thanks. (from what i looked at it seemed the same).

edit: WOW, i cant believe i missed that =P. the two callbacks send and ask for the same things but the orders are different, so maybe it will work now, thanks =). [now to fix the random crashing first...]

quzar
December 3rd, 2004, 18:18
hrm, no matter what i do it seems to hang after printing the following:

snd_init(): loading 3408 bytes into SPU RAM
and just... hangs. Any helpful hint as to what i may be doing wrong?

DanPotter
December 3rd, 2004, 19:51
This is about the time I start throwing printf's in the code :)

quzar
December 3rd, 2004, 21:21
This is about the time I start throwing printf's in the code :)



poo. that means having to recompile kos over and over, something i dont like doing =P. oh well, thanks anyways, ill just try that. (i thought there might be something specific i didnt do).

GPF
December 4th, 2004, 02:30
#include <dc/sound/stream.h>

int samplerate=44100; /* desired output sample rate */

uint16 sound_buffer[SND_STREAM_BUFFER_MAX] = {0};
uint8 dac_buffer[SND_STREAM_BUFFER_MAX] = {0};
snd_stream_hnd_t shnd;
snd_stream_hnd_t shnd2;

void *audio_callback(snd_stream_hnd_t hnd, int samples_requested, int *samples_returned)
{
sound_update((_u16*)(sound_buffer), samples_requested ); //core stereo sound update funct
*samples_returned = samples_requested;
return sound_buffer;
}

void *dac_audio_callback(snd_stream_hnd_t hnd, int samples_requested, int *samples_returned)
{
dac_update((_u8*)(dac_buffer), samples_requested ); //core dac sound update funct
*samples_returned = samples_requested;
return dac_buffer;
}
void
system_sound_chipreset(void)
{
sound_init(samplerate);
return;
}

BOOL
system_sound_init(void)
{
sound_init(samplerate); //inits core sound
snd_stream_init();

shnd = snd_stream_alloc(*audio_callback, SND_STREAM_BUFFER_MAX);

snd_stream_start(shnd,samplerate, 1);

shnd2 = snd_stream_alloc(*dac_audio_callback, SND_STREAM_BUFFER_MAX);

snd_stream_start(shnd2,8192, 0);

return TRUE;
}

void
system_sound_shutdown(void)
{
snd_stream_stop(shnd);
snd_stream_stop(shnd2);
snd_stream_shutdown();
return;
}

void
system_sound_update(int nframes) //called every VBL
{
snd_stream_poll(shnd);
snd_stream_poll(shnd2);
}


OK this works for me with kos 1.3 svn 165

Don't know if this is the most efficient way, should I have 2 different callback functions ? and poll like this.

THanks,

Troy

GPF
December 7th, 2004, 00:22
I am currently also trying to figure out how to convert SDL sound to KOS sound streaming but don't know where to start. Is there any examples anywhere? All the kos examples are for sndvorbis and mp3/wav playback.

My code has the stereo sound in a buffer and then dac sound effects in another buffer, and its using

SDL_BuildAudioCVT(&acvt, AUDIO_U8, 1, 8000, DEFAULT_FORMAT,DEFAULT_CHANNELS, samplerate)

and
SDL_ConvertAudio(&acvt)

then its mixing the both streams into one

SDL_MixAudio(sound_buffer+sound_frame_write, dac_data, bpf, SDL_MIX_MAXVOLUME);

how would I replace this with KOS calls? use multiple channels? Any examples or help is appreciated.

Thanks,

Troy

well now that I have the sound streaming working I still need some help figuring out how to get the DAC audio to play correctly its frequency is 8000hz, 1 channel 8 bit sound. How do I set up a filter or start the stream to play this?

Thanks,
Troy

GPF
December 17th, 2004, 01:09
still haven't figured out the DAC sound, but anyway.

How do I pause the sound or stop so I can restart it later?

Is there a way to tell where in sound buffer the current position is being played ? so I dont resend the same sound in my callback function

Thanks,
Troy

GPF
December 17th, 2004, 11:40
ok figured it out

snd_stream_stop(shnd);

and then

snd_stream_start(shnd,44100,1);

to restart it,

Still need help converting the DAC sound from 8 bit 8000hz mono to 16 bit 44100hz stereo so I can mix it .

Thanks,
Troy