Commit dbc4ace9 authored by Guillaume Roguez's avatar Guillaume Roguez

audiorecorder: use ThreadLoop

Use our integrated threadloop class than re-invent the weel.
Also cleanup code using modern C++.

Issue: #79703
Change-Id: Ibc3b0da9d0d24b4fc17950b946c1c3b9f134cdc5
parent 5236ab05
......@@ -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
/*
* 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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment