diff --git a/src/media/audio/audiorecorder.cpp b/src/media/audio/audiorecorder.cpp index 06ec53e3408ced93f9a5c2417e25f108c5998531..2058d55862bf233deb5fb6a91c537b5c9304f568 100644 --- a/src/media/audio/audiorecorder.cpp +++ b/src/media/audio/audiorecorder.cpp @@ -2,6 +2,7 @@ * Copyright (C) 2004-2015 Savoir-faire Linux Inc. * * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> + * Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,74 +22,70 @@ #include "audiorecorder.h" #include "audiorecord.h" #include "ringbufferpool.h" -#include "logger.h" +#include "audiobuffer.h" #include <chrono> +#include <thread> #include <sstream> -#include <unistd.h> +#include <algorithm> // std::min namespace ring { -int AudioRecorder::count_ = 0; - -AudioRecorder::AudioRecorder(AudioRecord *arec, RingBufferPool &rbp) - : recorderId_(), ringBufferPool_(rbp), arecord_(arec), running_(false) - , thread_() +static constexpr std::size_t BUFFER_LENGTH {10000}; +static constexpr std::chrono::milliseconds SLEEP_TIME {20}; + +AudioRecorder::AudioRecorder(AudioRecord* arec, RingBufferPool& rbp) + : ringBufferPool_(rbp) + , buffer_(new AudioBuffer(BUFFER_LENGTH, ringBufferPool_.getInternalAudioFormat())) + , arecord_(arec) + , thread_( + [this] { return true; }, + [this] { process(); }, + [] {}) { - ++count_; - - std::string id("processid_"); + std::string id("processd_"); // convert count into string std::string s; std::ostringstream out; - out << count_; + out << nextProcessID(); s = out.str(); recorderId_ = id.append(s); } -AudioRecorder::~AudioRecorder() +unsigned +AudioRecorder::nextProcessID() noexcept { - running_ = false; - - if (thread_.joinable()) - thread_.join(); + static unsigned id = 0; + return ++id; } -void AudioRecorder::init() { - if (!arecord_->isRecording()) { +void +AudioRecorder::init() { + if (!arecord_->isRecording()) arecord_->setSndFormat(ringBufferPool_.getInternalAudioFormat()); - } } -void AudioRecorder::start() +void +AudioRecorder::start() { - if (running_) return; - running_ = true; - thread_ = std::thread(&AudioRecorder::run, this); + if (thread_.isRunning()) + return; + thread_.start(); } -/** - * Reimplementation of run() - */ -void AudioRecorder::run() +void +AudioRecorder::process() { - static const size_t BUFFER_LENGTH = 10000; - static const std::chrono::milliseconds SLEEP_TIME(20); // 20 ms - - AudioBuffer buffer(BUFFER_LENGTH, ringBufferPool_.getInternalAudioFormat()); - - while (running_) { - const size_t availableSamples = ringBufferPool_.availableForGet(recorderId_); - buffer.resize(std::min(availableSamples, BUFFER_LENGTH)); - ringBufferPool_.getData(buffer, recorderId_); + auto availableSamples = ringBufferPool_.availableForGet(recorderId_); + buffer_->resize(std::min(availableSamples, BUFFER_LENGTH)); + ringBufferPool_.getData(*buffer_, recorderId_); - if (availableSamples > 0) - arecord_->recData(buffer); + if (availableSamples > 0) + arecord_->recData(*buffer_); - std::this_thread::sleep_for(SLEEP_TIME); - } + std::this_thread::sleep_for(SLEEP_TIME); } } // namespace ring diff --git a/src/media/audio/audiorecorder.h b/src/media/audio/audiorecorder.h index 9878ff1d7b4ddfb7411c97e53d2c8f26d067708f..e9688227f630dc59c818bf706406b65eab7db0f0 100644 --- a/src/media/audio/audiorecorder.h +++ b/src/media/audio/audiorecorder.h @@ -1,7 +1,8 @@ /* * Copyright (C) 2004-2015 Savoir-faire Linux Inc. * - * Alexandre Savard <alexandre.savard@savoirfairelinux.com> + * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> + * Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,52 +19,49 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef AUDIORECORDER_H_ -#define AUDIORECORDER_H_ +#pragma once +#include "threadloop.h" #include "noncopyable.h" -#include <thread> -#include <atomic> #include <string> +#include <memory> namespace ring { class RingBufferPool; class AudioRecord; +class AudioBuffer; class AudioRecorder { +public: + AudioRecorder(AudioRecord* arec, RingBufferPool& rbp); - public: - AudioRecorder(AudioRecord *arec, RingBufferPool &rbp); - ~AudioRecorder(); - std::string getRecorderID() const { - return recorderId_; - } + std::string getRecorderID() const noexcept { + return recorderId_; + } - /** - * Set the record to the current audio format. - * Should be called before start() at least once. - */ - void init(); + /** + * Set the record to the current audio format. + * Should be called before start() at least once. + */ + void init(); - /** - * Call to start recording. - */ - void start(); + /** + * Call to start recording. + */ + void start(); - private: - NON_COPYABLE(AudioRecorder); - void run(); +private: + NON_COPYABLE(AudioRecorder); + static unsigned nextProcessID() noexcept; + void process(); - static int count_; - std::string recorderId_; - RingBufferPool &ringBufferPool_; - AudioRecord *arecord_; - std::atomic<bool> running_; - std::thread thread_; + std::string recorderId_; + RingBufferPool& ringBufferPool_; + std::unique_ptr<AudioBuffer> buffer_; + AudioRecord* arecord_; + ThreadLoop thread_; }; } // namespace ring - -#endif