|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
#include "tsound_t.h"
|
|
Campbell Barton |
36d03a |
#include "texception.h"
|
|
Campbell Barton |
36d03a |
#include "tthread.h"
|
|
Campbell Barton |
36d03a |
#include "tthreadmessage.h"
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
#include <errno.h></errno.h>
|
|
Campbell Barton |
36d03a |
#include <unistd.h></unistd.h>
|
|
Campbell Barton |
36d03a |
#include <queue></queue>
|
|
Campbell Barton |
36d03a |
#include <set></set>
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
#include <sdl2 sdl.h=""></sdl2>
|
|
Campbell Barton |
36d03a |
using namespace std;
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//==============================================================================
|
|
Campbell Barton |
36d03a |
namespace {
|
|
Campbell Barton |
36d03a |
TThread::Mutex MutexOut;
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
namespace {
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
struct MyData {
|
|
Campbell Barton |
36d03a |
char *entireFileBuffer;
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
int totalPacketCount;
|
|
Campbell Barton |
36d03a |
int fileByteCount;
|
|
Campbell Barton |
36d03a |
// UInt32 maxPacketSize;
|
|
Campbell Barton |
36d03a |
// UInt64 packetOffset;
|
|
Campbell Barton |
36d03a |
int byteOffset;
|
|
Campbell Barton |
36d03a |
bool m_doNotify;
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
void *sourceBuffer;
|
|
Campbell Barton |
36d03a |
// AudioConverterRef converter;
|
|
Campbell Barton |
36d03a |
TSoundOutputDeviceImp *imp;
|
|
Campbell Barton |
36d03a |
bool isLooping;
|
|
Campbell Barton |
36d03a |
MyData()
|
|
Campbell Barton |
36d03a |
: entireFileBuffer(0)
|
|
Campbell Barton |
36d03a |
, totalPacketCount(0)
|
|
Campbell Barton |
36d03a |
, fileByteCount(0)
|
|
Campbell Barton |
36d03a |
, /*maxPacketSize(0), packetOffset(0),*/ byteOffset(0)
|
|
Campbell Barton |
36d03a |
, sourceBuffer(0)
|
|
Campbell Barton |
36d03a |
, isLooping(false)
|
|
Campbell Barton |
36d03a |
, imp(0)
|
|
Campbell Barton |
36d03a |
, m_doNotify(true) {}
|
|
Campbell Barton |
36d03a |
};
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
class TSoundOutputDeviceImp {
|
|
Campbell Barton |
36d03a |
public:
|
|
Campbell Barton |
36d03a |
bool m_isPlaying;
|
|
Campbell Barton |
36d03a |
bool m_looped;
|
|
Campbell Barton |
36d03a |
TSoundTrackFormat m_currentFormat;
|
|
Campbell Barton |
36d03a |
std::set<int> m_supportedRate;</int>
|
|
Campbell Barton |
36d03a |
bool m_opened;
|
|
Campbell Barton |
36d03a |
struct MyData *m_data;
|
|
Campbell Barton |
36d03a |
int m_volume;
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
TSoundOutputDeviceImp()
|
|
Campbell Barton |
36d03a |
: m_isPlaying(false)
|
|
Campbell Barton |
36d03a |
, m_looped(false)
|
|
Campbell Barton |
36d03a |
, m_supportedRate()
|
|
Campbell Barton |
36d03a |
, m_opened(false)
|
|
Campbell Barton |
36d03a |
, m_data(NULL)
|
|
Campbell Barton |
36d03a |
, m_volume(SDL_MIX_MAXVOLUME){};
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
std::set<tsoundoutputdevicelistener *=""> m_listeners;</tsoundoutputdevicelistener>
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
~TSoundOutputDeviceImp(){};
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
bool doOpenDevice(const TSoundTrackFormat &format);
|
|
Campbell Barton |
36d03a |
bool doStopDevice();
|
|
Campbell Barton |
36d03a |
void play(const TSoundTrackP &st, TINT32 s0, TINT32 s1, bool loop,
|
|
Campbell Barton |
36d03a |
bool scrubbing);
|
|
Campbell Barton |
36d03a |
};
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//-----------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
namespace {
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
class PlayCompletedMsg : public TThread::Message {
|
|
Campbell Barton |
36d03a |
std::set<tsoundoutputdevicelistener *=""> m_listeners;</tsoundoutputdevicelistener>
|
|
Campbell Barton |
36d03a |
MyData *m_data;
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
public:
|
|
Campbell Barton |
36d03a |
PlayCompletedMsg(MyData *data) : m_data(data) {}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
TThread::Message *clone() const { return new PlayCompletedMsg(*this); }
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
void onDeliver() {
|
|
Campbell Barton |
36d03a |
if (m_data->imp) {
|
|
Campbell Barton |
36d03a |
if (m_data->m_doNotify == false) return;
|
|
Campbell Barton |
36d03a |
m_data->m_doNotify = false;
|
|
Campbell Barton |
36d03a |
if (m_data->imp->m_isPlaying) m_data->imp->doStopDevice();
|
|
Campbell Barton |
36d03a |
std::set<tsoundoutputdevicelistener *="">::iterator it =</tsoundoutputdevicelistener>
|
|
Campbell Barton |
36d03a |
m_data->imp->m_listeners.begin();
|
|
Campbell Barton |
36d03a |
for (; it != m_data->imp->m_listeners.end(); ++it)
|
|
Campbell Barton |
36d03a |
(*it)->onPlayCompleted();
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
};
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
#define checkStatus(err) \
|
|
Campbell Barton |
36d03a |
if (err) { \
|
|
Campbell Barton |
36d03a |
printf("Error: 0x%x -> %s: %d\n", (int)err, __FILE__, __LINE__); \
|
|
Campbell Barton |
36d03a |
fflush(stdout); \
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
extern "C" {
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
void sdl_fill_audio(void *udata, Uint8 *stream, int len) {
|
|
Campbell Barton |
36d03a |
TSoundOutputDeviceImp *_this = (TSoundOutputDeviceImp *)udata;
|
|
Campbell Barton |
36d03a |
MyData *myData = _this->m_data;
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
/* Only play if we have data left */
|
|
Campbell Barton |
36d03a |
if (myData == NULL) return;
|
|
Campbell Barton |
36d03a |
{
|
|
Campbell Barton |
36d03a |
// TThread::ScopedLock sl(MutexOut);
|
|
Campbell Barton |
36d03a |
if (myData->imp->m_isPlaying == false) return;
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
int audio_len = myData->fileByteCount - myData->byteOffset;
|
|
Campbell Barton |
36d03a |
if (audio_len <= 0) {
|
|
Campbell Barton |
36d03a |
delete[] myData->entireFileBuffer;
|
|
Campbell Barton |
36d03a |
myData->entireFileBuffer = 0;
|
|
Campbell Barton |
36d03a |
#if 0
|
|
Campbell Barton |
36d03a |
{
|
|
Campbell Barton |
36d03a |
TThread::ScopedLock sl(MutexOut);
|
|
Campbell Barton |
36d03a |
*(myData->isPlaying) = false; //questo lo faccio nel main thread
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
#endif
|
|
Campbell Barton |
36d03a |
PlayCompletedMsg(myData).send();
|
|
Campbell Barton |
36d03a |
return;
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
/* Mix as much data as possible */
|
|
Campbell Barton |
36d03a |
len = (len > audio_len ? audio_len : len);
|
|
Campbell Barton |
36d03a |
SDL_MixAudio(stream, (Uint8 *)myData->entireFileBuffer + myData->byteOffset,
|
|
Campbell Barton |
36d03a |
len, _this->m_volume);
|
|
Campbell Barton |
36d03a |
myData->byteOffset += len;
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
} // extern "C"
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
bool TSoundOutputDeviceImp::doOpenDevice(const TSoundTrackFormat &format) {
|
|
Campbell Barton |
36d03a |
SDL_AudioSpec wanted;
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
static bool first = true; // TODO: should be shared with InputDevice
|
|
Campbell Barton |
36d03a |
if (first) {
|
|
Campbell Barton |
36d03a |
SDL_Init(SDL_INIT_AUDIO);
|
|
Campbell Barton |
36d03a |
first = false;
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
if (m_opened) {
|
|
Campbell Barton |
36d03a |
SDL_CloseAudio();
|
|
Campbell Barton |
36d03a |
// we'll just reopen right away
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
wanted.freq = format.m_sampleRate;
|
|
Campbell Barton |
36d03a |
switch (format.m_bitPerSample) {
|
|
Campbell Barton |
36d03a |
case 8:
|
|
Campbell Barton |
36d03a |
wanted.format = AUDIO_S8;
|
|
Campbell Barton |
36d03a |
break;
|
|
Campbell Barton |
36d03a |
case 16:
|
|
Campbell Barton |
36d03a |
wanted.format = AUDIO_S16;
|
|
Campbell Barton |
36d03a |
break;
|
|
Campbell Barton |
36d03a |
default:
|
|
Campbell Barton |
36d03a |
throw TSoundDeviceException(TSoundDeviceException::UnableOpenDevice,
|
|
Campbell Barton |
36d03a |
"invalid bits per sample");
|
|
Campbell Barton |
36d03a |
return false;
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
wanted.channels = format.m_channelCount; /* 1 = mono, 2 = stereo */
|
|
Campbell Barton |
36d03a |
wanted.samples = 1024; /* Good low-latency value for callback */
|
|
Campbell Barton |
36d03a |
wanted.callback = sdl_fill_audio;
|
|
Campbell Barton |
36d03a |
wanted.userdata = this;
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
/* Open the audio device, forcing the desired format */
|
|
Campbell Barton |
36d03a |
if (SDL_OpenAudio(&wanted, NULL) < 0) {
|
|
Campbell Barton |
36d03a |
std::string msg("Couldn't open audio: ");
|
|
Campbell Barton |
36d03a |
msg += SDL_GetError();
|
|
Campbell Barton |
36d03a |
throw TSoundDeviceException(TSoundDeviceException::UnableOpenDevice, msg);
|
|
Campbell Barton |
36d03a |
return false;
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
m_opened = true;
|
|
Campbell Barton |
36d03a |
return m_opened;
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//==============================================================================
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
TSoundOutputDevice::TSoundOutputDevice() : m_imp(new TSoundOutputDeviceImp) {
|
|
Campbell Barton |
36d03a |
#if 0
|
|
Campbell Barton |
36d03a |
try {
|
|
Campbell Barton |
36d03a |
supportsVolume();
|
|
Campbell Barton |
36d03a |
} catch (TSoundDeviceException &e) {
|
|
Campbell Barton |
36d03a |
throw TSoundDeviceException(e.getType(), e.getMessage());
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
#endif
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
TSoundOutputDevice::~TSoundOutputDevice() {
|
|
Campbell Barton |
36d03a |
stop();
|
|
Campbell Barton |
36d03a |
close();
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
bool TSoundOutputDevice::installed() { return true; }
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
bool TSoundOutputDevice::open(const TSoundTrackP &st) {
|
|
Campbell Barton |
36d03a |
if (!m_imp->doOpenDevice(st->getFormat()))
|
|
Campbell Barton |
36d03a |
throw TSoundDeviceException(
|
|
Campbell Barton |
36d03a |
TSoundDeviceException::UnableOpenDevice,
|
|
Campbell Barton |
36d03a |
"Problem to open the output device setting some params");
|
|
Campbell Barton |
36d03a |
return true;
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
bool TSoundOutputDevice::close() {
|
|
Campbell Barton |
36d03a |
stop();
|
|
Campbell Barton |
36d03a |
m_imp->m_opened = false;
|
|
Campbell Barton |
36d03a |
return true;
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
void TSoundOutputDevice::play(const TSoundTrackP &st, TINT32 s0, TINT32 s1,
|
|
Campbell Barton |
36d03a |
bool loop, bool scrubbing) {
|
|
Campbell Barton |
36d03a |
// TThread::ScopedLock sl(MutexOut);
|
|
Campbell Barton |
36d03a |
int lastSample = st->getSampleCount() - 1;
|
|
Campbell Barton |
36d03a |
notLessThan(0, s0);
|
|
Campbell Barton |
36d03a |
notLessThan(0, s1);
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
notMoreThan(lastSample, s0);
|
|
Campbell Barton |
36d03a |
notMoreThan(lastSample, s1);
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
if (s0 > s1) {
|
|
Campbell Barton |
36d03a |
#ifdef DEBUG
|
|
Campbell Barton |
36d03a |
cout << "s0 > s1; reorder" << endl;
|
|
Campbell Barton |
36d03a |
#endif
|
|
Campbell Barton |
36d03a |
swap(s0, s1);
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
if (isPlaying()) {
|
|
Campbell Barton |
36d03a |
#ifdef DEBUG
|
|
Campbell Barton |
36d03a |
cout << "is playing, stop it!" << endl;
|
|
Campbell Barton |
36d03a |
#endif
|
|
Campbell Barton |
36d03a |
stop();
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
m_imp->play(st, s0, s1, loop, scrubbing);
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
void TSoundOutputDeviceImp::play(const TSoundTrackP &st, TINT32 s0, TINT32 s1,
|
|
Campbell Barton |
36d03a |
bool loop, bool scrubbing) {
|
|
Campbell Barton |
36d03a |
if (!doOpenDevice(st->getFormat())) return;
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
MyData *myData = new MyData();
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
myData->imp = this;
|
|
Campbell Barton |
36d03a |
myData->totalPacketCount = s1 - s0;
|
|
Campbell Barton |
36d03a |
myData->fileByteCount = (s1 - s0) * st->getSampleSize();
|
|
Campbell Barton |
36d03a |
myData->entireFileBuffer = new char[myData->fileByteCount];
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
#if defined(i386)
|
|
Campbell Barton |
36d03a |
// XXX: let's see if that's needed for SDL
|
|
Campbell Barton |
36d03a |
if (st->getBitPerSample() == 16) {
|
|
Campbell Barton |
36d03a |
int i;
|
|
Campbell Barton |
36d03a |
USHORT *dst = (USHORT *)(myData->entireFileBuffer);
|
|
Campbell Barton |
36d03a |
USHORT *src = (USHORT *)(st->getRawData() + s0 * st->getSampleSize());
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
for (i = 0; i < myData->fileByteCount / 2; i++) *dst++ = swapUshort(*src++);
|
|
Campbell Barton |
36d03a |
} else
|
|
Campbell Barton |
36d03a |
memcpy(myData->entireFileBuffer,
|
|
Campbell Barton |
36d03a |
st->getRawData() + s0 * st->getSampleSize(), myData->fileByteCount);
|
|
Campbell Barton |
36d03a |
#else
|
|
Campbell Barton |
36d03a |
memcpy(myData->entireFileBuffer, st->getRawData() + s0 * st->getSampleSize(),
|
|
Campbell Barton |
36d03a |
myData->fileByteCount);
|
|
Campbell Barton |
36d03a |
#endif
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
// myData->maxPacketSize = fileASBD.mFramesPerPacket *
|
|
Shinya Kitaoka |
fd19c4 |
// fileASBD.mBytesPerFrame;
|
|
Campbell Barton |
36d03a |
{
|
|
Campbell Barton |
36d03a |
// TThread::ScopedLock sl(MutexOut);
|
|
Campbell Barton |
36d03a |
m_isPlaying = true;
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
myData->isLooping = loop;
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
// cout << "total packet count = " << myData->totalPacketCount <
|
|
Campbell Barton |
36d03a |
// cout << "filebytecount " << myData->fileByteCount << endl;
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
m_data = myData;
|
|
Campbell Barton |
36d03a |
SDL_PauseAudio(0);
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
bool TSoundOutputDeviceImp::doStopDevice() {
|
|
Campbell Barton |
36d03a |
SDL_PauseAudio(1);
|
|
Campbell Barton |
36d03a |
m_isPlaying = false;
|
|
Campbell Barton |
36d03a |
delete m_data;
|
|
Campbell Barton |
36d03a |
m_data = NULL;
|
|
Campbell Barton |
36d03a |
SDL_CloseAudio();
|
|
Campbell Barton |
36d03a |
m_opened = false;
|
|
Campbell Barton |
36d03a |
return true;
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
void TSoundOutputDevice::stop() {
|
|
Campbell Barton |
36d03a |
// TThread::ScopedLock sl(MutexOut);
|
|
Campbell Barton |
36d03a |
if (m_imp->m_opened == false) return;
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
// TThread::ScopedLock sl(MutexOut);
|
|
Campbell Barton |
36d03a |
m_imp->doStopDevice();
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
void TSoundOutputDevice::attach(TSoundOutputDeviceListener *listener) {
|
|
Campbell Barton |
36d03a |
m_imp->m_listeners.insert(listener);
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
void TSoundOutputDevice::detach(TSoundOutputDeviceListener *listener) {
|
|
Campbell Barton |
36d03a |
m_imp->m_listeners.erase(listener);
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
#if 0
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
double TSoundOutputDevice::getVolume()
|
|
Campbell Barton |
36d03a |
{
|
|
Campbell Barton |
36d03a |
if (!m_imp->m_opened)
|
|
Campbell Barton |
36d03a |
m_imp->doOpenDevice();
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
double vol = m_volume / SDL_MIX_MAXVOLUME;
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
return (vol < 0. ? 0. : vol);
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
bool TSoundOutputDevice::setVolume(double volume)
|
|
Campbell Barton |
36d03a |
{
|
|
Campbell Barton |
36d03a |
Float32 vol = volume;
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
m_imp->m_volume = (int)(volume * SDL_MIX_MAXVOLUME);
|
|
Campbell Barton |
36d03a |
return true;
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
bool TSoundOutputDevice::supportsVolume()
|
|
Campbell Barton |
36d03a |
{
|
|
Campbell Barton |
36d03a |
return true;
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
#endif
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
bool TSoundOutputDevice::isPlaying() const {
|
|
Campbell Barton |
36d03a |
// TThread::ScopedLock sl(MutexOut);
|
|
Campbell Barton |
36d03a |
// TODO: handle actually queuing items?
|
|
Campbell Barton |
36d03a |
return m_imp->m_isPlaying;
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
bool TSoundOutputDevice::isAllQueuedItemsPlayed() {
|
|
Campbell Barton |
36d03a |
// TThread::ScopedLock sl(MutexOut);
|
|
Campbell Barton |
36d03a |
return m_imp->m_data == NULL;
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
bool TSoundOutputDevice::isLooping() {
|
|
Campbell Barton |
36d03a |
// TThread::ScopedLock sl(MutexOut);
|
|
Campbell Barton |
36d03a |
return m_imp->m_looped;
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
void TSoundOutputDevice::setLooping(bool loop) {
|
|
Campbell Barton |
36d03a |
// TThread::ScopedLock sl(MutexOut);
|
|
Campbell Barton |
36d03a |
m_imp->m_looped = loop;
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
TSoundTrackFormat TSoundOutputDevice::getPreferredFormat(TUINT32 sampleRate,
|
|
Campbell Barton |
36d03a |
int channelCount,
|
|
Campbell Barton |
36d03a |
int bitPerSample) {
|
|
Campbell Barton |
36d03a |
if (bitPerSample > 16) bitPerSample = 16;
|
|
Campbell Barton |
36d03a |
// not sure SDL supports more than 2 channels
|
|
Campbell Barton |
36d03a |
if (channelCount > 2) channelCount = 2;
|
|
Campbell Barton |
36d03a |
TSoundTrackFormat fmt(sampleRate, bitPerSample, channelCount, true);
|
|
Campbell Barton |
36d03a |
return fmt;
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
TSoundTrackFormat TSoundOutputDevice::getPreferredFormat(
|
|
Campbell Barton |
36d03a |
const TSoundTrackFormat &format) {
|
|
Campbell Barton |
36d03a |
#if 0
|
|
Campbell Barton |
36d03a |
try {
|
|
Campbell Barton |
36d03a |
#endif
|
|
Campbell Barton |
36d03a |
return getPreferredFormat(format.m_sampleRate, format.m_channelCount,
|
|
Campbell Barton |
36d03a |
format.m_bitPerSample);
|
|
Campbell Barton |
36d03a |
#if 0
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
catch (TSoundDeviceException &e) {
|
|
Campbell Barton |
36d03a |
throw TSoundDeviceException( e.getType(), e.getMessage());
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
#endif
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//==============================================================================
|
|
Campbell Barton |
36d03a |
//==============================================================================
|
|
Campbell Barton |
36d03a |
// REGISTRAZIONE
|
|
Campbell Barton |
36d03a |
//==============================================================================
|
|
Campbell Barton |
36d03a |
//==============================================================================
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
class TSoundInputDeviceImp {
|
|
Campbell Barton |
36d03a |
public:
|
|
Campbell Barton |
36d03a |
// ALport m_port;
|
|
Campbell Barton |
36d03a |
bool m_stopped;
|
|
Campbell Barton |
36d03a |
bool m_isRecording;
|
|
Campbell Barton |
36d03a |
bool m_oneShotRecording;
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
long m_recordedSampleCount;
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
TSoundTrackFormat m_currentFormat;
|
|
Campbell Barton |
36d03a |
TSoundTrackP m_st;
|
|
Campbell Barton |
36d03a |
std::set<int> m_supportedRate;</int>
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
TThread::Executor m_executor;
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
TSoundInputDeviceImp()
|
|
Campbell Barton |
36d03a |
: m_stopped(false)
|
|
Campbell Barton |
36d03a |
, m_isRecording(false)
|
|
Campbell Barton |
36d03a |
// , m_port(NULL)
|
|
Campbell Barton |
36d03a |
, m_oneShotRecording(false)
|
|
Campbell Barton |
36d03a |
, m_recordedSampleCount(0)
|
|
Campbell Barton |
36d03a |
, m_st(0)
|
|
Campbell Barton |
36d03a |
, m_supportedRate(){};
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
~TSoundInputDeviceImp(){};
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
bool doOpenDevice(const TSoundTrackFormat &format,
|
|
Campbell Barton |
36d03a |
TSoundInputDevice::Source devType);
|
|
Campbell Barton |
36d03a |
};
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
bool TSoundInputDeviceImp::doOpenDevice(const TSoundTrackFormat &format,
|
|
Campbell Barton |
36d03a |
TSoundInputDevice::Source devType) {
|
|
Campbell Barton |
36d03a |
return true;
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//==============================================================================
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
class RecordTask : public TThread::Runnable {
|
|
Campbell Barton |
36d03a |
public:
|
|
Campbell Barton |
36d03a |
TSoundInputDeviceImp *m_devImp;
|
|
Campbell Barton |
36d03a |
int m_ByteToSample;
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
RecordTask(TSoundInputDeviceImp *devImp, int numByte)
|
|
Campbell Barton |
36d03a |
: TThread::Runnable(), m_devImp(devImp), m_ByteToSample(numByte){};
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
~RecordTask(){};
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
void run();
|
|
Campbell Barton |
36d03a |
};
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
void RecordTask::run() {}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//==============================================================================
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
TSoundInputDevice::TSoundInputDevice() : m_imp(new TSoundInputDeviceImp) {}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
TSoundInputDevice::~TSoundInputDevice() {
|
|
Campbell Barton |
36d03a |
#if 0
|
|
Campbell Barton |
36d03a |
if(m_imp->m_port)
|
|
Campbell Barton |
36d03a |
alClosePort(m_imp->m_port);
|
|
Campbell Barton |
36d03a |
delete m_imp;
|
|
Campbell Barton |
36d03a |
#endif
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
bool TSoundInputDevice::installed() {
|
|
Campbell Barton |
36d03a |
#if 0
|
|
Campbell Barton |
36d03a |
if (alQueryValues(AL_SYSTEM, AL_DEFAULT_INPUT, 0, 0, 0, 0) <= 0)
|
|
Campbell Barton |
36d03a |
return false;
|
|
Campbell Barton |
36d03a |
#endif
|
|
Campbell Barton |
36d03a |
return true;
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
void TSoundInputDevice::record(const TSoundTrackFormat &format,
|
|
Campbell Barton |
36d03a |
TSoundInputDevice::Source type) {}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
void TSoundInputDevice::record(const TSoundTrackP &st,
|
|
Campbell Barton |
36d03a |
TSoundInputDevice::Source type) {}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
TSoundTrackP TSoundInputDevice::stop() {
|
|
Campbell Barton |
36d03a |
TSoundTrackP st;
|
|
Campbell Barton |
36d03a |
return st;
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
double TSoundInputDevice::getVolume() { return 0.0; }
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
bool TSoundInputDevice::setVolume(double volume) { return true; }
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
bool TSoundInputDevice::supportsVolume() { return true; }
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
TSoundTrackFormat TSoundInputDevice::getPreferredFormat(TUINT32 sampleRate,
|
|
Campbell Barton |
36d03a |
int channelCount,
|
|
Campbell Barton |
36d03a |
int bitPerSample) {
|
|
Campbell Barton |
36d03a |
TSoundTrackFormat fmt;
|
|
Campbell Barton |
36d03a |
return fmt;
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
TSoundTrackFormat TSoundInputDevice::getPreferredFormat(
|
|
Campbell Barton |
36d03a |
const TSoundTrackFormat &format) {
|
|
Campbell Barton |
36d03a |
#if 0
|
|
Campbell Barton |
36d03a |
try {
|
|
Campbell Barton |
36d03a |
#endif
|
|
Campbell Barton |
36d03a |
return getPreferredFormat(format.m_sampleRate, format.m_channelCount,
|
|
Campbell Barton |
36d03a |
format.m_bitPerSample);
|
|
Campbell Barton |
36d03a |
#if 0
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
catch (TSoundDeviceException &e) {
|
|
Campbell Barton |
36d03a |
throw TSoundDeviceException( e.getType(), e.getMessage());
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
#endif
|
|
Campbell Barton |
36d03a |
}
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
//------------------------------------------------------------------------------
|
|
Campbell Barton |
36d03a |
|
|
Campbell Barton |
36d03a |
bool TSoundInputDevice::isRecording() { return m_imp->m_isRecording; }
|