int aica_audio_open(int freq, int channels, uint32_t size) { if (audio_mut == NULL) { audio_mut = mutex_create(); } sample_rate = freq; chans = channels; tmpbuf = (uint8*) malloc(BUFFER_MAX_FILL); sndbuf = (uint8*) malloc(BUFFER_MAX_FILL); memset (tmpbuf, 0, BUFFER_MAX_FILL); memset (sndbuf, 0, BUFFER_MAX_FILL); sbsize = size; sndptr = last_read = snd_ct = 0; waiting_for_data = 1; shnd = snd_stream_alloc(aica_audio_callback, sbsize); if(shnd < 0) { ds_printf("DS_ERROR: Can't alloc stream\n"); return -1; } snd_stream_prefill(shnd); snd_stream_start(shnd, freq, channels-1); return 0; }
/* Call this function as a thread to handle playback. Playback will stop and this thread will return when you call sndmp3_shutdown(). */ static void sndmp3_thread() { int sj; stream_hnd = snd_stream_alloc(NULL, SND_STREAM_BUFFER_MAX); if(stream_hnd < 0) { printf("sndserver: can't alloc stream\r\n"); return; } /* Main command loop */ while(sndmp3_status != STATUS_QUIT) { switch(sndmp3_status) { case STATUS_INIT: sndmp3_status = STATUS_READY; break; case STATUS_READY: printf("sndserver: waiting on semaphore\r\n"); sem_wait(sndmp3_halt_sem); printf("sndserver: released from semaphore\r\n"); break; case STATUS_STARTING: /* Initialize streaming driver */ if (snd_stream_reinit(stream_hnd, mpg123_callback) < 0) { sndmp3_status = STATUS_READY; } else { snd_stream_start(stream_hnd, rate, channels - 1); sndmp3_status = STATUS_PLAYING; } break; case STATUS_REINIT: /* Re-initialize streaming driver */ snd_stream_reinit(stream_hnd, NULL); sndmp3_status = STATUS_READY; break; case STATUS_PLAYING: { sj = jiffies; if (snd_stream_poll(stream_hnd) < 0) { if (sndmp3_loop) { printf("sndserver: restarting '%s'\r\n", mp3_last_fn); if (libmpg123_init(mp3_last_fn) < 0) { sndmp3_status = STATUS_STOPPING; mp3_last_fn[0] = 0; } } else { printf("sndserver: not restarting\r\n"); snd_stream_stop(stream_hnd); sndmp3_status = STATUS_READY; mp3_last_fn[0] = 0; } // stream_start(); } else thd_sleep(50); break; } case STATUS_STOPPING: snd_stream_stop(stream_hnd); sndmp3_status = STATUS_READY; break; } } /* Done: clean up */ libmpg123_shutdown(); snd_stream_stop(stream_hnd); snd_stream_destroy(stream_hnd); sndmp3_status = STATUS_ZOMBIE; }
/* Call this function as a thread to handle playback. Playback will stop and this thread will return when you call sndmp3_shutdown(). */ static void sndmp3_thread() { int sj; stream_hnd = snd_stream_alloc(NULL, SND_STREAM_BUFFER_MAX); //assert( stream_hnd != -1 ); /* Main command loop */ while(sndmp3_status != STATUS_QUIT) { switch(sndmp3_status) { case STATUS_INIT: sndmp3_status = STATUS_READY; break; case STATUS_READY: printf("sndserver: waiting on semaphore\r\n"); sem_wait(sndmp3_halt_sem); printf("sndserver: released from semaphore\r\n"); break; case STATUS_STARTING: /* Initialize streaming driver */ if (snd_stream_reinit(stream_hnd, mpglib_callback) < 0) { sndmp3_status = STATUS_READY; } else { //snd_stream_start(stream_hnd, decinfo.samprate, decinfo.channels - 1); //snd_stream_start(stream_hnd, 44100, 1); snd_stream_start(stream_hnd, freqs[mp.fr.sampling_frequency], mp.fr.stereo); sndmp3_status = STATUS_PLAYING; } break; case STATUS_REINIT: /* Re-initialize streaming driver */ snd_stream_reinit(stream_hnd, NULL); sndmp3_status = STATUS_READY; break; case STATUS_PLAYING: { sj = jiffies; if (snd_stream_poll(stream_hnd) < 0) { if (sndmp3_loop) { printf("sndserver: restarting '%s'\r\n", mp3_last_fn); if (mpglib_init(mp3_last_fn) < 0) { sndmp3_status = STATUS_STOPPING; mp3_last_fn[0] = 0; } } else { printf("sndserver: not restarting\r\n"); snd_stream_stop(stream_hnd); sndmp3_status = STATUS_READY; mp3_last_fn[0] = 0; } // stream_start(); } else thd_sleep(50); break; } case STATUS_STOPPING: snd_stream_stop(stream_hnd); sndmp3_status = STATUS_READY; break; } } /* Done: clean up */ mpglib_shutdown(); snd_stream_stop(stream_hnd); snd_stream_destroy(stream_hnd); sndmp3_status = STATUS_ZOMBIE; }
/* sndoggvorbis_thread() * * this function is called by sndoggvorbis_mainloop and handles all the threads * status handling and playing functionality. */ void sndoggvorbis_thread() { int stat; stream_hnd = snd_stream_alloc(NULL, SND_STREAM_BUFFER_MAX); assert( stream_hnd != SND_STREAM_INVALID ); while(sndoggvorbis_status != STATUS_QUIT) { switch(sndoggvorbis_status) { case STATUS_INIT: sndoggvorbis_status= STATUS_READY; break; case STATUS_READY: printf("oggthread: waiting on semaphore\n"); sem_wait(sndoggvorbis_halt_sem); printf("oggthread: released from semaphore (status=%d)\n", sndoggvorbis_status); break; case STATUS_QUEUEING: { vorbis_info * vi = ov_info(&vf, -1); snd_stream_reinit(stream_hnd, callback); snd_stream_queue_enable(stream_hnd); printf("oggthread: stream_init called\n"); snd_stream_start(stream_hnd, vi->rate, vi->channels - 1); snd_stream_volume(stream_hnd, sndoggvorbis_vol); printf("oggthread: stream_start called\n"); if (sndoggvorbis_status != STATUS_STOPPING) sndoggvorbis_status = STATUS_QUEUED; break; } case STATUS_QUEUED: printf("oggthread: queue waiting on semaphore\n"); sem_wait(sndoggvorbis_halt_sem); printf("oggthread: queue released from semaphore\n"); break; case STATUS_STARTING: { vorbis_info * vi = ov_info(&vf, -1); if (sndoggvorbis_queue_enabled) { snd_stream_queue_go(stream_hnd); } else { snd_stream_reinit(stream_hnd, callback); printf("oggthread: stream_init called\n"); snd_stream_start(stream_hnd, vi->rate, vi->channels - 1); printf("oggthread: stream_start called\n"); } snd_stream_volume(stream_hnd, sndoggvorbis_vol); sndoggvorbis_status=STATUS_PLAYING; break; } case STATUS_PLAYING: /* Preliminary Bitrate Code * For our tests the bitrate is being set in the struct once in a * while so that the user can just read out this value from the struct * and use it for whatever purpose */ /* if (tempcounter==sndoggvorbis_bitrateint) { long test; if((test=VorbisFile_getBitrateInstant()) != -1) { sndoggvorbis_info.actualbitrate=test; } tempcounter = 0; } tempcounter++; */ /* Stream Polling and end-of-stream detection */ if ( (stat = snd_stream_poll(stream_hnd)) < 0) { printf("oggthread: stream ended (status %d)\n", stat); printf("oggthread: not restarting\n"); snd_stream_stop(stream_hnd); /* Reset our PCM buffer */ pcm_count = 0; last_read = 0; pcm_ptr = pcm_buffer; /* This can also happen sometimes when you stop the stream manually, so we'll call this here to make sure */ ov_clear(&vf); sndoggvorbis_lastfilename[0] = 0; sndoggvorbis_status = STATUS_READY; sndoggvorbis_clear_comments(); } else { /* Sleep some until the next buffer is needed */ thd_sleep(50); } break; case STATUS_STOPPING: snd_stream_stop(stream_hnd); ov_clear(&vf); /* Reset our PCM buffer */ pcm_count = 0; last_read = 0; pcm_ptr = pcm_buffer; sndoggvorbis_lastfilename[0] = 0; sndoggvorbis_status = STATUS_READY; sndoggvorbis_clear_comments(); break; } } snd_stream_stop(stream_hnd); snd_stream_destroy(stream_hnd); sndoggvorbis_status=STATUS_ZOMBIE; printf("oggthread: thread released\n"); }