Linux support for tsound (SDL2), from pr #51
Credit goes to François Revol for this work.
This commit is contained in:
parent
deffae3359
commit
36d03a96ea
2 changed files with 696 additions and 12 deletions
563
toonz/sources/common/tsound/tsound_sdl.cpp
Normal file
563
toonz/sources/common/tsound/tsound_sdl.cpp
Normal file
|
@ -0,0 +1,563 @@
|
|||
|
||||
#include "tsound_t.h"
|
||||
#include "texception.h"
|
||||
#include "tthread.h"
|
||||
#include "tthreadmessage.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
using namespace std;
|
||||
|
||||
//==============================================================================
|
||||
namespace {
|
||||
TThread::Mutex MutexOut;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
struct MyData {
|
||||
char *entireFileBuffer;
|
||||
|
||||
int totalPacketCount;
|
||||
int fileByteCount;
|
||||
// UInt32 maxPacketSize;
|
||||
// UInt64 packetOffset;
|
||||
int byteOffset;
|
||||
bool m_doNotify;
|
||||
|
||||
void *sourceBuffer;
|
||||
// AudioConverterRef converter;
|
||||
TSoundOutputDeviceImp *imp;
|
||||
bool isLooping;
|
||||
MyData()
|
||||
: entireFileBuffer(0)
|
||||
, totalPacketCount(0)
|
||||
, fileByteCount(0)
|
||||
, /*maxPacketSize(0), packetOffset(0),*/ byteOffset(0)
|
||||
, sourceBuffer(0)
|
||||
, isLooping(false)
|
||||
, imp(0)
|
||||
, m_doNotify(true) {}
|
||||
};
|
||||
}
|
||||
|
||||
class TSoundOutputDeviceImp {
|
||||
public:
|
||||
bool m_isPlaying;
|
||||
bool m_looped;
|
||||
TSoundTrackFormat m_currentFormat;
|
||||
std::set<int> m_supportedRate;
|
||||
bool m_opened;
|
||||
struct MyData *m_data;
|
||||
int m_volume;
|
||||
|
||||
TSoundOutputDeviceImp()
|
||||
: m_isPlaying(false)
|
||||
, m_looped(false)
|
||||
, m_supportedRate()
|
||||
, m_opened(false)
|
||||
, m_data(NULL)
|
||||
, m_volume(SDL_MIX_MAXVOLUME){};
|
||||
|
||||
std::set<TSoundOutputDeviceListener *> m_listeners;
|
||||
|
||||
~TSoundOutputDeviceImp(){};
|
||||
|
||||
bool doOpenDevice(const TSoundTrackFormat &format);
|
||||
bool doStopDevice();
|
||||
void play(const TSoundTrackP &st, TINT32 s0, TINT32 s1, bool loop,
|
||||
bool scrubbing);
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace {
|
||||
|
||||
class PlayCompletedMsg : public TThread::Message {
|
||||
std::set<TSoundOutputDeviceListener *> m_listeners;
|
||||
MyData *m_data;
|
||||
|
||||
public:
|
||||
PlayCompletedMsg(MyData *data) : m_data(data) {}
|
||||
|
||||
TThread::Message *clone() const { return new PlayCompletedMsg(*this); }
|
||||
|
||||
void onDeliver() {
|
||||
if (m_data->imp) {
|
||||
if (m_data->m_doNotify == false) return;
|
||||
m_data->m_doNotify = false;
|
||||
if (m_data->imp->m_isPlaying) m_data->imp->doStopDevice();
|
||||
std::set<TSoundOutputDeviceListener *>::iterator it =
|
||||
m_data->imp->m_listeners.begin();
|
||||
for (; it != m_data->imp->m_listeners.end(); ++it)
|
||||
(*it)->onPlayCompleted();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#define checkStatus(err) \
|
||||
if (err) { \
|
||||
printf("Error: 0x%x -> %s: %d\n", (int)err, __FILE__, __LINE__); \
|
||||
fflush(stdout); \
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
void sdl_fill_audio(void *udata, Uint8 *stream, int len) {
|
||||
TSoundOutputDeviceImp *_this = (TSoundOutputDeviceImp *)udata;
|
||||
MyData *myData = _this->m_data;
|
||||
|
||||
/* Only play if we have data left */
|
||||
if (myData == NULL) return;
|
||||
{
|
||||
// TThread::ScopedLock sl(MutexOut);
|
||||
if (myData->imp->m_isPlaying == false) return;
|
||||
}
|
||||
|
||||
int audio_len = myData->fileByteCount - myData->byteOffset;
|
||||
if (audio_len <= 0) {
|
||||
delete[] myData->entireFileBuffer;
|
||||
myData->entireFileBuffer = 0;
|
||||
#if 0
|
||||
{
|
||||
TThread::ScopedLock sl(MutexOut);
|
||||
*(myData->isPlaying) = false; //questo lo faccio nel main thread
|
||||
}
|
||||
#endif
|
||||
PlayCompletedMsg(myData).send();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Mix as much data as possible */
|
||||
len = (len > audio_len ? audio_len : len);
|
||||
SDL_MixAudio(stream, (Uint8 *)myData->entireFileBuffer + myData->byteOffset,
|
||||
len, _this->m_volume);
|
||||
myData->byteOffset += len;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
bool TSoundOutputDeviceImp::doOpenDevice(const TSoundTrackFormat &format) {
|
||||
SDL_AudioSpec wanted;
|
||||
|
||||
static bool first = true; // TODO: should be shared with InputDevice
|
||||
if (first) {
|
||||
SDL_Init(SDL_INIT_AUDIO);
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (m_opened) {
|
||||
SDL_CloseAudio();
|
||||
// we'll just reopen right away
|
||||
}
|
||||
|
||||
wanted.freq = format.m_sampleRate;
|
||||
switch (format.m_bitPerSample) {
|
||||
case 8:
|
||||
wanted.format = AUDIO_S8;
|
||||
break;
|
||||
case 16:
|
||||
wanted.format = AUDIO_S16;
|
||||
break;
|
||||
default:
|
||||
throw TSoundDeviceException(TSoundDeviceException::UnableOpenDevice,
|
||||
"invalid bits per sample");
|
||||
return false;
|
||||
}
|
||||
wanted.channels = format.m_channelCount; /* 1 = mono, 2 = stereo */
|
||||
wanted.samples = 1024; /* Good low-latency value for callback */
|
||||
wanted.callback = sdl_fill_audio;
|
||||
wanted.userdata = this;
|
||||
|
||||
/* Open the audio device, forcing the desired format */
|
||||
if (SDL_OpenAudio(&wanted, NULL) < 0) {
|
||||
std::string msg("Couldn't open audio: ");
|
||||
msg += SDL_GetError();
|
||||
throw TSoundDeviceException(TSoundDeviceException::UnableOpenDevice, msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_opened = true;
|
||||
return m_opened;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
TSoundOutputDevice::TSoundOutputDevice() : m_imp(new TSoundOutputDeviceImp) {
|
||||
#if 0
|
||||
try {
|
||||
supportsVolume();
|
||||
} catch (TSoundDeviceException &e) {
|
||||
throw TSoundDeviceException(e.getType(), e.getMessage());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
TSoundOutputDevice::~TSoundOutputDevice() {
|
||||
stop();
|
||||
close();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool TSoundOutputDevice::installed() { return true; }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool TSoundOutputDevice::open(const TSoundTrackP &st) {
|
||||
if (!m_imp->doOpenDevice(st->getFormat()))
|
||||
throw TSoundDeviceException(
|
||||
TSoundDeviceException::UnableOpenDevice,
|
||||
"Problem to open the output device setting some params");
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool TSoundOutputDevice::close() {
|
||||
stop();
|
||||
m_imp->m_opened = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void TSoundOutputDevice::play(const TSoundTrackP &st, TINT32 s0, TINT32 s1,
|
||||
bool loop, bool scrubbing) {
|
||||
// TThread::ScopedLock sl(MutexOut);
|
||||
int lastSample = st->getSampleCount() - 1;
|
||||
notLessThan(0, s0);
|
||||
notLessThan(0, s1);
|
||||
|
||||
notMoreThan(lastSample, s0);
|
||||
notMoreThan(lastSample, s1);
|
||||
|
||||
if (s0 > s1) {
|
||||
#ifdef DEBUG
|
||||
cout << "s0 > s1; reorder" << endl;
|
||||
#endif
|
||||
swap(s0, s1);
|
||||
}
|
||||
|
||||
if (isPlaying()) {
|
||||
#ifdef DEBUG
|
||||
cout << "is playing, stop it!" << endl;
|
||||
#endif
|
||||
stop();
|
||||
}
|
||||
m_imp->play(st, s0, s1, loop, scrubbing);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void TSoundOutputDeviceImp::play(const TSoundTrackP &st, TINT32 s0, TINT32 s1,
|
||||
bool loop, bool scrubbing) {
|
||||
if (!doOpenDevice(st->getFormat())) return;
|
||||
|
||||
MyData *myData = new MyData();
|
||||
|
||||
myData->imp = this;
|
||||
myData->totalPacketCount = s1 - s0;
|
||||
myData->fileByteCount = (s1 - s0) * st->getSampleSize();
|
||||
myData->entireFileBuffer = new char[myData->fileByteCount];
|
||||
|
||||
#if defined(i386)
|
||||
// XXX: let's see if that's needed for SDL
|
||||
if (st->getBitPerSample() == 16) {
|
||||
int i;
|
||||
USHORT *dst = (USHORT *)(myData->entireFileBuffer);
|
||||
USHORT *src = (USHORT *)(st->getRawData() + s0 * st->getSampleSize());
|
||||
|
||||
for (i = 0; i < myData->fileByteCount / 2; i++) *dst++ = swapUshort(*src++);
|
||||
} else
|
||||
memcpy(myData->entireFileBuffer,
|
||||
st->getRawData() + s0 * st->getSampleSize(), myData->fileByteCount);
|
||||
#else
|
||||
memcpy(myData->entireFileBuffer, st->getRawData() + s0 * st->getSampleSize(),
|
||||
myData->fileByteCount);
|
||||
#endif
|
||||
|
||||
// myData->maxPacketSize = fileASBD.mFramesPerPacket *
|
||||
//fileASBD.mBytesPerFrame;
|
||||
{
|
||||
// TThread::ScopedLock sl(MutexOut);
|
||||
m_isPlaying = true;
|
||||
}
|
||||
myData->isLooping = loop;
|
||||
|
||||
// cout << "total packet count = " << myData->totalPacketCount <<endl;
|
||||
// cout << "filebytecount " << myData->fileByteCount << endl;
|
||||
|
||||
m_data = myData;
|
||||
SDL_PauseAudio(0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool TSoundOutputDeviceImp::doStopDevice() {
|
||||
SDL_PauseAudio(1);
|
||||
m_isPlaying = false;
|
||||
delete m_data;
|
||||
m_data = NULL;
|
||||
SDL_CloseAudio();
|
||||
m_opened = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void TSoundOutputDevice::stop() {
|
||||
// TThread::ScopedLock sl(MutexOut);
|
||||
if (m_imp->m_opened == false) return;
|
||||
|
||||
// TThread::ScopedLock sl(MutexOut);
|
||||
m_imp->doStopDevice();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void TSoundOutputDevice::attach(TSoundOutputDeviceListener *listener) {
|
||||
m_imp->m_listeners.insert(listener);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void TSoundOutputDevice::detach(TSoundOutputDeviceListener *listener) {
|
||||
m_imp->m_listeners.erase(listener);
|
||||
}
|
||||
|
||||
#if 0
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
double TSoundOutputDevice::getVolume()
|
||||
{
|
||||
if (!m_imp->m_opened)
|
||||
m_imp->doOpenDevice();
|
||||
|
||||
double vol = m_volume / SDL_MIX_MAXVOLUME;
|
||||
|
||||
return (vol < 0. ? 0. : vol);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool TSoundOutputDevice::setVolume(double volume)
|
||||
{
|
||||
Float32 vol = volume;
|
||||
|
||||
m_imp->m_volume = (int)(volume * SDL_MIX_MAXVOLUME);
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool TSoundOutputDevice::supportsVolume()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool TSoundOutputDevice::isPlaying() const {
|
||||
// TThread::ScopedLock sl(MutexOut);
|
||||
// TODO: handle actually queuing items?
|
||||
return m_imp->m_isPlaying;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool TSoundOutputDevice::isAllQueuedItemsPlayed() {
|
||||
// TThread::ScopedLock sl(MutexOut);
|
||||
return m_imp->m_data == NULL;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool TSoundOutputDevice::isLooping() {
|
||||
// TThread::ScopedLock sl(MutexOut);
|
||||
return m_imp->m_looped;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void TSoundOutputDevice::setLooping(bool loop) {
|
||||
// TThread::ScopedLock sl(MutexOut);
|
||||
m_imp->m_looped = loop;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
TSoundTrackFormat TSoundOutputDevice::getPreferredFormat(TUINT32 sampleRate,
|
||||
int channelCount,
|
||||
int bitPerSample) {
|
||||
if (bitPerSample > 16) bitPerSample = 16;
|
||||
// not sure SDL supports more than 2 channels
|
||||
if (channelCount > 2) channelCount = 2;
|
||||
TSoundTrackFormat fmt(sampleRate, bitPerSample, channelCount, true);
|
||||
return fmt;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
TSoundTrackFormat TSoundOutputDevice::getPreferredFormat(
|
||||
const TSoundTrackFormat &format) {
|
||||
#if 0
|
||||
try {
|
||||
#endif
|
||||
return getPreferredFormat(format.m_sampleRate, format.m_channelCount,
|
||||
format.m_bitPerSample);
|
||||
#if 0
|
||||
}
|
||||
catch (TSoundDeviceException &e) {
|
||||
throw TSoundDeviceException( e.getType(), e.getMessage());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
//==============================================================================
|
||||
// REGISTRAZIONE
|
||||
//==============================================================================
|
||||
//==============================================================================
|
||||
|
||||
class TSoundInputDeviceImp {
|
||||
public:
|
||||
// ALport m_port;
|
||||
bool m_stopped;
|
||||
bool m_isRecording;
|
||||
bool m_oneShotRecording;
|
||||
|
||||
long m_recordedSampleCount;
|
||||
|
||||
TSoundTrackFormat m_currentFormat;
|
||||
TSoundTrackP m_st;
|
||||
std::set<int> m_supportedRate;
|
||||
|
||||
TThread::Executor m_executor;
|
||||
|
||||
TSoundInputDeviceImp()
|
||||
: m_stopped(false)
|
||||
, m_isRecording(false)
|
||||
// , m_port(NULL)
|
||||
, m_oneShotRecording(false)
|
||||
, m_recordedSampleCount(0)
|
||||
, m_st(0)
|
||||
, m_supportedRate(){};
|
||||
|
||||
~TSoundInputDeviceImp(){};
|
||||
|
||||
bool doOpenDevice(const TSoundTrackFormat &format,
|
||||
TSoundInputDevice::Source devType);
|
||||
};
|
||||
|
||||
bool TSoundInputDeviceImp::doOpenDevice(const TSoundTrackFormat &format,
|
||||
TSoundInputDevice::Source devType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
class RecordTask : public TThread::Runnable {
|
||||
public:
|
||||
TSoundInputDeviceImp *m_devImp;
|
||||
int m_ByteToSample;
|
||||
|
||||
RecordTask(TSoundInputDeviceImp *devImp, int numByte)
|
||||
: TThread::Runnable(), m_devImp(devImp), m_ByteToSample(numByte){};
|
||||
|
||||
~RecordTask(){};
|
||||
|
||||
void run();
|
||||
};
|
||||
|
||||
void RecordTask::run() {}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
TSoundInputDevice::TSoundInputDevice() : m_imp(new TSoundInputDeviceImp) {}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
TSoundInputDevice::~TSoundInputDevice() {
|
||||
#if 0
|
||||
if(m_imp->m_port)
|
||||
alClosePort(m_imp->m_port);
|
||||
delete m_imp;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool TSoundInputDevice::installed() {
|
||||
#if 0
|
||||
if (alQueryValues(AL_SYSTEM, AL_DEFAULT_INPUT, 0, 0, 0, 0) <= 0)
|
||||
return false;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void TSoundInputDevice::record(const TSoundTrackFormat &format,
|
||||
TSoundInputDevice::Source type) {}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void TSoundInputDevice::record(const TSoundTrackP &st,
|
||||
TSoundInputDevice::Source type) {}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
TSoundTrackP TSoundInputDevice::stop() {
|
||||
TSoundTrackP st;
|
||||
return st;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
double TSoundInputDevice::getVolume() { return 0.0; }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool TSoundInputDevice::setVolume(double volume) { return true; }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool TSoundInputDevice::supportsVolume() { return true; }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
TSoundTrackFormat TSoundInputDevice::getPreferredFormat(TUINT32 sampleRate,
|
||||
int channelCount,
|
||||
int bitPerSample) {
|
||||
TSoundTrackFormat fmt;
|
||||
return fmt;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
TSoundTrackFormat TSoundInputDevice::getPreferredFormat(
|
||||
const TSoundTrackFormat &format) {
|
||||
#if 0
|
||||
try {
|
||||
#endif
|
||||
return getPreferredFormat(format.m_sampleRate, format.m_channelCount,
|
||||
format.m_bitPerSample);
|
||||
#if 0
|
||||
}
|
||||
catch (TSoundDeviceException &e) {
|
||||
throw TSoundDeviceException( e.getType(), e.getMessage());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool TSoundInputDevice::isRecording() { return m_imp->m_isRecording; }
|
|
@ -5,11 +5,22 @@
|
|||
#include "tthread.h"
|
||||
|
||||
#include <errno.h>
|
||||
#ifdef __sgi
|
||||
#include <audio.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
|
||||
#ifndef __sgi
|
||||
// Warning, this file is for SGI currently,
|
||||
// otherwise we just stub out the functions.
|
||||
typedef unsigned long ULONG;
|
||||
typedef void *ALport;
|
||||
typedef void *ALvalue;
|
||||
typedef void *ALpv;
|
||||
#endif
|
||||
|
||||
// forward declaration
|
||||
namespace {
|
||||
bool isInterfaceSupported(int deviceType, int interfaceType);
|
||||
|
@ -47,9 +58,47 @@ public:
|
|||
bool verifyRate();
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
if (!isInterfaceSupported(AL_DEFAULT_OUTPUT, AL_SPEAKER_IF_TYPE))
|
||||
return false; // throw TException("Speakers are not supported");
|
||||
|
||||
int dev = alGetResourceByName(AL_SYSTEM, (char *)"Headphone/Speaker",
|
||||
AL_DEVICE_TYPE);
|
||||
if (!dev) return false; // throw TException("invalid device speakers");
|
||||
|
||||
pvbuf[0].param = AL_DEFAULT_OUTPUT;
|
||||
pvbuf[0].value.i = dev;
|
||||
alSetParams(AL_SYSTEM, pvbuf, 1);
|
||||
|
||||
ALfixed buf[2] = {alDoubleToFixed(0), alDoubleToFixed(0)};
|
||||
|
||||
config = alNewConfig();
|
||||
// qui devo metterci gli altoparlanti e poi setto i valori per il default
|
||||
// output
|
||||
pvbuf[0].param = AL_RATE;
|
||||
pvbuf[0].value.ll = alDoubleToFixed((double)format.m_sampleRate);
|
||||
pvbuf[1].param = AL_GAIN;
|
||||
pvbuf[1].value.ptr = buf;
|
||||
pvbuf[1].sizeIn = 8;
|
||||
pvbuf[2].param = AL_INTERFACE;
|
||||
pvbuf[2].value.i = AL_SPEAKER_IF_TYPE;
|
||||
|
||||
if (alSetParams(AL_DEFAULT_OUTPUT, pvbuf, 3) < 0) return false;
|
||||
// throw TException("Unable to set params for output device");
|
||||
|
||||
if (alSetChannels(config, format.m_channelCount) == -1)
|
||||
return false; // throw TException("Error to setting audio hardware.");
|
||||
|
||||
int bytePerSample = format.m_bitPerSample >> 3;
|
||||
switch (bytePerSample) {
|
||||
case 3:
|
||||
bytePerSample++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
bool TSoundOutputDeviceImp::doOpenDevice(const TSoundTrackFormat &format) {
|
||||
#ifdef __sgi
|
||||
ALconfig config;
|
||||
ALpv pvbuf[3];
|
||||
|
||||
|
@ -115,6 +164,9 @@ bool TSoundOutputDeviceImp::doOpenDevice(const TSoundTrackFormat &format) {
|
|||
|
||||
alFreeConfig(config);
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -132,6 +184,7 @@ void TSoundOutputDeviceImp::insertAllRate() {
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool TSoundOutputDeviceImp::verifyRate() {
|
||||
#ifdef __sgi
|
||||
// Sample Rate
|
||||
ALparamInfo pinfo;
|
||||
int ret = alGetParamInfo(AL_DEFAULT_OUTPUT, AL_RATE, &pinfo);
|
||||
|
@ -147,6 +200,7 @@ bool TSoundOutputDeviceImp::verifyRate() {
|
|||
return false;
|
||||
else
|
||||
return false;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -166,6 +220,7 @@ public:
|
|||
};
|
||||
|
||||
void PlayTask::run() {
|
||||
#ifdef __sgi
|
||||
int leftToPlay = m_sndtrack->getSampleCount();
|
||||
int i = 0;
|
||||
|
||||
|
@ -211,11 +266,13 @@ void PlayTask::run() {
|
|||
while (!m_devImp->m_queuedSoundTracks.empty())
|
||||
m_devImp->m_queuedSoundTracks.pop();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
TSoundOutputDevice::TSoundOutputDevice() : m_imp(new TSoundOutputDeviceImp) {
|
||||
#ifdef __sgi
|
||||
if (!setDefaultOutput())
|
||||
throw TSoundDeviceException(TSoundDeviceException::UnableSetDevice,
|
||||
"Speaker not supported");
|
||||
|
@ -225,6 +282,7 @@ TSoundOutputDevice::TSoundOutputDevice() : m_imp(new TSoundOutputDeviceImp) {
|
|||
throw TSoundDeviceException(e.getType(), e.getMessage());
|
||||
}
|
||||
m_imp->insertAllRate();
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -237,8 +295,10 @@ TSoundOutputDevice::~TSoundOutputDevice() {
|
|||
//------------------------------------------------------------------------------
|
||||
|
||||
bool TSoundOutputDevice::installed() {
|
||||
#ifdef __sgi
|
||||
if (alQueryValues(AL_SYSTEM, AL_DEFAULT_OUTPUT, 0, 0, 0, 0) <= 0)
|
||||
return false;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -255,10 +315,11 @@ bool TSoundOutputDevice::open(const TSoundTrackP &st) {
|
|||
//------------------------------------------------------------------------------
|
||||
|
||||
bool TSoundOutputDevice::close() {
|
||||
#ifdef __sgi
|
||||
stop();
|
||||
if (m_imp->m_port) alClosePort(m_imp->m_port);
|
||||
m_imp->m_port = NULL;
|
||||
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -266,6 +327,7 @@ bool TSoundOutputDevice::close() {
|
|||
|
||||
void TSoundOutputDevice::play(const TSoundTrackP &st, TINT32 s0, TINT32 s1,
|
||||
bool loop, bool scrubbing) {
|
||||
#ifdef __sgi
|
||||
if (!st->getSampleCount()) return;
|
||||
|
||||
{
|
||||
|
@ -302,22 +364,27 @@ void TSoundOutputDevice::play(const TSoundTrackP &st, TINT32 s0, TINT32 s1,
|
|||
m_imp->m_executor.addTask(new PlayTask(m_imp, subTrack));
|
||||
} else
|
||||
m_imp->m_queuedSoundTracks.push(subTrack);
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void TSoundOutputDevice::stop() {
|
||||
#ifdef __sgi
|
||||
if (!m_imp->m_isPlaying) return;
|
||||
|
||||
TThread::ScopedLock sl(m_imp->m_mutex);
|
||||
m_imp->m_isPlaying = false;
|
||||
m_imp->m_stopped = true;
|
||||
m_imp->m_looped = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if 0
|
||||
double TSoundOutputDevice::getVolume() {
|
||||
#ifdef __sgi
|
||||
ALpv pv[1];
|
||||
ALfixed value[2];
|
||||
|
||||
|
@ -336,10 +403,15 @@ double TSoundOutputDevice::getVolume() {
|
|||
(((alFixedToDouble(value[0]) + alFixedToDouble(value[1])) / 2.) + 60.) /
|
||||
8.05;
|
||||
return val;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if 0
|
||||
bool TSoundOutputDevice::setVolume(double volume) {
|
||||
ALpv pv[1];
|
||||
ALfixed value[2];
|
||||
|
@ -360,10 +432,14 @@ bool TSoundOutputDevice::setVolume(double volume) {
|
|||
if (alSetParams(AL_DEFAULT_OUTPUT, pv, 1) < 0) return false;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool TSoundOutputDevice::supportsVolume() {
|
||||
#if 0
|
||||
bool TSoundOutputDevice::supportsVolume()
|
||||
{
|
||||
#ifdef __sgi
|
||||
ALparamInfo pinfo;
|
||||
int ret;
|
||||
ret = alGetParamInfo(AL_DEFAULT_OUTPUT, AL_GAIN, &pinfo);
|
||||
|
@ -377,7 +453,11 @@ bool TSoundOutputDevice::supportsVolume() {
|
|||
else
|
||||
throw TSoundDeviceException(TSoundDeviceException::NoMixer,
|
||||
"Output device is not accessible");
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
@ -386,23 +466,30 @@ bool TSoundOutputDevice::isPlaying() const { return m_imp->m_isPlaying; }
|
|||
//------------------------------------------------------------------------------
|
||||
|
||||
bool TSoundOutputDevice::isLooping() {
|
||||
#ifdef __sgi
|
||||
TThread::ScopedLock sl(m_imp->m_mutex);
|
||||
return m_imp->m_looped;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void TSoundOutputDevice::setLooping(bool loop) {
|
||||
#ifdef __sgi
|
||||
TThread::ScopedLock sl(m_imp->m_mutex);
|
||||
m_imp->m_looped = loop;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
TSoundTrackFormat TSoundOutputDevice::getPreferredFormat(ULONG sampleRate,
|
||||
TSoundTrackFormat TSoundOutputDevice::getPreferredFormat(TUINT32 sampleRate,
|
||||
int channelCount,
|
||||
int bitPerSample) {
|
||||
TSoundTrackFormat fmt;
|
||||
#ifdef __sgi
|
||||
int ret;
|
||||
|
||||
if (!m_imp->verifyRate())
|
||||
|
@ -455,6 +542,7 @@ TSoundTrackFormat TSoundOutputDevice::getPreferredFormat(ULONG sampleRate,
|
|||
fmt.m_channelCount = channelCount;
|
||||
fmt.m_sampleRate = sampleRate;
|
||||
fmt.m_signedSample = true;
|
||||
#endif
|
||||
|
||||
return fmt;
|
||||
}
|
||||
|
@ -515,6 +603,7 @@ public:
|
|||
|
||||
bool TSoundInputDeviceImp::doOpenDevice(const TSoundTrackFormat &format,
|
||||
TSoundInputDevice::Source devType) {
|
||||
#ifdef __sgi
|
||||
ALconfig config;
|
||||
ALpv pvbuf[2];
|
||||
|
||||
|
@ -570,6 +659,7 @@ bool TSoundInputDeviceImp::doOpenDevice(const TSoundTrackFormat &format,
|
|||
if (!m_port) return false; // throw TException("Could not open audio port.");
|
||||
|
||||
alFreeConfig(config);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -588,6 +678,7 @@ void TSoundInputDeviceImp::insertAllRate() {
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool TSoundInputDeviceImp::verifyRate() {
|
||||
#ifdef __sgi
|
||||
// Sample Rate
|
||||
ALparamInfo pinfo;
|
||||
int ret = alGetParamInfo(AL_DEFAULT_INPUT, AL_RATE, &pinfo);
|
||||
|
@ -603,6 +694,7 @@ bool TSoundInputDeviceImp::verifyRate() {
|
|||
return false;
|
||||
else
|
||||
return false;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -622,6 +714,7 @@ public:
|
|||
};
|
||||
|
||||
void RecordTask::run() {
|
||||
#ifdef __sgi
|
||||
TINT32 byteRecordedSample = 0;
|
||||
int filled = alGetFilled(m_devImp->m_port);
|
||||
|
||||
|
@ -665,6 +758,7 @@ void RecordTask::run() {
|
|||
alClosePort(m_devImp->m_port);
|
||||
m_devImp->m_port = 0;
|
||||
m_devImp->m_stopped = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
@ -674,14 +768,18 @@ TSoundInputDevice::TSoundInputDevice() : m_imp(new TSoundInputDeviceImp) {}
|
|||
//------------------------------------------------------------------------------
|
||||
|
||||
TSoundInputDevice::~TSoundInputDevice() {
|
||||
#ifdef __sgi
|
||||
if (m_imp->m_port) alClosePort(m_imp->m_port);
|
||||
#endif
|
||||
delete m_imp;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool TSoundInputDevice::installed() {
|
||||
#ifdef __sgi
|
||||
if (alQueryValues(AL_SYSTEM, AL_DEFAULT_INPUT, 0, 0, 0, 0) <= 0) return false;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -812,7 +910,7 @@ recordThread->start();*/
|
|||
|
||||
TSoundTrackP TSoundInputDevice::stop() {
|
||||
TSoundTrackP st;
|
||||
|
||||
#ifdef __sgi
|
||||
if (!m_imp->m_isRecording)
|
||||
throw TSoundDeviceException(TSoundDeviceException::UnablePrepare,
|
||||
"No recording process is in execution");
|
||||
|
@ -840,12 +938,14 @@ TSoundTrackP TSoundInputDevice::stop() {
|
|||
}
|
||||
m_imp->m_samplePerBlocks.clear();
|
||||
}
|
||||
#endif
|
||||
return st;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
double TSoundInputDevice::getVolume() {
|
||||
#ifdef __sgi
|
||||
ALpv pv[1];
|
||||
ALfixed value[2];
|
||||
|
||||
|
@ -864,11 +964,15 @@ double TSoundInputDevice::getVolume() {
|
|||
(((alFixedToDouble(value[0]) + alFixedToDouble(value[1])) / 2.) + 60.) /
|
||||
8.05;
|
||||
return val;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool TSoundInputDevice::setVolume(double volume) {
|
||||
#ifdef __sgi
|
||||
ALpv pv[1];
|
||||
ALfixed value[2];
|
||||
|
||||
|
@ -886,13 +990,14 @@ bool TSoundInputDevice::setVolume(double volume) {
|
|||
pv[0].value.ptr = value;
|
||||
pv[0].sizeIn = 8;
|
||||
alSetParams(AL_DEFAULT_INPUT, pv, 1);
|
||||
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool TSoundInputDevice::supportsVolume() {
|
||||
#ifdef __sgi
|
||||
ALparamInfo pinfo;
|
||||
int ret;
|
||||
ret = alGetParamInfo(AL_DEFAULT_INPUT, AL_GAIN, &pinfo);
|
||||
|
@ -906,14 +1011,16 @@ bool TSoundInputDevice::supportsVolume() {
|
|||
else
|
||||
throw TSoundDeviceException(TSoundDeviceException::NoMixer,
|
||||
"Output device is not accessible");
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
TSoundTrackFormat TSoundInputDevice::getPreferredFormat(ULONG sampleRate,
|
||||
TSoundTrackFormat TSoundInputDevice::getPreferredFormat(TUINT32 sampleRate,
|
||||
int channelCount,
|
||||
int bitPerSample) {
|
||||
TSoundTrackFormat fmt;
|
||||
#ifdef __sgi
|
||||
int ret;
|
||||
|
||||
if (!m_imp->verifyRate())
|
||||
|
@ -966,7 +1073,7 @@ TSoundTrackFormat TSoundInputDevice::getPreferredFormat(ULONG sampleRate,
|
|||
fmt.m_channelCount = channelCount;
|
||||
fmt.m_sampleRate = sampleRate;
|
||||
fmt.m_signedSample = true;
|
||||
|
||||
#endif
|
||||
return fmt;
|
||||
}
|
||||
|
||||
|
@ -994,6 +1101,7 @@ bool TSoundInputDevice::isRecording() { return m_imp->m_isRecording; }
|
|||
//******************************************************************************
|
||||
namespace {
|
||||
bool isInterfaceSupported(int deviceType, int interfaceType) {
|
||||
#ifdef __sgi
|
||||
ALvalue vals[16];
|
||||
int devNum;
|
||||
|
||||
|
@ -1007,12 +1115,14 @@ bool isInterfaceSupported(int deviceType, int interfaceType) {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool setDefaultInput(TSoundInputDevice::Source type) {
|
||||
#ifdef __sgi
|
||||
string label;
|
||||
|
||||
switch (type) {
|
||||
|
@ -1046,13 +1156,14 @@ bool setDefaultInput(TSoundInputDevice::Source type) {
|
|||
param.value.i = dev;
|
||||
if (alSetParams(AL_SYSTEM, ¶m, 1) < 0)
|
||||
return false; // throw TException("Error to set input device");
|
||||
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool setDefaultOutput() {
|
||||
#ifdef __sgi
|
||||
ALpv pvbuf[1];
|
||||
|
||||
if (!isInterfaceSupported(AL_DEFAULT_OUTPUT, AL_SPEAKER_IF_TYPE))
|
||||
|
@ -1073,7 +1184,7 @@ bool setDefaultOutput() {
|
|||
|
||||
if (alSetParams(AL_DEFAULT_OUTPUT, pvbuf, 1) < 0)
|
||||
return false; // throw TException("Unable to set output device params");
|
||||
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1084,6 +1195,7 @@ list<int> getInputDevice(int deviceType) {
|
|||
ALvalue vals[16];
|
||||
ALpv quals[1];
|
||||
list<int> devList;
|
||||
#ifdef __sgi
|
||||
int devNum;
|
||||
|
||||
quals[0].param = AL_TYPE;
|
||||
|
@ -1100,7 +1212,7 @@ list<int> getInputDevice(int deviceType) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
return devList;
|
||||
}
|
||||
|
||||
|
@ -1112,6 +1224,7 @@ list<int> getInputDevice(int deviceType, int itfType) {
|
|||
ALpv quals[1];
|
||||
list<int> devList;
|
||||
int devNum;
|
||||
#ifdef __sgi
|
||||
|
||||
quals[0].param = AL_TYPE;
|
||||
quals[0].value.i = deviceType;
|
||||
|
@ -1129,13 +1242,14 @@ list<int> getInputDevice(int deviceType, int itfType) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
return devList;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
string getResourceLabel(int resourceID) {
|
||||
#ifdef __sgi
|
||||
ALpv par[1];
|
||||
char l[32];
|
||||
|
||||
|
@ -1146,6 +1260,9 @@ string getResourceLabel(int resourceID) {
|
|||
alGetParams(resourceID, par, 1);
|
||||
|
||||
return string(l);
|
||||
#else
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -1153,6 +1270,7 @@ string getResourceLabel(int resourceID) {
|
|||
// verify the samplerate of the select device is changed from another
|
||||
// application
|
||||
bool isChangeOutput(ULONG sampleRate) {
|
||||
#ifdef __sgi
|
||||
ALpv par[2];
|
||||
char l[32];
|
||||
|
||||
|
@ -1167,5 +1285,8 @@ bool isChangeOutput(ULONG sampleRate) {
|
|||
return true;
|
||||
else
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue