From: <c99...@us...> - 2007-02-28 19:54:52
|
Revision: 393 http://svn.sourceforge.net/cadcdev/?rev=393&view=rev Author: c99koder Date: 2007-02-28 11:43:35 -0800 (Wed, 28 Feb 2007) Log Message: ----------- Tiki: Dreamcast sound streaming wrapper Modified Paths: -------------- tiki/dc/src/audio/stream.cpp tiki/include/Tiki/stream.h Modified: tiki/dc/src/audio/stream.cpp =================================================================== --- tiki/dc/src/audio/stream.cpp 2007-01-28 22:41:27 UTC (rev 392) +++ tiki/dc/src/audio/stream.cpp 2007-02-28 19:43:35 UTC (rev 393) @@ -3,6 +3,7 @@ stream.cpp + Copyright (C)2007 Sam Steele Copyright (C)2005 Cryptic Allusion, LLC */ @@ -10,10 +11,33 @@ #include "Tiki/stream.h" #include <string.h> +#include <vector> using namespace Tiki::Audio; using namespace Tiki::Thread; +Stream *streams[SND_STREAM_MAX]; +static uint8 pcm_buffer[SND_STREAM_BUFFER_MAX+16384]; + +void *cbk(snd_stream_hnd_t hnd, int size, int * size_out) { + int pcm_decoded = 0; + + /* Check if the callback requests more data than our buffer can hold */ + if (size > SND_STREAM_BUFFER_MAX) + size = SND_STREAM_BUFFER_MAX; + + pcm_decoded = size / (2 * streams[(int)hnd]->getChannelCount()); + Stream::GetDataResult rv = streams[(int)hnd]->getData((uint16 *)pcm_buffer,&pcm_decoded); + pcm_decoded *= (2 * streams[(int)hnd]->getChannelCount()); + if(rv == Stream::GDError || rv == Stream::GDEOS) { + *size_out = 0; + return NULL; + } else { + *size_out = pcm_decoded; + return pcm_buffer; + } +} + TIKI_OBJECT_NAME(Stream) TIKI_OBJECT_BEGIN(Object, Stream) TIKI_OBJECT_RECEIVER("start", Stream::objectStart) @@ -30,13 +54,15 @@ Stream::Stream() { // Default our members. - m_bufSize = 0x4000; - m_chnCount = 2; + m_bufSize = SND_STREAM_BUFFER_MAX; + m_chnCount = 1; m_freq = 44100; m_queueing = false; - m_isPlaying = false; m_volume = 0.8f; m_mutex = new Mutex(); + m_thread = NULL; + m_threadActive = false; + m_state = StateStopped; } Stream::~Stream() { @@ -44,16 +70,21 @@ } bool Stream::create() { - AutoLock lock(m_mutex); + destroy(); + + assert( m_state == StateStopped ); + hnd = snd_stream_alloc(cbk,SND_STREAM_BUFFER_MAX); + streams[hnd] = this; + return true; } void Stream::destroy() { - AutoLock lock(m_mutex); + stop(); + + assert( m_state == StateStopped ); } -// virtual void filter(int freq, int chncount, void * buffer, int smpcnt) { } - void Stream::filterAdd(Filter * f) { AutoLock lock(m_mutex); @@ -85,24 +116,37 @@ } void Stream::start() { - AutoLock lock(m_mutex); - m_isPlaying = true; + if (m_state != StateStopped) + return; + + m_state = StatePlaying; + snd_stream_volume(hnd,int(255.0f * m_volume)); + printf("Starting audio thread...\n"); + m_threadActive = true; + m_thread = new Thread::Thread(alThreadProc, this); } void Stream::stop() { - AutoLock lock(m_mutex); + if (m_state == StateStopped) + return; - pause(); + assert( m_thread ); + m_threadActive = false; + printf("Joining audio thread...\n"); + m_thread->join(); + delete m_thread; + m_thread = NULL; } void Stream::pause() { - AutoLock lock(m_mutex); - m_isPlaying = false; + if (m_state != StatePlaying) + return; + + m_state = StatePaused; } void Stream::resume() { AutoLock lock(m_mutex); - m_isPlaying = true; } void Stream::setVolume(float vol) { @@ -112,9 +156,7 @@ } bool Stream::isPlaying() { - AutoLock lock(m_mutex); - - return m_isPlaying; + return m_state == StatePlaying; } int Stream::objectStart(Object * /*from*/, Object * /*arg*/) { @@ -129,32 +171,31 @@ void Stream::processFilters(void * buffer, int smpcnt) { } -// "len" is a *sample* count. -void Stream::sepData(void * buffer, int len, bool stereo, int16 * outl, int16 * outr) { - int16 * sep_buffer[2] = { outl, outr }; - int16 * bufsrc, * bufdst; - int cnt; +void * Stream::alThreadProc(void * u) { + Stream * us = (Stream *)u; + us->threadProc(); + return NULL; +} - if (stereo) { - bufsrc = (int16*)buffer; - bufdst = sep_buffer[0]; - cnt = len; - do { - *bufdst = *bufsrc; - bufdst++; bufsrc+=2; cnt--; - } while (cnt > 0); +void Stream::threadProc() { + int stat; + + printf("Starting stream...\n"); + snd_stream_start(hnd,m_freq,m_chnCount-1); - bufsrc = (int16*)buffer; bufsrc++; - bufdst = sep_buffer[1]; - cnt = len; - do { - *bufdst = *bufsrc; - bufdst++; bufsrc+=2; cnt--; - } while (cnt > 0); - } else { - memcpy(sep_buffer[0], buffer, len * 2); - memcpy(sep_buffer[1], buffer, len * 2); + while (m_threadActive) { + AutoLock lock(m_mutex); + if((stat = snd_stream_poll(hnd)) < 0) { + printf("Stopping, status: %d\n",stat); + m_threadActive = false; + } + lock.unlock(); + thd_sleep(2); } + printf("Stopping stream...\n"); + snd_stream_stop(hnd); + m_state = StateStopped; + printf("Stream stopped\n"); } Stream::GetDataResult Stream::getData(uint16 * buffer, int * numSamples) { Modified: tiki/include/Tiki/stream.h =================================================================== --- tiki/include/Tiki/stream.h 2007-01-28 22:41:27 UTC (rev 392) +++ tiki/include/Tiki/stream.h 2007-02-28 19:43:35 UTC (rev 393) @@ -75,6 +75,7 @@ void setQueueing(bool isQueued); void setFrequency(int freq); void setChannelCount(int chncount); + int getChannelCount() { return m_chnCount; } virtual void start(); virtual void stop(); virtual void pause(); @@ -87,7 +88,7 @@ int objectStart(Object * from, Object * arg); int objectStop(Object * from, Object * arg); -protected: +public: // Your subclass must override this to provide data for the stream. When // this is called, you should try to place numSamples samples into buffer. // Return the disposition of the stream, and place the actual number of @@ -103,8 +104,9 @@ }; virtual GetDataResult getData(uint16 * buffer, int * numSamples); +protected: void processFilters(void * buffer, int smpcnt); -static void sepData(void * buffer, int len, bool stereo, int16 * outl, int16 * outr); + void sepData(void * buffer, int len, bool stereo, int16 * outl, int16 * outr); protected: @@ -128,11 +130,13 @@ ALuint m_buffers[2]; ALuint m_source; ALenum m_format; +#else + #endif Thread::Thread * m_thread; volatile bool m_threadActive; -static void * alThreadProc(void * us); +static void * alThreadProc(void * us); void threadProc(); void check(); #if TIKI_PLAT != TIKI_DC && TIKI_PLAT != TIKI_NDS @@ -141,7 +145,7 @@ #if TIKI_PLAT == TIKI_DC private: - bool m_isPlaying; + int hnd; #endif }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |