From now on build default LASP with Portaudio backend. Also on Linux. Code cleanup of Portaudio glue code
This commit is contained in:
parent
292a9d5938
commit
08010e56dd
@ -15,9 +15,11 @@ using std::endl;
|
|||||||
using std::string;
|
using std::string;
|
||||||
using std::to_string;
|
using std::to_string;
|
||||||
|
|
||||||
inline void throwIfError(PaError e) {
|
inline void throwIfError(PaError e)
|
||||||
|
{
|
||||||
DEBUGTRACE_ENTER;
|
DEBUGTRACE_ENTER;
|
||||||
if (e != paNoError) {
|
if (e != paNoError)
|
||||||
|
{
|
||||||
throw rte(string("PortAudio backend error: ") + Pa_GetErrorText(e));
|
throw rte(string("PortAudio backend error: ") + Pa_GetErrorText(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -25,21 +27,25 @@ inline void throwIfError(PaError e) {
|
|||||||
/**
|
/**
|
||||||
* @brief Device info, plus PortAudio stuff
|
* @brief Device info, plus PortAudio stuff
|
||||||
*/
|
*/
|
||||||
class OurPaDeviceInfo : public DeviceInfo {
|
class OurPaDeviceInfo : public DeviceInfo
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Store instance to PaDeviceInfo.
|
* @brief Store instance to PaDeviceInfo.
|
||||||
*/
|
*/
|
||||||
PaDeviceInfo _paDevInfo;
|
PaDeviceInfo _paDevInfo;
|
||||||
|
|
||||||
virtual std::unique_ptr<DeviceInfo> clone() const override final {
|
virtual std::unique_ptr<DeviceInfo> clone() const override final
|
||||||
|
{
|
||||||
return std::make_unique<OurPaDeviceInfo>(*this);
|
return std::make_unique<OurPaDeviceInfo>(*this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void fillPortAudioDeviceInfo(DeviceInfoList &devinfolist) {
|
void fillPortAudioDeviceInfo(DeviceInfoList &devinfolist)
|
||||||
|
{
|
||||||
DEBUGTRACE_ENTER;
|
DEBUGTRACE_ENTER;
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
|
|
||||||
PaError err = Pa_Initialize();
|
PaError err = Pa_Initialize();
|
||||||
/// PortAudio says that Pa_Terminate() should not be called whenever there
|
/// PortAudio says that Pa_Terminate() should not be called whenever there
|
||||||
@ -47,24 +53,27 @@ void fillPortAudioDeviceInfo(DeviceInfoList &devinfolist) {
|
|||||||
/// of PortAudio show.
|
/// of PortAudio show.
|
||||||
throwIfError(err);
|
throwIfError(err);
|
||||||
|
|
||||||
auto fin = gsl::finally([&err] {
|
auto fin = gsl::finally([&err]
|
||||||
|
{
|
||||||
DEBUGTRACE_PRINT("Terminating PortAudio instance");
|
DEBUGTRACE_PRINT("Terminating PortAudio instance");
|
||||||
err = Pa_Terminate();
|
err = Pa_Terminate();
|
||||||
if (err != paNoError) {
|
if (err != paNoError) {
|
||||||
cerr << "Error terminating PortAudio. Do not know what to do." << endl;
|
cerr << "Error terminating PortAudio. Do not know what to do." << endl;
|
||||||
}
|
} });
|
||||||
});
|
|
||||||
|
|
||||||
/* const PaDeviceInfo *deviceInfo; */
|
/* const PaDeviceInfo *deviceInfo; */
|
||||||
const int numDevices = Pa_GetDeviceCount();
|
const int numDevices = Pa_GetDeviceCount();
|
||||||
if (numDevices < 0) {
|
if (numDevices < 0)
|
||||||
|
{
|
||||||
throw rte("PortAudio could not find any devices");
|
throw rte("PortAudio could not find any devices");
|
||||||
}
|
}
|
||||||
for (us i = 0; i < (us)numDevices; i++) {
|
for (us i = 0; i < (us)numDevices; i++)
|
||||||
|
{
|
||||||
/* DEBUGTRACE_PRINT(i); */
|
/* DEBUGTRACE_PRINT(i); */
|
||||||
|
|
||||||
const PaDeviceInfo *deviceInfo = Pa_GetDeviceInfo(i);
|
const PaDeviceInfo *deviceInfo = Pa_GetDeviceInfo(i);
|
||||||
if (!deviceInfo) {
|
if (!deviceInfo)
|
||||||
|
{
|
||||||
throw rte("No device info struct returned");
|
throw rte("No device info struct returned");
|
||||||
}
|
}
|
||||||
OurPaDeviceInfo d;
|
OurPaDeviceInfo d;
|
||||||
@ -100,7 +109,8 @@ void fillPortAudioDeviceInfo(DeviceInfoList &devinfolist) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (rte &e) {
|
catch (rte &e)
|
||||||
|
{
|
||||||
cerr << "PortAudio backend error: " << e.what() << std::endl;
|
cerr << "PortAudio backend error: " << e.what() << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -125,7 +135,8 @@ static int rawPaCallback(const void *inputBuffer, void *outputBuffer,
|
|||||||
const PaStreamCallbackTimeInfo *timeInfo,
|
const PaStreamCallbackTimeInfo *timeInfo,
|
||||||
PaStreamCallbackFlags statusFlags, void *userData);
|
PaStreamCallbackFlags statusFlags, void *userData);
|
||||||
|
|
||||||
class PortAudioDaq : public Daq {
|
class PortAudioDaq : public Daq
|
||||||
|
{
|
||||||
bool _shouldPaTerminate = false;
|
bool _shouldPaTerminate = false;
|
||||||
PaStream *_stream = nullptr;
|
PaStream *_stream = nullptr;
|
||||||
std::atomic<StreamStatus::StreamError> _streamError =
|
std::atomic<StreamStatus::StreamError> _streamError =
|
||||||
@ -162,11 +173,13 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<Daq> createPortAudioDevice(const DeviceInfo &devinfo,
|
std::unique_ptr<Daq> createPortAudioDevice(const DeviceInfo &devinfo,
|
||||||
const DaqConfiguration &config) {
|
const DaqConfiguration &config)
|
||||||
|
{
|
||||||
|
|
||||||
const OurPaDeviceInfo *_info =
|
const OurPaDeviceInfo *_info =
|
||||||
dynamic_cast<const OurPaDeviceInfo *>(&devinfo);
|
dynamic_cast<const OurPaDeviceInfo *>(&devinfo);
|
||||||
if (_info == nullptr) {
|
if (_info == nullptr)
|
||||||
|
{
|
||||||
throw rte("BUG: Could not cast DeviceInfo to OurPaDeviceInfo");
|
throw rte("BUG: Could not cast DeviceInfo to OurPaDeviceInfo");
|
||||||
}
|
}
|
||||||
return std::make_unique<PortAudioDaq>(*_info, config);
|
return std::make_unique<PortAudioDaq>(*_info, config);
|
||||||
@ -175,14 +188,16 @@ std::unique_ptr<Daq> createPortAudioDevice(const DeviceInfo &devinfo,
|
|||||||
static int rawPaCallback(const void *inputBuffer, void *outputBuffer,
|
static int rawPaCallback(const void *inputBuffer, void *outputBuffer,
|
||||||
unsigned long framesPerBuffer,
|
unsigned long framesPerBuffer,
|
||||||
const PaStreamCallbackTimeInfo *timeInfo,
|
const PaStreamCallbackTimeInfo *timeInfo,
|
||||||
PaStreamCallbackFlags statusFlags, void *userData) {
|
PaStreamCallbackFlags statusFlags, void *userData)
|
||||||
|
{
|
||||||
return static_cast<PortAudioDaq *>(userData)->memberPaCallback(
|
return static_cast<PortAudioDaq *>(userData)->memberPaCallback(
|
||||||
inputBuffer, outputBuffer, framesPerBuffer, timeInfo, statusFlags);
|
inputBuffer, outputBuffer, framesPerBuffer, timeInfo, statusFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
PortAudioDaq::PortAudioDaq(const OurPaDeviceInfo &devinfo_gen,
|
PortAudioDaq::PortAudioDaq(const OurPaDeviceInfo &devinfo_gen,
|
||||||
const DaqConfiguration &config)
|
const DaqConfiguration &config)
|
||||||
: Daq(devinfo_gen, config) {
|
: Daq(devinfo_gen, config)
|
||||||
|
{
|
||||||
|
|
||||||
DEBUGTRACE_ENTER;
|
DEBUGTRACE_ENTER;
|
||||||
PaError err = Pa_Initialize();
|
PaError err = Pa_Initialize();
|
||||||
@ -198,11 +213,13 @@ PortAudioDaq::PortAudioDaq(const OurPaDeviceInfo &devinfo_gen,
|
|||||||
// Going to find the device in the list. If its there, we have to retrieve
|
// Going to find the device in the list. If its there, we have to retrieve
|
||||||
// the index, as this is required in the PaStreamParameters struct
|
// the index, as this is required in the PaStreamParameters struct
|
||||||
int devindex = -1;
|
int devindex = -1;
|
||||||
for (int i = 0; i < Pa_GetDeviceCount(); i++) {
|
for (int i = 0; i < Pa_GetDeviceCount(); i++)
|
||||||
|
{
|
||||||
// DEBUGTRACE_PRINT(i);
|
// DEBUGTRACE_PRINT(i);
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
|
const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
|
||||||
if (!info) {
|
if (!info)
|
||||||
|
{
|
||||||
throw rte("No device structure returned from PortAudio");
|
throw rte("No device structure returned from PortAudio");
|
||||||
}
|
}
|
||||||
ok &= string(info->name) == devinfo_gen.device_name;
|
ok &= string(info->name) == devinfo_gen.device_name;
|
||||||
@ -211,11 +228,13 @@ PortAudioDaq::PortAudioDaq(const OurPaDeviceInfo &devinfo_gen,
|
|||||||
ok &= info->maxOutputChannels == devinfo_gen._paDevInfo.maxOutputChannels;
|
ok &= info->maxOutputChannels == devinfo_gen._paDevInfo.maxOutputChannels;
|
||||||
ok &= info->defaultSampleRate == devinfo_gen._paDevInfo.defaultSampleRate;
|
ok &= info->defaultSampleRate == devinfo_gen._paDevInfo.defaultSampleRate;
|
||||||
|
|
||||||
if (ok) {
|
if (ok)
|
||||||
|
{
|
||||||
devindex = i;
|
devindex = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (devindex < 0) {
|
if (devindex < 0)
|
||||||
|
{
|
||||||
throw rte(string("Device not found: ") + string(devinfo_gen.device_name));
|
throw rte(string("Device not found: ") + string(devinfo_gen.device_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,7 +242,8 @@ PortAudioDaq::PortAudioDaq(const OurPaDeviceInfo &devinfo_gen,
|
|||||||
const Dtype dtype = dataType();
|
const Dtype dtype = dataType();
|
||||||
// Sample format is bit flag
|
// Sample format is bit flag
|
||||||
PaSampleFormat format = paNonInterleaved;
|
PaSampleFormat format = paNonInterleaved;
|
||||||
switch (dtype) {
|
switch (dtype)
|
||||||
|
{
|
||||||
case Dtype::dtype_fl32:
|
case Dtype::dtype_fl32:
|
||||||
DEBUGTRACE_PRINT("Datatype float32");
|
DEBUGTRACE_PRINT("Datatype float32");
|
||||||
format |= paFloat32;
|
format |= paFloat32;
|
||||||
@ -252,18 +272,20 @@ PortAudioDaq::PortAudioDaq(const OurPaDeviceInfo &devinfo_gen,
|
|||||||
std::unique_ptr<PaStreamParameters> instreamParams;
|
std::unique_ptr<PaStreamParameters> instreamParams;
|
||||||
std::unique_ptr<PaStreamParameters> outstreamParams;
|
std::unique_ptr<PaStreamParameters> outstreamParams;
|
||||||
|
|
||||||
if (neninchannels() > 0) {
|
if (neninchannels() > 0)
|
||||||
|
{
|
||||||
instreamParams = std::make_unique<PaStreamParameters>(
|
instreamParams = std::make_unique<PaStreamParameters>(
|
||||||
PaStreamParameters({.device = devindex,
|
PaStreamParameters({.device = devindex,
|
||||||
.channelCount = (int)neninchannels(),
|
.channelCount = (int)getHighestEnabledInChannel() + 1,
|
||||||
.sampleFormat = format,
|
.sampleFormat = format,
|
||||||
.suggestedLatency = framesPerBlock() / samplerate(),
|
.suggestedLatency = framesPerBlock() / samplerate(),
|
||||||
.hostApiSpecificStreamInfo = nullptr}));
|
.hostApiSpecificStreamInfo = nullptr}));
|
||||||
}
|
}
|
||||||
if (nenoutchannels() > 0) {
|
if (nenoutchannels() > 0)
|
||||||
|
{
|
||||||
outstreamParams = std::make_unique<PaStreamParameters>(
|
outstreamParams = std::make_unique<PaStreamParameters>(
|
||||||
PaStreamParameters({.device = devindex,
|
PaStreamParameters({.device = devindex,
|
||||||
.channelCount = (int)nenoutchannels(),
|
.channelCount = (int)getHighestEnabledOutChannel() + 1,
|
||||||
.sampleFormat = format,
|
.sampleFormat = format,
|
||||||
.suggestedLatency = framesPerBlock() / samplerate(),
|
.suggestedLatency = framesPerBlock() / samplerate(),
|
||||||
.hostApiSpecificStreamInfo = nullptr}));
|
.hostApiSpecificStreamInfo = nullptr}));
|
||||||
@ -284,21 +306,26 @@ PortAudioDaq::PortAudioDaq(const OurPaDeviceInfo &devinfo_gen,
|
|||||||
throwIfError(err);
|
throwIfError(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PortAudioDaq::start(InDaqCallback inCallback, OutDaqCallback outCallback) {
|
void PortAudioDaq::start(InDaqCallback inCallback, OutDaqCallback outCallback)
|
||||||
|
{
|
||||||
DEBUGTRACE_ENTER;
|
DEBUGTRACE_ENTER;
|
||||||
assert(_stream);
|
assert(_stream);
|
||||||
if (Pa_IsStreamActive(_stream)) {
|
if (Pa_IsStreamActive(_stream))
|
||||||
|
{
|
||||||
throw rte("Stream is already running");
|
throw rte("Stream is already running");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logical XOR
|
// Logical XOR
|
||||||
if (inCallback && outCallback) {
|
if (inCallback && outCallback)
|
||||||
|
{
|
||||||
throw rte("Either input or output stream possible for RtAudio. "
|
throw rte("Either input or output stream possible for RtAudio. "
|
||||||
"Stream duplex mode not provided.");
|
"Stream duplex mode not provided.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (neninchannels() > 0) {
|
if (neninchannels() > 0)
|
||||||
if (!inCallback) {
|
{
|
||||||
|
if (!inCallback)
|
||||||
|
{
|
||||||
throw rte(
|
throw rte(
|
||||||
|
|
||||||
"Input callback given, but stream does not provide input data");
|
"Input callback given, but stream does not provide input data");
|
||||||
@ -306,8 +333,10 @@ void PortAudioDaq::start(InDaqCallback inCallback, OutDaqCallback outCallback) {
|
|||||||
|
|
||||||
_incallback = inCallback;
|
_incallback = inCallback;
|
||||||
}
|
}
|
||||||
if (nenoutchannels() > 0) {
|
if (nenoutchannels() > 0)
|
||||||
if (!outCallback) {
|
{
|
||||||
|
if (!outCallback)
|
||||||
|
{
|
||||||
throw rte(
|
throw rte(
|
||||||
"Output callback given, but stream does not provide output data");
|
"Output callback given, but stream does not provide output data");
|
||||||
}
|
}
|
||||||
@ -317,46 +346,57 @@ void PortAudioDaq::start(InDaqCallback inCallback, OutDaqCallback outCallback) {
|
|||||||
PaError err = Pa_StartStream(_stream);
|
PaError err = Pa_StartStream(_stream);
|
||||||
throwIfError(err);
|
throwIfError(err);
|
||||||
}
|
}
|
||||||
void PortAudioDaq::stop() {
|
void PortAudioDaq::stop()
|
||||||
|
{
|
||||||
DEBUGTRACE_ENTER;
|
DEBUGTRACE_ENTER;
|
||||||
assert(_stream);
|
assert(_stream);
|
||||||
if (Pa_IsStreamStopped(_stream)) {
|
if (Pa_IsStreamStopped(_stream))
|
||||||
|
{
|
||||||
throw rte("Stream is already stopped");
|
throw rte("Stream is already stopped");
|
||||||
}
|
}
|
||||||
PaError err = Pa_StopStream(_stream);
|
PaError err = Pa_StopStream(_stream);
|
||||||
throwIfError(err);
|
throwIfError(err);
|
||||||
}
|
}
|
||||||
Daq::StreamStatus PortAudioDaq::getStreamStatus() const {
|
Daq::StreamStatus PortAudioDaq::getStreamStatus() const
|
||||||
|
{
|
||||||
Daq::StreamStatus status;
|
Daq::StreamStatus status;
|
||||||
// Copy over atomic flag.
|
// Copy over atomic flag.
|
||||||
status.errorType = _streamError;
|
status.errorType = _streamError;
|
||||||
// Check if stream is still running.
|
// Check if stream is still running.
|
||||||
if (_stream) {
|
if (_stream)
|
||||||
if (Pa_IsStreamActive(_stream)) {
|
{
|
||||||
|
if (Pa_IsStreamActive(_stream))
|
||||||
|
{
|
||||||
status.isRunning = true;
|
status.isRunning = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
PortAudioDaq::~PortAudioDaq() {
|
PortAudioDaq::~PortAudioDaq()
|
||||||
|
{
|
||||||
PaError err;
|
PaError err;
|
||||||
if (_stream) {
|
if (_stream)
|
||||||
if (Pa_IsStreamActive(_stream)) {
|
{
|
||||||
|
if (Pa_IsStreamActive(_stream))
|
||||||
|
{
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
err = Pa_CloseStream(_stream);
|
err = Pa_CloseStream(_stream);
|
||||||
_stream = nullptr;
|
_stream = nullptr;
|
||||||
if (err != paNoError) {
|
if (err != paNoError)
|
||||||
|
{
|
||||||
cerr << "Error closing PortAudio stream. Do not know what to do." << endl;
|
cerr << "Error closing PortAudio stream. Do not know what to do." << endl;
|
||||||
}
|
}
|
||||||
assert(_shouldPaTerminate);
|
assert(_shouldPaTerminate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_shouldPaTerminate) {
|
if (_shouldPaTerminate)
|
||||||
|
{
|
||||||
err = Pa_Terminate();
|
err = Pa_Terminate();
|
||||||
if (err != paNoError) {
|
if (err != paNoError)
|
||||||
|
{
|
||||||
cerr << "Error terminating PortAudio. Do not know what to do." << endl;
|
cerr << "Error terminating PortAudio. Do not know what to do." << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -364,23 +404,28 @@ PortAudioDaq::~PortAudioDaq() {
|
|||||||
int PortAudioDaq::memberPaCallback(const void *inputBuffer, void *outputBuffer,
|
int PortAudioDaq::memberPaCallback(const void *inputBuffer, void *outputBuffer,
|
||||||
unsigned long framesPerBuffer,
|
unsigned long framesPerBuffer,
|
||||||
const PaStreamCallbackTimeInfo *timeInfo,
|
const PaStreamCallbackTimeInfo *timeInfo,
|
||||||
PaStreamCallbackFlags statusFlags) {
|
PaStreamCallbackFlags statusFlags)
|
||||||
|
{
|
||||||
|
|
||||||
DEBUGTRACE_ENTER;
|
DEBUGTRACE_ENTER;
|
||||||
typedef Daq::StreamStatus::StreamError se;
|
typedef Daq::StreamStatus::StreamError se;
|
||||||
if (statusFlags & paPrimingOutput) {
|
if (statusFlags & paPrimingOutput)
|
||||||
|
{
|
||||||
// Initial output buffers generated. So nothing with input yet
|
// Initial output buffers generated. So nothing with input yet
|
||||||
return paContinue;
|
return paContinue;
|
||||||
}
|
}
|
||||||
if ((statusFlags & paInputUnderflow) || (statusFlags & paInputOverflow)) {
|
if ((statusFlags & paInputUnderflow) || (statusFlags & paInputOverflow))
|
||||||
|
{
|
||||||
_streamError = se::inputXRun;
|
_streamError = se::inputXRun;
|
||||||
return paAbort;
|
return paAbort;
|
||||||
}
|
}
|
||||||
if ((statusFlags & paOutputUnderflow) || (statusFlags & paOutputOverflow)) {
|
if ((statusFlags & paOutputUnderflow) || (statusFlags & paOutputOverflow))
|
||||||
|
{
|
||||||
_streamError = se::outputXRun;
|
_streamError = se::outputXRun;
|
||||||
return paAbort;
|
return paAbort;
|
||||||
}
|
}
|
||||||
if (framesPerBuffer != framesPerBlock()) {
|
if (framesPerBuffer != framesPerBlock())
|
||||||
|
{
|
||||||
cerr << "Logic error: expected a block size of: " << framesPerBlock()
|
cerr << "Logic error: expected a block size of: " << framesPerBlock()
|
||||||
<< endl;
|
<< endl;
|
||||||
_streamError = se::logicError;
|
_streamError = se::logicError;
|
||||||
@ -392,7 +437,8 @@ int PortAudioDaq::memberPaCallback(const void *inputBuffer, void *outputBuffer,
|
|||||||
const auto &dtype_descr = dtypeDescr();
|
const auto &dtype_descr = dtypeDescr();
|
||||||
const auto dtype = dataType();
|
const auto dtype = dataType();
|
||||||
const us sw = dtype_descr.sw;
|
const us sw = dtype_descr.sw;
|
||||||
if (inputBuffer) {
|
if (inputBuffer)
|
||||||
|
{
|
||||||
assert(_incallback);
|
assert(_incallback);
|
||||||
std::vector<byte_t *> ptrs;
|
std::vector<byte_t *> ptrs;
|
||||||
ptrs.reserve(neninchannels);
|
ptrs.reserve(neninchannels);
|
||||||
@ -404,8 +450,10 @@ int PortAudioDaq::memberPaCallback(const void *inputBuffer, void *outputBuffer,
|
|||||||
|
|
||||||
/// Only pass on the pointers of the channels we want. inputBuffer is
|
/// Only pass on the pointers of the channels we want. inputBuffer is
|
||||||
/// noninterleaved, as specified in PortAudioDaq constructor.
|
/// noninterleaved, as specified in PortAudioDaq constructor.
|
||||||
for (us ch = ch_min; ch <= ch_max; ch++) {
|
for (us ch = ch_min; ch <= ch_max; ch++)
|
||||||
if (inchannel_config.at(ch).enabled) {
|
{
|
||||||
|
if (inchannel_config.at(ch).enabled)
|
||||||
|
{
|
||||||
byte_t *ch_ptr =
|
byte_t *ch_ptr =
|
||||||
reinterpret_cast<byte_t **>(const_cast<void *>(inputBuffer))[ch];
|
reinterpret_cast<byte_t **>(const_cast<void *>(inputBuffer))[ch];
|
||||||
ptrs.push_back(ch_ptr);
|
ptrs.push_back(ch_ptr);
|
||||||
@ -417,7 +465,8 @@ int PortAudioDaq::memberPaCallback(const void *inputBuffer, void *outputBuffer,
|
|||||||
_incallback(d);
|
_incallback(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outputBuffer) {
|
if (outputBuffer)
|
||||||
|
{
|
||||||
assert(_outcallback);
|
assert(_outcallback);
|
||||||
std::vector<byte_t *> ptrs;
|
std::vector<byte_t *> ptrs;
|
||||||
ptrs.reserve(nenoutchannels);
|
ptrs.reserve(nenoutchannels);
|
||||||
@ -429,8 +478,10 @@ int PortAudioDaq::memberPaCallback(const void *inputBuffer, void *outputBuffer,
|
|||||||
assert(ch_min < noutchannels);
|
assert(ch_min < noutchannels);
|
||||||
assert(ch_max < noutchannels);
|
assert(ch_max < noutchannels);
|
||||||
/// Only pass on the pointers of the channels we want
|
/// Only pass on the pointers of the channels we want
|
||||||
for (us ch = ch_min; ch <= ch_max; ch++) {
|
for (us ch = ch_min; ch <= ch_max; ch++)
|
||||||
if (outchannel_config.at(ch).enabled) {
|
{
|
||||||
|
if (outchannel_config.at(ch).enabled)
|
||||||
|
{
|
||||||
byte_t *ch_ptr = reinterpret_cast<byte_t **>(outputBuffer)[ch];
|
byte_t *ch_ptr = reinterpret_cast<byte_t **>(outputBuffer)[ch];
|
||||||
ptrs.push_back(ch_ptr);
|
ptrs.push_back(ch_ptr);
|
||||||
}
|
}
|
||||||
@ -440,7 +491,8 @@ int PortAudioDaq::memberPaCallback(const void *inputBuffer, void *outputBuffer,
|
|||||||
_outcallback(d);
|
_outcallback(d);
|
||||||
// Copy over the buffer
|
// Copy over the buffer
|
||||||
us j = 0;
|
us j = 0;
|
||||||
for (auto ptr : ptrs) {
|
for (auto ptr : ptrs)
|
||||||
|
{
|
||||||
d.copyToRaw(j, ptr);
|
d.copyToRaw(j, ptr);
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
@ -22,23 +22,37 @@ classifiers = [
|
|||||||
]
|
]
|
||||||
urls = { "Documentation" = "https://lasp.ascee.nl" }
|
urls = { "Documentation" = "https://lasp.ascee.nl" }
|
||||||
|
|
||||||
dependencies = ["scipy", "numpy", "matplotlib>=3.7.2", "appdirs",
|
dependencies = [
|
||||||
"dataclasses_json", "h5py"]
|
"scipy",
|
||||||
|
"numpy",
|
||||||
|
"matplotlib>=3.7.2",
|
||||||
|
"appdirs",
|
||||||
|
"dataclasses_json",
|
||||||
|
"h5py",
|
||||||
|
]
|
||||||
|
|
||||||
[build-system] # How pip and other frontends should build this project
|
[build-system] # How pip and other frontends should build this project
|
||||||
requires = ["py-build-cmake~=0.1.8", "pybind11" ]
|
requires = ["py-build-cmake~=0.1.8", "pybind11"]
|
||||||
build-backend = "py_build_cmake.build"
|
build-backend = "py_build_cmake.build"
|
||||||
|
|
||||||
[tool.py-build-cmake.module] # Where to find the Python module to package
|
[tool.py-build-cmake.module] # Where to find the Python module to package
|
||||||
directory = "python_src"
|
directory = "python_src"
|
||||||
|
|
||||||
[tool.py-build-cmake.sdist] # What to include in source distributions
|
[tool.py-build-cmake.sdist] # What to include in source distributions
|
||||||
include = ["CMakeLists.txt", "cmake", "cpp_src", "python_src", "img", "scripts",
|
include = [
|
||||||
"third_party"]
|
"CMakeLists.txt",
|
||||||
|
"cmake",
|
||||||
|
"cpp_src",
|
||||||
|
"python_src",
|
||||||
|
"img",
|
||||||
|
"scripts",
|
||||||
|
"third_party",
|
||||||
|
]
|
||||||
|
|
||||||
[tool.py-build-cmake.cmake] # How to build the CMake project
|
[tool.py-build-cmake.cmake] # How to build the CMake project
|
||||||
build_type = "Release"
|
build_type = "Release"
|
||||||
source_path = "."
|
source_path = "."
|
||||||
|
options = { "LASP_HAS_PORTAUDIO" = "ON", "LASP_HAS_RTAUDIO" = "OFF" }
|
||||||
build_args = ["-j12"]
|
build_args = ["-j12"]
|
||||||
install_components = ["python_modules"]
|
install_components = ["python_modules"]
|
||||||
|
|
||||||
|
2
third_party/rtaudio
vendored
2
third_party/rtaudio
vendored
@ -1 +1 @@
|
|||||||
Subproject commit b4f04903312e0e0efffbe77655172e0f060dc085
|
Subproject commit 46b01b5b134f33d8ddc3dab76829d4b1350e0522
|
Loading…
Reference in New Issue
Block a user