Fix travis missing libraries for portaudio and sox

Make attributes of AudioQueue private and hide functionality in methods
Add braces to all loops and conditions
presentation
Ulrich Huber 7 years ago
parent d417619c26
commit b5db134170
  1. 2
      .travis.yml
  2. 30
      src/util/audio/AudioQueue.cpp
  3. 7
      src/util/audio/AudioQueue.h
  4. 4
      src/util/audio/AudioRecorder.cpp
  5. 10
      src/util/audio/PortAudioProducer.cpp
  6. 18
      src/util/audio/SoxConsumer.cpp

@ -28,6 +28,8 @@ addons:
- libgtk-3-dev
- libpoppler-glib-dev
- libportaudio-dev
- libsox-dev
coverity_scan:
project:

@ -3,6 +3,7 @@
AudioQueue::AudioQueue()
{
XOJ_INIT_TYPE(AudioQueue);
this->lock = std::unique_lock<std::mutex>(this->queueLock);
}
AudioQueue::~AudioQueue()
@ -42,16 +43,25 @@ void AudioQueue::push(int *samples, unsigned long nSamples)
unsigned long requiredSize = this->size() + nSamples;
if (this->max_size() < requiredSize)
{
this->resize(requiredSize);
}
for (long i = nSamples - 1; i >= 0; i--)
{
this->push_front(samples[i]);
}
this->notified = true;
this->lockCondition.notify_one();
}
std::vector<int> AudioQueue::pop(unsigned long nSamples)
{
XOJ_CHECK_TYPE(AudioQueue);
this->notified = false;
std::vector<int> buffer(nSamples);
for (long i = nSamples - 1; i >= 0; i--)
{
@ -60,3 +70,23 @@ std::vector<int> AudioQueue::pop(unsigned long nSamples)
}
return buffer;
}
void AudioQueue::signalEndOfStream()
{
this->streamEnd = true;
this->notified = true;
this->lockCondition.notify_one();
}
void AudioQueue::waitForNewElements()
{
while (!this->notified)
{
this->lockCondition.wait(this->lock);
}
}
bool AudioQueue::hasStreamEnded()
{
return this->streamEnd;
}

@ -23,13 +23,20 @@ class AudioQueue : protected std::deque<int>
public:
AudioQueue();
~AudioQueue();
void reset();
bool empty();
unsigned long size();
void push(int *samples, unsigned long nSamples);
std::vector<int> pop(unsigned long nSamples);
void signalEndOfStream();
void waitForNewElements();
bool hasStreamEnded();
private:
std::mutex queueLock;
std::unique_lock<std::mutex> lock;
std::condition_variable lockCondition;
bool streamEnd = false;
bool notified = false;

@ -1,3 +1,5 @@
#include <utility>
#include "AudioRecorder.h"
AudioRecorder::AudioRecorder(Settings *settings) : settings(settings)
@ -31,7 +33,7 @@ void AudioRecorder::start(std::string filename)
// Start the consumer for writing the data
// TODO get sample rate from settings
this->soxConsumer->start(filename, 44100.0, this->portAudioProducer->getSelectedInputDevice());
this->soxConsumer->start(std::move(filename), 44100.0, this->portAudioProducer->getSelectedInputDevice());
// Start recording
this->portAudioProducer->startRecording();

@ -64,7 +64,9 @@ void PortAudioProducer::startRecording()
// 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);
@ -90,13 +92,9 @@ int PortAudioProducer::recordCallback(const void *inputBuffer, void *outputBuffe
if (inputBuffer != nullptr)
{
std::unique_lock<std::mutex> lock(this->audioQueue->queueLock);
unsigned long providedFrames = framesPerBuffer * this->inputChannels;
this->audioQueue->push(((int *) inputBuffer), providedFrames);
this->audioQueue->notified = true;
this->audioQueue->lockCondition.notify_one();
}
return paContinue;
}
@ -113,9 +111,7 @@ void PortAudioProducer::stopRecording()
}
// Notify the consumer at the other side that ther will be no more data
this->audioQueue->streamEnd = true;
this->audioQueue->notified = true;
this->audioQueue->lockCondition.notify_one();
this->audioQueue->signalEndOfStream();
// Allow new recording by removing the old one
delete this->inputStream;

@ -39,16 +39,11 @@ void SoxConsumer::start(std::string filename, double sampleRate, const DeviceInf
this->consumerThread = new std::thread([&]
{
std::unique_lock<std::mutex> lock(audioQueue->queueLock);
unsigned long availableFrames;
while (!(this->stopConsumer || (audioQueue->streamEnd && audioQueue->empty())))
while (!(this->stopConsumer || (audioQueue->hasStreamEnded() && audioQueue->empty())))
{
while (!audioQueue->notified)
{
audioQueue->lockCondition.wait(lock);
}
audioQueue->waitForNewElements();
while (!audioQueue->empty())
{
@ -60,7 +55,6 @@ void SoxConsumer::start(std::string filename, double sampleRate, const DeviceInf
sox_write(this->outputFile, tmpBuffer.data(), availableFrames);
}
}
audioQueue->notified = false;
}
sox_close(this->outputFile);
@ -75,7 +69,9 @@ void SoxConsumer::join()
// Join the consumer thread to wait for completion
if (this->consumerThread->joinable())
{
this->consumerThread->join();
}
}
void SoxConsumer::stop()
@ -83,12 +79,12 @@ void SoxConsumer::stop()
XOJ_CHECK_TYPE(SoxConsumer);
// Stop consumer
this->stopConsumer = true;
this->audioQueue->notified = true;
this->audioQueue->lockCondition.notify_one();
this->audioQueue->signalEndOfStream();
// Wait for consumer to finish
if (this->consumerThread->joinable())
{
this->consumerThread->join();
}
}

Loading…
Cancel
Save