|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tsound_t.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "texception.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tthread.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include <errno.h></errno.h>
|
|
Toshihiro Shimizu |
890ddd |
#include <audio.h></audio.h>
|
|
Toshihiro Shimizu |
890ddd |
#include <unistd.h></unistd.h>
|
|
Toshihiro Shimizu |
890ddd |
#include <queue></queue>
|
|
Toshihiro Shimizu |
890ddd |
#include <set></set>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//forward declaration
|
|
Toshihiro Shimizu |
890ddd |
namespace
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
bool isInterfaceSupported(int deviceType, int interfaceType);
|
|
Toshihiro Shimizu |
890ddd |
bool setDefaultInput(TSoundInputDevice::Source type);
|
|
Toshihiro Shimizu |
890ddd |
bool setDefaultOutput();
|
|
Toshihiro Shimizu |
890ddd |
bool isChangeOutput(ULONG sampleRate);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
class TSoundOutputDeviceImp
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
ALport m_port;
|
|
Toshihiro Shimizu |
890ddd |
bool m_stopped;
|
|
Toshihiro Shimizu |
890ddd |
bool m_isPlaying;
|
|
Toshihiro Shimizu |
890ddd |
bool m_looped;
|
|
Toshihiro Shimizu |
890ddd |
TSoundTrackFormat m_currentFormat;
|
|
Toshihiro Shimizu |
890ddd |
std::queue<tsoundtrackp> m_queuedSoundTracks;</tsoundtrackp>
|
|
Toshihiro Shimizu |
890ddd |
std::set<int> m_supportedRate;</int>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TThread::Executor m_executor;
|
|
Toshihiro Shimizu |
890ddd |
TThread::Mutex m_mutex;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TSoundOutputDeviceImp()
|
|
Toshihiro Shimizu |
890ddd |
: m_stopped(false), m_isPlaying(false), m_looped(false), m_port(NULL), m_queuedSoundTracks(), m_supportedRate(){};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
~TSoundOutputDeviceImp(){};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool doOpenDevice(const TSoundTrackFormat &format);
|
|
Toshihiro Shimizu |
890ddd |
void insertAllRate();
|
|
Toshihiro Shimizu |
890ddd |
bool verifyRate();
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TSoundOutputDeviceImp::doOpenDevice(const TSoundTrackFormat &format)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
ALconfig config;
|
|
Toshihiro Shimizu |
890ddd |
ALpv pvbuf[3];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_currentFormat = format;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// AL_MONITOR_CTL fa parte dei vecchi andrebbero trovati quelli nuovi
|
|
Toshihiro Shimizu |
890ddd |
pvbuf[0].param = AL_PORT_COUNT;
|
|
Toshihiro Shimizu |
890ddd |
pvbuf[1].param = AL_MONITOR_CTL;
|
|
Toshihiro Shimizu |
890ddd |
if (alGetParams(AL_DEFAULT_OUTPUT, pvbuf, 2) < 0)
|
|
Toshihiro Shimizu |
890ddd |
if (oserror() == AL_BAD_DEVICE_ACCESS)
|
|
Toshihiro Shimizu |
890ddd |
return false; //throw TException("Could not access audio hardware.");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!isInterfaceSupported(AL_DEFAULT_OUTPUT, AL_SPEAKER_IF_TYPE))
|
|
Toshihiro Shimizu |
890ddd |
return false; //throw TException("Speakers are not supported");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int dev = alGetResourceByName(AL_SYSTEM, (char *)"Headphone/Speaker", AL_DEVICE_TYPE);
|
|
Toshihiro Shimizu |
890ddd |
if (!dev)
|
|
Toshihiro Shimizu |
890ddd |
return false; //throw TException("invalid device speakers");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
pvbuf[0].param = AL_DEFAULT_OUTPUT;
|
|
Toshihiro Shimizu |
890ddd |
pvbuf[0].value.i = dev;
|
|
Toshihiro Shimizu |
890ddd |
alSetParams(AL_SYSTEM, pvbuf, 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ALfixed buf[2] = {alDoubleToFixed(0), alDoubleToFixed(0)};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
config = alNewConfig();
|
|
Toshihiro Shimizu |
890ddd |
// qui devo metterci gli altoparlanti e poi setto i valori per il default output
|
|
Toshihiro Shimizu |
890ddd |
pvbuf[0].param = AL_RATE;
|
|
Toshihiro Shimizu |
890ddd |
pvbuf[0].value.ll = alDoubleToFixed((double)format.m_sampleRate);
|
|
Toshihiro Shimizu |
890ddd |
pvbuf[1].param = AL_GAIN;
|
|
Toshihiro Shimizu |
890ddd |
pvbuf[1].value.ptr = buf;
|
|
Toshihiro Shimizu |
890ddd |
pvbuf[1].sizeIn = 8;
|
|
Toshihiro Shimizu |
890ddd |
pvbuf[2].param = AL_INTERFACE;
|
|
Toshihiro Shimizu |
890ddd |
pvbuf[2].value.i = AL_SPEAKER_IF_TYPE;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (alSetParams(AL_DEFAULT_OUTPUT, pvbuf, 3) < 0)
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
//throw TException("Unable to set params for output device");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (alSetChannels(config, format.m_channelCount) == -1)
|
|
Toshihiro Shimizu |
890ddd |
return false; //throw TException("Error to setting audio hardware.");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int bytePerSample = format.m_bitPerSample >> 3;
|
|
Toshihiro Shimizu |
890ddd |
switch (bytePerSample) {
|
|
Toshihiro Shimizu |
890ddd |
case 3:
|
|
Toshihiro Shimizu |
890ddd |
bytePerSample++;
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
default:
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (alSetWidth(config, bytePerSample) == -1)
|
|
Toshihiro Shimizu |
890ddd |
return false; //throw TException("Error to setting audio hardware.");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (alSetSampFmt(config, AL_SAMPFMT_TWOSCOMP) == -1)
|
|
Toshihiro Shimizu |
890ddd |
return false; //throw TException("Error to setting audio hardware.");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (alSetQueueSize(config, (TINT32)format.m_sampleRate) == -1)
|
|
Toshihiro Shimizu |
890ddd |
return false; //throw TException("Error to setting audio hardware.");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_port = alOpenPort("AudioOutput", "w", config);
|
|
Toshihiro Shimizu |
890ddd |
if (!m_port)
|
|
Toshihiro Shimizu |
890ddd |
return false; //throw TException("Could not open audio port.");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
alFreeConfig(config);
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TSoundOutputDeviceImp::insertAllRate()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_supportedRate.insert(8000);
|
|
Toshihiro Shimizu |
890ddd |
m_supportedRate.insert(11025);
|
|
Toshihiro Shimizu |
890ddd |
m_supportedRate.insert(16000);
|
|
Toshihiro Shimizu |
890ddd |
m_supportedRate.insert(22050);
|
|
Toshihiro Shimizu |
890ddd |
m_supportedRate.insert(32000);
|
|
Toshihiro Shimizu |
890ddd |
m_supportedRate.insert(44100);
|
|
Toshihiro Shimizu |
890ddd |
m_supportedRate.insert(48000);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TSoundOutputDeviceImp::verifyRate()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
//Sample Rate
|
|
Toshihiro Shimizu |
890ddd |
ALparamInfo pinfo;
|
|
Toshihiro Shimizu |
890ddd |
int ret = alGetParamInfo(AL_DEFAULT_OUTPUT, AL_RATE, &pinfo);
|
|
Toshihiro Shimizu |
890ddd |
if (ret != -1 && pinfo.elementType == AL_FIXED_ELEM) {
|
|
Toshihiro Shimizu |
890ddd |
int min = (int)alFixedToDouble(pinfo.min.ll);
|
|
Toshihiro Shimizu |
890ddd |
int max = (int)alFixedToDouble(pinfo.max.ll);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::set<int>::iterator it;</int>
|
|
Toshihiro Shimizu |
890ddd |
for (it = m_supportedRate.begin(); it != m_supportedRate.end(); ++it)
|
|
Toshihiro Shimizu |
890ddd |
if (*it < min || *it > max)
|
|
Toshihiro Shimizu |
890ddd |
m_supportedRate.erase(*it);
|
|
Toshihiro Shimizu |
890ddd |
if (m_supportedRate.end() == m_supportedRate.begin())
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
} else if (ret == AL_BAD_PARAM)
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
class PlayTask : public TThread::Runnable
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
TSoundOutputDeviceImp *m_devImp;
|
|
Toshihiro Shimizu |
890ddd |
TSoundTrackP m_sndtrack;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
PlayTask(TSoundOutputDeviceImp *devImp, const TSoundTrackP &st)
|
|
Toshihiro Shimizu |
890ddd |
: TThread::Runnable(), m_devImp(devImp), m_sndtrack(st){};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
~PlayTask(){};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void run();
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void PlayTask::run()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int leftToPlay = m_sndtrack->getSampleCount();
|
|
Toshihiro Shimizu |
890ddd |
int i = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!m_devImp->m_port ||
|
|
Toshihiro Shimizu |
890ddd |
(m_devImp->m_currentFormat != m_sndtrack->getFormat()) ||
|
|
Toshihiro Shimizu |
890ddd |
isChangeOutput(m_sndtrack->getSampleRate()))
|
|
Toshihiro Shimizu |
890ddd |
if (!m_devImp->doOpenDevice(m_sndtrack->getFormat()))
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
while ((leftToPlay > 0) && m_devImp->m_isPlaying) {
|
|
Toshihiro Shimizu |
890ddd |
int fillable = alGetFillable(m_devImp->m_port);
|
|
Toshihiro Shimizu |
890ddd |
if (!fillable)
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (fillable < leftToPlay) {
|
|
Toshihiro Shimizu |
890ddd |
alWriteFrames(m_devImp->m_port, (void *)(m_sndtrack->getRawData() + i), fillable);
|
|
Toshihiro Shimizu |
890ddd |
// ricorda getSampleSize restituisce m_sampleSize che comprende gia'
|
|
Toshihiro Shimizu |
890ddd |
// la moltiplicazione per il numero dei canali
|
|
Toshihiro Shimizu |
890ddd |
i += fillable * m_sndtrack->getSampleSize();
|
|
Toshihiro Shimizu |
890ddd |
leftToPlay -= fillable;
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
alWriteFrames(m_devImp->m_port, (void *)(m_sndtrack->getRawData() + i), leftToPlay);
|
|
Toshihiro Shimizu |
890ddd |
leftToPlay = 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!m_devImp->m_stopped) {
|
|
Toshihiro Shimizu |
890ddd |
while (ALgetfilled(m_devImp->m_port) > 0)
|
|
Toshihiro Shimizu |
890ddd |
sginap(1);
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TThread::ScopedLock sl(m_devImp->m_mutex);
|
|
Toshihiro Shimizu |
890ddd |
if (!m_devImp->m_looped)
|
|
Toshihiro Shimizu |
890ddd |
m_devImp->m_queuedSoundTracks.pop();
|
|
Toshihiro Shimizu |
890ddd |
if (m_devImp->m_queuedSoundTracks.empty()) {
|
|
Toshihiro Shimizu |
890ddd |
m_devImp->m_isPlaying = false;
|
|
Toshihiro Shimizu |
890ddd |
m_devImp->m_stopped = true;
|
|
Toshihiro Shimizu |
890ddd |
m_devImp->m_looped = false;
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
m_devImp->m_executor.addTask(
|
|
Toshihiro Shimizu |
890ddd |
new PlayTask(m_devImp, m_devImp->m_queuedSoundTracks.front()));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
alDiscardFrames(m_devImp->m_port, alGetFilled(m_devImp->m_port));
|
|
Toshihiro Shimizu |
890ddd |
while (!m_devImp->m_queuedSoundTracks.empty())
|
|
Toshihiro Shimizu |
890ddd |
m_devImp->m_queuedSoundTracks.pop();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TSoundOutputDevice::TSoundOutputDevice() : m_imp(new TSoundOutputDeviceImp)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (!setDefaultOutput())
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::UnableSetDevice, "Speaker not supported");
|
|
Toshihiro Shimizu |
890ddd |
try {
|
|
Toshihiro Shimizu |
890ddd |
supportsVolume();
|
|
Toshihiro Shimizu |
890ddd |
} catch (TSoundDeviceException &e) {
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(e.getType(), e.getMessage());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
m_imp->insertAllRate();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TSoundOutputDevice::~TSoundOutputDevice()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
close();
|
|
Toshihiro Shimizu |
890ddd |
delete m_imp;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TSoundOutputDevice::installed()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (alQueryValues(AL_SYSTEM, AL_DEFAULT_OUTPUT, 0, 0, 0, 0) <= 0)
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TSoundOutputDevice::open(const TSoundTrackP &st)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (!m_imp->doOpenDevice(st->getFormat()))
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::UnableOpenDevice,
|
|
Toshihiro Shimizu |
890ddd |
"Problem to open the output device or set some params");
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TSoundOutputDevice::close()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
stop();
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_port)
|
|
Toshihiro Shimizu |
890ddd |
alClosePort(m_imp->m_port);
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_port = NULL;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TSoundOutputDevice::play(const TSoundTrackP &st, TINT32 s0, TINT32 s1, bool loop, bool scrubbing)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (!st->getSampleCount())
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TThread::ScopedLock sl(m_imp->m_mutex);
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_looped)
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::Busy,
|
|
Toshihiro Shimizu |
890ddd |
"Unable to queue another playback when the sound player is looping");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_isPlaying = true;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_stopped = false;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_looped = loop;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TSoundTrackFormat fmt;
|
|
Toshihiro Shimizu |
890ddd |
try {
|
|
Toshihiro Shimizu |
890ddd |
fmt = getPreferredFormat(st->getFormat());
|
|
Toshihiro Shimizu |
890ddd |
if (fmt != st->getFormat()) {
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::UnsupportedFormat,
|
|
Toshihiro Shimizu |
890ddd |
"Unsupported Format");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} catch (TSoundDeviceException &e) {
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::UnsupportedFormat,
|
|
Toshihiro Shimizu |
890ddd |
e.getMessage());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(s1 >= s0);
|
|
Toshihiro Shimizu |
890ddd |
TSoundTrackP subTrack = st->extract(s0, s1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//far partire il thread
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_queuedSoundTracks.empty()) {
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_queuedSoundTracks.push(subTrack);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_executor.addTask(new PlayTask(m_imp, subTrack));
|
|
Toshihiro Shimizu |
890ddd |
} else
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_queuedSoundTracks.push(subTrack);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TSoundOutputDevice::stop()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (!m_imp->m_isPlaying)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TThread::ScopedLock sl(m_imp->m_mutex);
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_isPlaying = false;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_stopped = true;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_looped = false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double TSoundOutputDevice::getVolume()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
ALpv pv[1];
|
|
Toshihiro Shimizu |
890ddd |
ALfixed value[2];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
try {
|
|
Toshihiro Shimizu |
890ddd |
supportsVolume();
|
|
Toshihiro Shimizu |
890ddd |
} catch (TSoundDeviceException &e) {
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(e.getType(), e.getMessage());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
pv[0].param = AL_GAIN;
|
|
Toshihiro Shimizu |
890ddd |
pv[0].value.ptr = value;
|
|
Toshihiro Shimizu |
890ddd |
pv[0].sizeIn = 8;
|
|
Toshihiro Shimizu |
890ddd |
alGetParams(AL_DEFAULT_OUTPUT, pv, 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double val = (((alFixedToDouble(value[0]) + alFixedToDouble(value[1])) / 2.) + 60.) / 8.05;
|
|
Toshihiro Shimizu |
890ddd |
return val;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TSoundOutputDevice::setVolume(double volume)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
ALpv pv[1];
|
|
Toshihiro Shimizu |
890ddd |
ALfixed value[2];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
try {
|
|
Toshihiro Shimizu |
890ddd |
supportsVolume();
|
|
Toshihiro Shimizu |
890ddd |
} catch (TSoundDeviceException &e) {
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(e.getType(), e.getMessage());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double val = -60. + 8.05 * volume;
|
|
Toshihiro Shimizu |
890ddd |
value[0] = alDoubleToFixed(val);
|
|
Toshihiro Shimizu |
890ddd |
value[1] = alDoubleToFixed(val);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
pv[0].param = AL_GAIN;
|
|
Toshihiro Shimizu |
890ddd |
pv[0].value.ptr = value;
|
|
Toshihiro Shimizu |
890ddd |
pv[0].sizeIn = 8;
|
|
Toshihiro Shimizu |
890ddd |
if (alSetParams(AL_DEFAULT_OUTPUT, pv, 1) < 0)
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TSoundOutputDevice::supportsVolume()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
ALparamInfo pinfo;
|
|
Toshihiro Shimizu |
890ddd |
int ret;
|
|
Toshihiro Shimizu |
890ddd |
ret = alGetParamInfo(AL_DEFAULT_OUTPUT, AL_GAIN, &pinfo);
|
|
Toshihiro Shimizu |
890ddd |
double min = alFixedToDouble(pinfo.min.ll);
|
|
Toshihiro Shimizu |
890ddd |
double max = alFixedToDouble(pinfo.max.ll);
|
|
Toshihiro Shimizu |
890ddd |
if ((ret != -1) && (min != max) && (max != 0.0))
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
else if ((ret == AL_BAD_PARAM) || ((min == max) && (max == 0.0)))
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::UnableVolume,
|
|
Toshihiro Shimizu |
890ddd |
"It is impossible to chamge setting of volume");
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::NoMixer, "Output device is not accessible");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TSoundOutputDevice::isPlaying() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_isPlaying;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TSoundOutputDevice::isLooping()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TThread::ScopedLock sl(m_imp->m_mutex);
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_looped;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TSoundOutputDevice::setLooping(bool loop)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TThread::ScopedLock sl(m_imp->m_mutex);
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_looped = loop;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TSoundTrackFormat TSoundOutputDevice::getPreferredFormat(
|
|
Toshihiro Shimizu |
890ddd |
ULONG sampleRate, int channelCount, int bitPerSample)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TSoundTrackFormat fmt;
|
|
Toshihiro Shimizu |
890ddd |
int ret;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!m_imp->verifyRate())
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::UnsupportedFormat,
|
|
Toshihiro Shimizu |
890ddd |
"There isn't any support rate");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_supportedRate.find((int)sampleRate) ==
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_supportedRate.end()) {
|
|
Toshihiro Shimizu |
890ddd |
std::set<int>::iterator it =</int>
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_supportedRate.lower_bound((int)sampleRate);
|
|
Toshihiro Shimizu |
890ddd |
if (it == m_imp->m_supportedRate.end()) {
|
|
Toshihiro Shimizu |
890ddd |
it = std::max_element(m_imp->m_supportedRate.begin(),
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_supportedRate.end());
|
|
Toshihiro Shimizu |
890ddd |
if (it != m_imp->m_supportedRate.end())
|
|
Toshihiro Shimizu |
890ddd |
sampleRate = *(m_imp->m_supportedRate.rbegin());
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::UnsupportedFormat,
|
|
Toshihiro Shimizu |
890ddd |
"There isn't a supported rate");
|
|
Toshihiro Shimizu |
890ddd |
} else
|
|
Toshihiro Shimizu |
890ddd |
sampleRate = *it;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int value;
|
|
Toshihiro Shimizu |
890ddd |
ALvalue vals[32];
|
|
Toshihiro Shimizu |
890ddd |
if ((ret = alQueryValues(AL_DEFAULT_OUTPUT, AL_CHANNELS, vals, 32, 0, 0)) > 0)
|
|
Toshihiro Shimizu |
890ddd |
for (int i = 0; i < ret; ++i)
|
|
Toshihiro Shimizu |
890ddd |
value = vals[i].i;
|
|
Toshihiro Shimizu |
890ddd |
else if (oserror() == AL_BAD_PARAM)
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::NoMixer,
|
|
Toshihiro Shimizu |
890ddd |
"It is impossible ask for the max numbers of channels supported");
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::NoMixer,
|
|
Toshihiro Shimizu |
890ddd |
"It is impossibile information about ouput device");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (value > 2)
|
|
Toshihiro Shimizu |
890ddd |
value = 2;
|
|
Toshihiro Shimizu |
890ddd |
if (channelCount > value)
|
|
Toshihiro Shimizu |
890ddd |
channelCount = value;
|
|
Toshihiro Shimizu |
890ddd |
else if (channelCount <= 0)
|
|
Toshihiro Shimizu |
890ddd |
channelCount = 1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (bitPerSample <= 8)
|
|
Toshihiro Shimizu |
890ddd |
bitPerSample = 8;
|
|
Toshihiro Shimizu |
890ddd |
else if (bitPerSample <= 16)
|
|
Toshihiro Shimizu |
890ddd |
bitPerSample = 16;
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
bitPerSample = 24;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
fmt.m_bitPerSample = bitPerSample;
|
|
Toshihiro Shimizu |
890ddd |
fmt.m_channelCount = channelCount;
|
|
Toshihiro Shimizu |
890ddd |
fmt.m_sampleRate = sampleRate;
|
|
Toshihiro Shimizu |
890ddd |
fmt.m_signedSample = true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return fmt;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TSoundTrackFormat TSoundOutputDevice::getPreferredFormat(const TSoundTrackFormat &format)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
try {
|
|
Toshihiro Shimizu |
890ddd |
return getPreferredFormat(
|
|
Toshihiro Shimizu |
890ddd |
format.m_sampleRate, format.m_channelCount, format.m_bitPerSample);
|
|
Toshihiro Shimizu |
890ddd |
} catch (TSoundDeviceException &e) {
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(e.getType(), e.getMessage());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
// REGISTRAZIONE
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
class TSoundInputDeviceImp
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
ALport m_port;
|
|
Toshihiro Shimizu |
890ddd |
bool m_stopped;
|
|
Toshihiro Shimizu |
890ddd |
bool m_isRecording;
|
|
Toshihiro Shimizu |
890ddd |
bool m_oneShotRecording;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TINT32 m_recordedSampleCount;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vector<char *=""> m_recordedBlocks;</char>
|
|
Toshihiro Shimizu |
890ddd |
vector<int> m_samplePerBlocks;</int>
|
|
Toshihiro Shimizu |
890ddd |
TSoundTrackFormat m_currentFormat;
|
|
Toshihiro Shimizu |
890ddd |
TSoundTrackP m_st;
|
|
Toshihiro Shimizu |
890ddd |
std::set<int> m_supportedRate;</int>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TThread::Executor m_executor;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TSoundInputDeviceImp()
|
|
Toshihiro Shimizu |
890ddd |
: m_stopped(false), m_isRecording(false), m_port(NULL), m_recordedBlocks(), m_samplePerBlocks(), m_recordedSampleCount(0), m_oneShotRecording(false), m_st(0), m_supportedRate(){};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
~TSoundInputDeviceImp(){};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool doOpenDevice(const TSoundTrackFormat &format,
|
|
Toshihiro Shimizu |
890ddd |
TSoundInputDevice::Source devType);
|
|
Toshihiro Shimizu |
890ddd |
void insertAllRate();
|
|
Toshihiro Shimizu |
890ddd |
bool verifyRate();
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TSoundInputDeviceImp::doOpenDevice(const TSoundTrackFormat &format,
|
|
Toshihiro Shimizu |
890ddd |
TSoundInputDevice::Source devType)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
ALconfig config;
|
|
Toshihiro Shimizu |
890ddd |
ALpv pvbuf[2];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_currentFormat = format;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// AL_MONITOR_CTL fa parte dei vecchi andrebbero trovati quelli nuovi
|
|
Toshihiro Shimizu |
890ddd |
pvbuf[0].param = AL_PORT_COUNT;
|
|
Toshihiro Shimizu |
890ddd |
pvbuf[1].param = AL_MONITOR_CTL;
|
|
Toshihiro Shimizu |
890ddd |
if (alGetParams(AL_DEFAULT_INPUT, pvbuf, 2) < 0)
|
|
Toshihiro Shimizu |
890ddd |
if (oserror() == AL_BAD_DEVICE_ACCESS)
|
|
Toshihiro Shimizu |
890ddd |
return false; //throw TException("Could not access audio hardware.");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
config = alNewConfig();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!setDefaultInput(devType))
|
|
Toshihiro Shimizu |
890ddd |
return false; //throw TException("Could not set the input device specified");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
pvbuf[0].param = AL_RATE;
|
|
Toshihiro Shimizu |
890ddd |
pvbuf[0].value.ll = alDoubleToFixed(format.m_sampleRate);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ALfixed buf[2] = {alDoubleToFixed(0), alDoubleToFixed(0)};
|
|
Toshihiro Shimizu |
890ddd |
pvbuf[1].param = AL_GAIN;
|
|
Toshihiro Shimizu |
890ddd |
pvbuf[1].value.ptr = buf;
|
|
Toshihiro Shimizu |
890ddd |
pvbuf[1].sizeIn = 8;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (alSetParams(AL_DEFAULT_INPUT, pvbuf, 2) < 0)
|
|
Toshihiro Shimizu |
890ddd |
return false; //throw TException("Problem to set params ");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (alSetChannels(config, format.m_channelCount) == -1)
|
|
Toshihiro Shimizu |
890ddd |
return false; //throw TException("Error to setting audio hardware.");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int bytePerSample = format.m_bitPerSample >> 3;
|
|
Toshihiro Shimizu |
890ddd |
switch (bytePerSample) {
|
|
Toshihiro Shimizu |
890ddd |
case 3:
|
|
Toshihiro Shimizu |
890ddd |
bytePerSample++;
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
default:
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (alSetWidth(config, bytePerSample) == -1)
|
|
Toshihiro Shimizu |
890ddd |
return false; //throw TException("Error to setting audio hardware.");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (alSetSampFmt(config, AL_SAMPFMT_TWOSCOMP) == -1)
|
|
Toshihiro Shimizu |
890ddd |
return false; //throw TException("Error to setting audio hardware.");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (alSetQueueSize(config, (TINT32)format.m_sampleRate) == -1)
|
|
Toshihiro Shimizu |
890ddd |
return false; //throw TException("Error to setting audio hardware.");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
alSetDevice(config, AL_DEFAULT_INPUT);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_port = alOpenPort("AudioInput", "r", config);
|
|
Toshihiro Shimizu |
890ddd |
if (!m_port)
|
|
Toshihiro Shimizu |
890ddd |
return false; //throw TException("Could not open audio port.");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
alFreeConfig(config);
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TSoundInputDeviceImp::insertAllRate()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_supportedRate.insert(8000);
|
|
Toshihiro Shimizu |
890ddd |
m_supportedRate.insert(11025);
|
|
Toshihiro Shimizu |
890ddd |
m_supportedRate.insert(16000);
|
|
Toshihiro Shimizu |
890ddd |
m_supportedRate.insert(22050);
|
|
Toshihiro Shimizu |
890ddd |
m_supportedRate.insert(32000);
|
|
Toshihiro Shimizu |
890ddd |
m_supportedRate.insert(44100);
|
|
Toshihiro Shimizu |
890ddd |
m_supportedRate.insert(48000);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TSoundInputDeviceImp::verifyRate()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
//Sample Rate
|
|
Toshihiro Shimizu |
890ddd |
ALparamInfo pinfo;
|
|
Toshihiro Shimizu |
890ddd |
int ret = alGetParamInfo(AL_DEFAULT_INPUT, AL_RATE, &pinfo);
|
|
Toshihiro Shimizu |
890ddd |
if (ret != -1 && pinfo.elementType == AL_FIXED_ELEM) {
|
|
Toshihiro Shimizu |
890ddd |
int min = (int)alFixedToDouble(pinfo.min.ll);
|
|
Toshihiro Shimizu |
890ddd |
int max = (int)alFixedToDouble(pinfo.max.ll);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::set<int>::iterator it;</int>
|
|
Toshihiro Shimizu |
890ddd |
for (it = m_supportedRate.begin(); it != m_supportedRate.end(); ++it)
|
|
Toshihiro Shimizu |
890ddd |
if (*it < min || *it > max)
|
|
Toshihiro Shimizu |
890ddd |
m_supportedRate.erase(*it);
|
|
Toshihiro Shimizu |
890ddd |
if (m_supportedRate.end() == m_supportedRate.begin())
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
} else if (ret == AL_BAD_PARAM)
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
class RecordTask : public TThread::Runnable
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
TSoundInputDeviceImp *m_devImp;
|
|
Toshihiro Shimizu |
890ddd |
int m_ByteToSample;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
RecordTask(TSoundInputDeviceImp *devImp, int numByte)
|
|
Toshihiro Shimizu |
890ddd |
: TThread::Runnable(), m_devImp(devImp), m_ByteToSample(numByte){};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
~RecordTask(){};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void run();
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void RecordTask::run()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TINT32 byteRecordedSample = 0;
|
|
Toshihiro Shimizu |
890ddd |
int filled = alGetFilled(m_devImp->m_port);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_devImp->m_oneShotRecording) {
|
|
Toshihiro Shimizu |
890ddd |
char *rawData = m_devImp->m_recordedBlocks.front();
|
|
Toshihiro Shimizu |
890ddd |
int sampleSize;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if ((m_devImp->m_currentFormat.m_bitPerSample >> 3) == 3)
|
|
Toshihiro Shimizu |
890ddd |
sampleSize = 4;
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
sampleSize = (m_devImp->m_currentFormat.m_bitPerSample >> 3);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
sampleSize *= m_devImp->m_currentFormat.m_channelCount;
|
|
Toshihiro Shimizu |
890ddd |
while ((byteRecordedSample <= (m_ByteToSample - filled * sampleSize)) && m_devImp->m_isRecording) {
|
|
Toshihiro Shimizu |
890ddd |
alReadFrames(m_devImp->m_port, (void *)(rawData + byteRecordedSample), filled);
|
|
Toshihiro Shimizu |
890ddd |
byteRecordedSample += filled * sampleSize;
|
|
Toshihiro Shimizu |
890ddd |
filled = alGetFilled(m_devImp->m_port);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_devImp->m_isRecording) {
|
|
Toshihiro Shimizu |
890ddd |
alReadFrames(m_devImp->m_port, (void *)(rawData + byteRecordedSample),
|
|
Toshihiro Shimizu |
890ddd |
(m_ByteToSample - byteRecordedSample) / sampleSize);
|
|
Toshihiro Shimizu |
890ddd |
while (alGetFillable(m_devImp->m_port) > 0)
|
|
Toshihiro Shimizu |
890ddd |
sginap(1);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
while (m_devImp->m_isRecording) {
|
|
Toshihiro Shimizu |
890ddd |
filled = alGetFilled(m_devImp->m_port);
|
|
Toshihiro Shimizu |
890ddd |
if (filled > 0) {
|
|
Toshihiro Shimizu |
890ddd |
char *dataBuffer = new char[filled * m_ByteToSample];
|
|
Toshihiro Shimizu |
890ddd |
m_devImp->m_recordedBlocks.push_back(dataBuffer);
|
|
Toshihiro Shimizu |
890ddd |
m_devImp->m_samplePerBlocks.push_back(filled * m_ByteToSample);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
alReadFrames(m_devImp->m_port, (void *)dataBuffer, filled);
|
|
Toshihiro Shimizu |
890ddd |
m_devImp->m_recordedSampleCount += filled;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
while (alGetFillable(m_devImp->m_port) > 0)
|
|
Toshihiro Shimizu |
890ddd |
sginap(1);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
alClosePort(m_devImp->m_port);
|
|
Toshihiro Shimizu |
890ddd |
m_devImp->m_port = 0;
|
|
Toshihiro Shimizu |
890ddd |
m_devImp->m_stopped = true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TSoundInputDevice::TSoundInputDevice() : m_imp(new TSoundInputDeviceImp)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TSoundInputDevice::~TSoundInputDevice()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_port)
|
|
Toshihiro Shimizu |
890ddd |
alClosePort(m_imp->m_port);
|
|
Toshihiro Shimizu |
890ddd |
delete m_imp;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TSoundInputDevice::installed()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (alQueryValues(AL_SYSTEM, AL_DEFAULT_INPUT, 0, 0, 0, 0) <= 0)
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TSoundInputDevice::record(const TSoundTrackFormat &format, TSoundInputDevice::Source type)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_isRecording == true)
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::Busy,
|
|
Toshihiro Shimizu |
890ddd |
"Just another recoding is in progress");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_recordedBlocks.clear();
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_samplePerBlocks.clear();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//registra creando una nuova traccia
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_oneShotRecording = false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!setDefaultInput(type))
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::UnableSetDevice,
|
|
Toshihiro Shimizu |
890ddd |
"Error to set the input device");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->insertAllRate();
|
|
Toshihiro Shimizu |
890ddd |
TSoundTrackFormat fmt;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
try {
|
|
Toshihiro Shimizu |
890ddd |
fmt = getPreferredFormat(format);
|
|
Toshihiro Shimizu |
890ddd |
if (fmt != format) {
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::UnsupportedFormat,
|
|
Toshihiro Shimizu |
890ddd |
"Unsupported Format");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} catch (TSoundDeviceException &e) {
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::UnsupportedFormat,
|
|
Toshihiro Shimizu |
890ddd |
e.getMessage());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!m_imp->m_port)
|
|
Toshihiro Shimizu |
890ddd |
m_imp->doOpenDevice(format, type);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_currentFormat = format;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_isRecording = true;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_stopped = false;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_recordedSampleCount = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int bytePerSample = format.m_bitPerSample >> 3;
|
|
Toshihiro Shimizu |
890ddd |
switch (bytePerSample) {
|
|
Toshihiro Shimizu |
890ddd |
case 3:
|
|
Toshihiro Shimizu |
890ddd |
bytePerSample++;
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
default:
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
bytePerSample *= format.m_channelCount;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//far partire il thread
|
|
Toshihiro Shimizu |
890ddd |
/*TRecordThread *recordThread = new TRecordThread(m_imp, bytePerSample);
|
|
Toshihiro Shimizu |
890ddd |
if (!recordThread)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_isRecording = false;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_stopped = true;
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::UnablePrepare,
|
|
Toshihiro Shimizu |
890ddd |
"Unable to create the recording thread");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
recordThread->start();*/
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_executor.addTask(new RecordTask(m_imp, bytePerSample));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TSoundInputDevice::record(const TSoundTrackP &st, TSoundInputDevice::Source type)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_isRecording == true)
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::Busy,
|
|
Toshihiro Shimizu |
890ddd |
"Just another recoding is in progress");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_recordedBlocks.clear();
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_samplePerBlocks.clear();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!setDefaultInput(type))
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::UnableSetDevice,
|
|
Toshihiro Shimizu |
890ddd |
"Error to set the input device");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->insertAllRate();
|
|
Toshihiro Shimizu |
890ddd |
TSoundTrackFormat fmt;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
try {
|
|
Toshihiro Shimizu |
890ddd |
fmt = getPreferredFormat(st->getFormat());
|
|
Toshihiro Shimizu |
890ddd |
if (fmt != st->getFormat()) {
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::UnsupportedFormat,
|
|
Toshihiro Shimizu |
890ddd |
"Unsupported Format");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} catch (TSoundDeviceException &e) {
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::UnsupportedFormat,
|
|
Toshihiro Shimizu |
890ddd |
e.getMessage());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!m_imp->m_port)
|
|
Toshihiro Shimizu |
890ddd |
if (!m_imp->doOpenDevice(st->getFormat(), type))
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::UnableOpenDevice,
|
|
Toshihiro Shimizu |
890ddd |
"Unable to open input device");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Sovrascive un'intera o parte di traccia gia' esistente
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_oneShotRecording = true;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_currentFormat = st->getFormat();
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_isRecording = true;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_stopped = false;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_recordedSampleCount = 0;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_st = st;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_recordedBlocks.push_back((char *)st->getRawData());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int totByteToSample = st->getSampleCount() * st->getSampleSize();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//far partire il thread
|
|
Toshihiro Shimizu |
890ddd |
/*TRecordThread *recordThread = new TRecordThread(m_imp, totByteToSample);
|
|
Toshihiro Shimizu |
890ddd |
if (!recordThread)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_isRecording = false;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_stopped = true;
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::UnablePrepare,
|
|
Toshihiro Shimizu |
890ddd |
"Unable to create the recording thread");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
recordThread->start();*/
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_executor.addTask(new RecordTask(m_imp, totByteToSample));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TSoundTrackP TSoundInputDevice::stop()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TSoundTrackP st;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!m_imp->m_isRecording)
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::UnablePrepare,
|
|
Toshihiro Shimizu |
890ddd |
"No recording process is in execution");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_isRecording = false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
alDiscardFrames(m_imp->m_port, alGetFilled(m_imp->m_port));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
while (!m_imp->m_stopped)
|
|
Toshihiro Shimizu |
890ddd |
sginap(1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_oneShotRecording)
|
|
Toshihiro Shimizu |
890ddd |
st = m_imp->m_st;
|
|
Toshihiro Shimizu |
890ddd |
else {
|
|
Toshihiro Shimizu |
890ddd |
st = TSoundTrack::create(m_imp->m_currentFormat, m_imp->m_recordedSampleCount);
|
|
Toshihiro Shimizu |
890ddd |
TINT32 bytesCopied = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (int i = 0; i < (int)m_imp->m_recordedBlocks.size(); ++i) {
|
|
Toshihiro Shimizu |
890ddd |
memcpy(
|
|
Toshihiro Shimizu |
890ddd |
(void *)(st->getRawData() + bytesCopied),
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_recordedBlocks[i],
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_samplePerBlocks[i]);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
delete[] m_imp->m_recordedBlocks[i];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bytesCopied += m_imp->m_samplePerBlocks[i];
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_samplePerBlocks.clear();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return st;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double TSoundInputDevice::getVolume()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
ALpv pv[1];
|
|
Toshihiro Shimizu |
890ddd |
ALfixed value[2];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
try {
|
|
Toshihiro Shimizu |
890ddd |
supportsVolume();
|
|
Toshihiro Shimizu |
890ddd |
} catch (TSoundDeviceException &e) {
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(e.getType(), e.getMessage());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
pv[0].param = AL_GAIN;
|
|
Toshihiro Shimizu |
890ddd |
pv[0].value.ptr = value;
|
|
Toshihiro Shimizu |
890ddd |
pv[0].sizeIn = 8;
|
|
Toshihiro Shimizu |
890ddd |
alGetParams(AL_DEFAULT_INPUT, pv, 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double val = (((alFixedToDouble(value[0]) + alFixedToDouble(value[1])) / 2.) + 60.) / 8.05;
|
|
Toshihiro Shimizu |
890ddd |
return val;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TSoundInputDevice::setVolume(double volume)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
ALpv pv[1];
|
|
Toshihiro Shimizu |
890ddd |
ALfixed value[2];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
try {
|
|
Toshihiro Shimizu |
890ddd |
supportsVolume();
|
|
Toshihiro Shimizu |
890ddd |
} catch (TSoundDeviceException &e) {
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(e.getType(), e.getMessage());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double val = -60. + 8.05 * volume;
|
|
Toshihiro Shimizu |
890ddd |
value[0] = alDoubleToFixed(val);
|
|
Toshihiro Shimizu |
890ddd |
value[1] = alDoubleToFixed(val);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
pv[0].param = AL_GAIN;
|
|
Toshihiro Shimizu |
890ddd |
pv[0].value.ptr = value;
|
|
Toshihiro Shimizu |
890ddd |
pv[0].sizeIn = 8;
|
|
Toshihiro Shimizu |
890ddd |
alSetParams(AL_DEFAULT_INPUT, pv, 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TSoundInputDevice::supportsVolume()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
ALparamInfo pinfo;
|
|
Toshihiro Shimizu |
890ddd |
int ret;
|
|
Toshihiro Shimizu |
890ddd |
ret = alGetParamInfo(AL_DEFAULT_INPUT, AL_GAIN, &pinfo);
|
|
Toshihiro Shimizu |
890ddd |
double min = alFixedToDouble(pinfo.min.ll);
|
|
Toshihiro Shimizu |
890ddd |
double max = alFixedToDouble(pinfo.max.ll);
|
|
Toshihiro Shimizu |
890ddd |
if ((ret != -1) && (min != max) && (max != 0.0))
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
else if ((ret == AL_BAD_PARAM) || ((min == max) && (max == 0.0)))
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::UnableVolume,
|
|
Toshihiro Shimizu |
890ddd |
"It is impossible to chamge setting of volume");
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::NoMixer, "Output device is not accessible");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TSoundTrackFormat TSoundInputDevice::getPreferredFormat(
|
|
Toshihiro Shimizu |
890ddd |
ULONG sampleRate, int channelCount, int bitPerSample)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TSoundTrackFormat fmt;
|
|
Toshihiro Shimizu |
890ddd |
int ret;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!m_imp->verifyRate())
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::UnsupportedFormat,
|
|
Toshihiro Shimizu |
890ddd |
"There isn't any support rate");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_supportedRate.find((int)sampleRate) ==
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_supportedRate.end()) {
|
|
Toshihiro Shimizu |
890ddd |
std::set<int>::iterator it =</int>
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_supportedRate.lower_bound((int)sampleRate);
|
|
Toshihiro Shimizu |
890ddd |
if (it == m_imp->m_supportedRate.end()) {
|
|
Toshihiro Shimizu |
890ddd |
it = std::max_element(m_imp->m_supportedRate.begin(),
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_supportedRate.end());
|
|
Toshihiro Shimizu |
890ddd |
if (it != m_imp->m_supportedRate.end())
|
|
Toshihiro Shimizu |
890ddd |
sampleRate = *(m_imp->m_supportedRate.rbegin());
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::UnsupportedFormat,
|
|
Toshihiro Shimizu |
890ddd |
"There isn't a supported rate");
|
|
Toshihiro Shimizu |
890ddd |
} else
|
|
Toshihiro Shimizu |
890ddd |
sampleRate = *it;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int value;
|
|
Toshihiro Shimizu |
890ddd |
ALvalue vals[32];
|
|
Toshihiro Shimizu |
890ddd |
if ((ret = alQueryValues(AL_DEFAULT_INPUT, AL_CHANNELS, vals, 32, 0, 0)) > 0)
|
|
Toshihiro Shimizu |
890ddd |
for (int i = 0; i < ret; ++i)
|
|
Toshihiro Shimizu |
890ddd |
value = vals[i].i;
|
|
Toshihiro Shimizu |
890ddd |
else if (oserror() == AL_BAD_PARAM)
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::NoMixer,
|
|
Toshihiro Shimizu |
890ddd |
"It is impossible ask for the max nembers of channels supported");
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(
|
|
Toshihiro Shimizu |
890ddd |
TSoundDeviceException::NoMixer,
|
|
Toshihiro Shimizu |
890ddd |
"It is impossibile information about ouput device");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (value > 2)
|
|
Toshihiro Shimizu |
890ddd |
value = 2;
|
|
Toshihiro Shimizu |
890ddd |
if (channelCount > value)
|
|
Toshihiro Shimizu |
890ddd |
channelCount = value;
|
|
Toshihiro Shimizu |
890ddd |
else if (channelCount <= 0)
|
|
Toshihiro Shimizu |
890ddd |
channelCount = 1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (bitPerSample <= 8)
|
|
Toshihiro Shimizu |
890ddd |
bitPerSample = 8;
|
|
Toshihiro Shimizu |
890ddd |
else if (bitPerSample <= 16)
|
|
Toshihiro Shimizu |
890ddd |
bitPerSample = 16;
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
bitPerSample = 24;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
fmt.m_bitPerSample = bitPerSample;
|
|
Toshihiro Shimizu |
890ddd |
fmt.m_channelCount = channelCount;
|
|
Toshihiro Shimizu |
890ddd |
fmt.m_sampleRate = sampleRate;
|
|
Toshihiro Shimizu |
890ddd |
fmt.m_signedSample = true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return fmt;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TSoundTrackFormat TSoundInputDevice::getPreferredFormat(const TSoundTrackFormat &format)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
try {
|
|
Toshihiro Shimizu |
890ddd |
return getPreferredFormat(
|
|
Toshihiro Shimizu |
890ddd |
format.m_sampleRate, format.m_channelCount, format.m_bitPerSample);
|
|
Toshihiro Shimizu |
890ddd |
} catch (TSoundDeviceException &e) {
|
|
Toshihiro Shimizu |
890ddd |
throw TSoundDeviceException(e.getType(), e.getMessage());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TSoundInputDevice::isRecording()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_isRecording;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//******************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
//******************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// funzioni per l'interazione con la libreria audio
|
|
Toshihiro Shimizu |
890ddd |
//******************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
//******************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
namespace
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
bool isInterfaceSupported(int deviceType, int interfaceType)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
ALvalue vals[16];
|
|
Toshihiro Shimizu |
890ddd |
int devNum;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if ((devNum = alQueryValues(AL_SYSTEM, deviceType, vals, 16, 0, 0)) > 0) {
|
|
Toshihiro Shimizu |
890ddd |
int i;
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < devNum; ++i) {
|
|
Toshihiro Shimizu |
890ddd |
ALpv quals[2];
|
|
Toshihiro Shimizu |
890ddd |
quals[0].param = AL_TYPE;
|
|
Toshihiro Shimizu |
890ddd |
quals[0].value.i = interfaceType;
|
|
Toshihiro Shimizu |
890ddd |
if (alQueryValues(vals[i].i, AL_INTERFACE, 0, 0, quals, 1) > 0)
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool setDefaultInput(TSoundInputDevice::Source type)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
string label;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
switch (type) {
|
|
Toshihiro Shimizu |
890ddd |
case TSoundInputDevice::LineIn:
|
|
Toshihiro Shimizu |
890ddd |
label = "Line In";
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
case TSoundInputDevice::DigitalIn:
|
|
Toshihiro Shimizu |
890ddd |
label = "AES Input";
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
default:
|
|
Toshihiro Shimizu |
890ddd |
label = "Microphone";
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int dev = alGetResourceByName(AL_SYSTEM, (char *)label.c_str(), AL_DEVICE_TYPE);
|
|
Toshihiro Shimizu |
890ddd |
if (!dev)
|
|
Toshihiro Shimizu |
890ddd |
return false; //throw TException("Error to set input device");
|
|
Toshihiro Shimizu |
890ddd |
int itf;
|
|
Toshihiro Shimizu |
890ddd |
if (itf = alGetResourceByName(AL_SYSTEM, (char *)label.c_str(), AL_INTERFACE_TYPE)) {
|
|
Toshihiro Shimizu |
890ddd |
ALpv p;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
p.param = AL_INTERFACE;
|
|
Toshihiro Shimizu |
890ddd |
p.value.i = itf;
|
|
Toshihiro Shimizu |
890ddd |
if (alSetParams(dev, &p, 1) < 0 || p.sizeOut < 0)
|
|
Toshihiro Shimizu |
890ddd |
return false; //throw TException("Error to set input device");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ALpv param;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
param.param = AL_DEFAULT_INPUT;
|
|
Toshihiro Shimizu |
890ddd |
param.value.i = dev;
|
|
Toshihiro Shimizu |
890ddd |
if (alSetParams(AL_SYSTEM, ¶m, 1) < 0)
|
|
Toshihiro Shimizu |
890ddd |
return false; //throw TException("Error to set input device");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool setDefaultOutput()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
ALpv pvbuf[1];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!isInterfaceSupported(AL_DEFAULT_OUTPUT, AL_SPEAKER_IF_TYPE))
|
|
Toshihiro Shimizu |
890ddd |
return false; //throw TException("Speakers are not supported");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int dev = alGetResourceByName(AL_SYSTEM, (char *)"Headphone/Speaker", AL_DEVICE_TYPE);
|
|
Toshihiro Shimizu |
890ddd |
if (!dev)
|
|
Toshihiro Shimizu |
890ddd |
return false; //throw TException("invalid device speakers");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
pvbuf[0].param = AL_DEFAULT_OUTPUT;
|
|
Toshihiro Shimizu |
890ddd |
pvbuf[0].value.i = dev;
|
|
Toshihiro Shimizu |
890ddd |
alSetParams(AL_SYSTEM, pvbuf, 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// qui devo metterci gli altoparlanti e poi setto i valori per il default output
|
|
Toshihiro Shimizu |
890ddd |
pvbuf[0].param = AL_INTERFACE;
|
|
Toshihiro Shimizu |
890ddd |
pvbuf[0].value.i = AL_SPEAKER_IF_TYPE;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (alSetParams(AL_DEFAULT_OUTPUT, pvbuf, 1) < 0)
|
|
Toshihiro Shimizu |
890ddd |
return false; // throw TException("Unable to set output device params");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//return the indexes of all input device of a particular type
|
|
Toshihiro Shimizu |
890ddd |
list<int> getInputDevice(int deviceType)</int>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
ALvalue vals[16];
|
|
Toshihiro Shimizu |
890ddd |
ALpv quals[1];
|
|
Toshihiro Shimizu |
890ddd |
list<int> devList;</int>
|
|
Toshihiro Shimizu |
890ddd |
int devNum;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
quals[0].param = AL_TYPE;
|
|
Toshihiro Shimizu |
890ddd |
quals[0].value.i = deviceType;
|
|
Toshihiro Shimizu |
890ddd |
if ((devNum = alQueryValues(AL_SYSTEM, AL_DEFAULT_INPUT, vals, 16, quals, 1)) > 0) {
|
|
Toshihiro Shimizu |
890ddd |
int i;
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < devNum; ++i) {
|
|
Toshihiro Shimizu |
890ddd |
int itf;
|
|
Toshihiro Shimizu |
890ddd |
ALvalue val[16];
|
|
Toshihiro Shimizu |
890ddd |
if ((itf = alQueryValues(i, AL_INTERFACE, val, 16, 0, 0)) > 0) {
|
|
Toshihiro Shimizu |
890ddd |
int j;
|
|
Toshihiro Shimizu |
890ddd |
for (j = 0; j < itf; ++j)
|
|
Toshihiro Shimizu |
890ddd |
devList.push_back(vals[j].i);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return devList;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//return the indexes of all input device of a particular type and interface
|
|
Toshihiro Shimizu |
890ddd |
list<int> getInputDevice(int deviceType, int itfType)</int>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
ALvalue vals[16];
|
|
Toshihiro Shimizu |
890ddd |
ALpv quals[1];
|
|
Toshihiro Shimizu |
890ddd |
list<int> devList;</int>
|
|
Toshihiro Shimizu |
890ddd |
int devNum;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
quals[0].param = AL_TYPE;
|
|
Toshihiro Shimizu |
890ddd |
quals[0].value.i = deviceType;
|
|
Toshihiro Shimizu |
890ddd |
if ((devNum = alQueryValues(AL_SYSTEM, AL_DEFAULT_INPUT, vals, 16, quals, 1)) > 0) {
|
|
Toshihiro Shimizu |
890ddd |
int i;
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < devNum; ++i) {
|
|
Toshihiro Shimizu |
890ddd |
int itf;
|
|
Toshihiro Shimizu |
890ddd |
ALvalue val[16];
|
|
Toshihiro Shimizu |
890ddd |
quals[0].param = AL_TYPE;
|
|
Toshihiro Shimizu |
890ddd |
quals[0].value.i = itfType;
|
|
Toshihiro Shimizu |
890ddd |
if ((itf = alQueryValues(i, AL_INTERFACE, val, 16, quals, 1)) > 0) {
|
|
Toshihiro Shimizu |
890ddd |
int j;
|
|
Toshihiro Shimizu |
890ddd |
for (j = 0; j < itf; ++j)
|
|
Toshihiro Shimizu |
890ddd |
devList.push_back(vals[j].i);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return devList;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
string getResourceLabel(int resourceID)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
ALpv par[1];
|
|
Toshihiro Shimizu |
890ddd |
char l[32];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
par[0].param = AL_LABEL;
|
|
Toshihiro Shimizu |
890ddd |
par[0].value.ptr = l;
|
|
Toshihiro Shimizu |
890ddd |
par[0].sizeIn = 32;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
alGetParams(resourceID, par, 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return string(l);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// verify the samplerate of the select device is changed from another application
|
|
Toshihiro Shimizu |
890ddd |
bool isChangeOutput(ULONG sampleRate)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
ALpv par[2];
|
|
Toshihiro Shimizu |
890ddd |
char l[32];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
par[0].param = AL_LABEL;
|
|
Toshihiro Shimizu |
890ddd |
par[0].value.ptr = l;
|
|
Toshihiro Shimizu |
890ddd |
par[0].sizeIn = 32;
|
|
Toshihiro Shimizu |
890ddd |
par[1].param = AL_RATE;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
alGetParams(AL_DEFAULT_OUTPUT, par, 2);
|
|
Toshihiro Shimizu |
890ddd |
if ((strcmp(l, "Analog Out") != 0) || (alFixedToDouble(par[1].value.ll) != sampleRate))
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|