|
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.
|