You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
121 lines
3.6 KiB
121 lines
3.6 KiB
#include "PortAudioProducer.h" |
|
|
|
PortAudioProducer::PortAudioProducer(Settings *settings, AudioQueue *audioQueue) : sys(portaudio::System::instance()), settings(settings), audioQueue(audioQueue) |
|
{ |
|
XOJ_INIT_TYPE(PortAudioProducer); |
|
|
|
DeviceInfo inputInfo(&sys.defaultInputDevice(), true); |
|
this->setInputDevice(inputInfo); |
|
} |
|
|
|
PortAudioProducer::~PortAudioProducer() |
|
{ |
|
XOJ_CHECK_TYPE(PortAudioProducer); |
|
|
|
portaudio::System::terminate(); |
|
|
|
XOJ_RELEASE_TYPE(PortAudioProducer); |
|
} |
|
|
|
std::list<DeviceInfo> PortAudioProducer::getInputDevices() |
|
{ |
|
XOJ_CHECK_TYPE(PortAudioProducer); |
|
|
|
std::list<DeviceInfo> deviceList; |
|
|
|
for (portaudio::System::DeviceIterator i = this->sys.devicesBegin(); i != sys.devicesEnd(); ++i) |
|
{ |
|
|
|
if (i->isFullDuplexDevice() || i->isInputOnlyDevice()) |
|
{ |
|
DeviceInfo deviceInfo(&(*i), this->selectedInputDevice == i->index()); |
|
deviceList.push_back(deviceInfo); |
|
} |
|
|
|
} |
|
return deviceList; |
|
} |
|
|
|
const DeviceInfo PortAudioProducer::getSelectedInputDevice() |
|
{ |
|
XOJ_CHECK_TYPE(PortAudioProducer); |
|
|
|
return DeviceInfo(&sys.deviceByIndex(this->selectedInputDevice), true); |
|
} |
|
|
|
void PortAudioProducer::setInputDevice(DeviceInfo deviceInfo) |
|
{ |
|
XOJ_CHECK_TYPE(PortAudioProducer); |
|
|
|
this->selectedInputDevice = deviceInfo.getIndex(); |
|
portaudio::Device *device = &sys.deviceByIndex(this->selectedInputDevice); |
|
this->inputChannels = static_cast<unsigned int>(device->maxInputChannels()); |
|
} |
|
|
|
bool PortAudioProducer::isRecording() |
|
{ |
|
XOJ_CHECK_TYPE(PortAudioProducer); |
|
|
|
return this->inputStream != nullptr && this->inputStream->isActive(); |
|
} |
|
|
|
void PortAudioProducer::startRecording() |
|
{ |
|
XOJ_CHECK_TYPE(PortAudioProducer); |
|
|
|
// Check if there already is a recording |
|
if (this->inputStream != nullptr) |
|
{ |
|
return; |
|
} |
|
|
|
// Get the device information of our input device |
|
portaudio::Device *device = &sys.deviceByIndex(this->selectedInputDevice); |
|
portaudio::DirectionSpecificStreamParameters inParams(*device, device->maxInputChannels(), portaudio::INT32, true, device->defaultLowInputLatency(), nullptr); |
|
portaudio::StreamParameters params(inParams, portaudio::DirectionSpecificStreamParameters::null(), this->sampleRate, this->framesPerBuffer, paNoFlag); |
|
|
|
// Specify the callback used for buffering the recorded data |
|
this->inputStream = new portaudio::MemFunCallbackStream<PortAudioProducer>(params, *this, &PortAudioProducer::recordCallback); |
|
|
|
// Start the recording |
|
this->inputStream->start(); |
|
} |
|
|
|
int PortAudioProducer::recordCallback(const void* inputBuffer, void* outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, |
|
PaStreamCallbackFlags statusFlags) |
|
{ |
|
XOJ_CHECK_TYPE(PortAudioProducer); |
|
std::unique_lock<std::mutex> lock(this->audioQueue->syncMutex()); |
|
|
|
if (statusFlags) |
|
{ |
|
g_message("PortAudioProducer: statusFlag: %s", std::to_string(statusFlags).c_str()); |
|
} |
|
|
|
if (inputBuffer != nullptr) |
|
{ |
|
unsigned long providedFrames = framesPerBuffer * this->inputChannels; |
|
|
|
this->audioQueue->push(((int *) inputBuffer), providedFrames); |
|
} |
|
return paContinue; |
|
} |
|
|
|
void PortAudioProducer::stopRecording() |
|
{ |
|
XOJ_CHECK_TYPE(PortAudioProducer); |
|
|
|
// Stop the recording |
|
if (this->inputStream != nullptr) |
|
{ |
|
this->inputStream->stop(); |
|
this->inputStream->close(); |
|
} |
|
|
|
// Notify the consumer at the other side that ther will be no more data |
|
this->audioQueue->signalEndOfStream(); |
|
|
|
// Allow new recording by removing the old one |
|
delete this->inputStream; |
|
this->inputStream = nullptr; |
|
}
|
|
|