Commit 8f8eb254 authored by Guillaume Roguez's avatar Guillaume Roguez

media: make recordable non audio dedicated

To add video recording this patch changes recordable and
audio related class non-dependent.
This moves AudioRecorder handling into AudioRecord class.

Fixes also Audio recording start/stop that not working as waited:
- first start was just creating the file
- recording was started at second "toggle", confusing user.


Change-Id: I07f69b76ad711d7fc4d64e57e78b5704d60b4861
Tuleap: #337
parent 4c71686e
......@@ -26,7 +26,7 @@
#include "audio/ringbufferpool.h"
#include "dring/call_const.h"
#include "client/ring_signal.h"
#include "audio/audiorecorder.h"
#include "audio/audiorecord.h"
#include "sip/sip_utils.h"
#include "ip_utils.h"
#include "array_size.h"
......@@ -260,14 +260,12 @@ bool
Call::toggleRecording()
{
const bool startRecording = Recordable::toggleRecording();
std::string process_id = Recordable::recAudio_->getRecorderID();
RingBufferPool &rbPool = Manager::instance().getRingBufferPool();
std::string process_id = Recordable::recorder_->getRecorderID();
if (startRecording) {
rbPool.bindHalfDuplexOut(process_id, id_);
rbPool.bindHalfDuplexOut(process_id, RingBufferPool::DEFAULT_ID);
Recordable::recorder_->start();
} else {
rbPool.unBindHalfDuplexOut(process_id, id_);
rbPool.unBindHalfDuplexOut(process_id, RingBufferPool::DEFAULT_ID);
......
......@@ -25,7 +25,7 @@
#include "manager.h"
#include "audio/audiolayer.h"
#include "audio/ringbufferpool.h"
#include "audio/audiorecorder.h"
#include "audio/audiorecord.h"
#ifdef RING_VIDEO
#include "sip/sipcall.h"
......@@ -148,18 +148,15 @@ Conference::getDisplayNames() const
bool Conference::toggleRecording()
{
const bool startRecording = Recordable::toggleRecording();
std::string process_id(Recordable::recAudio_->getRecorderID());
auto& rbPool = Manager::instance().getRingBufferPool();
std::string process_id(Recordable::recorder_->getRecorderID());
// start recording
if (startRecording) {
for (const auto &item : participants_)
rbPool.bindHalfDuplexOut(process_id, item);
rbPool.bindHalfDuplexOut(process_id, RingBufferPool::DEFAULT_ID);
Recordable::recorder_->start();
} else {
for (const auto &item : participants_)
rbPool.unBindHalfDuplexOut(process_id, item);
......
......@@ -1125,7 +1125,7 @@ Manager::joinParticipant(const std::string& callId1,
conf->setState(Conference::ACTIVE_ATTACHED);
// set recording sampling rate
conf->setRecordingFormat(ringbufferpool_->getInternalAudioFormat());
conf->setRecordingAudioFormat(ringbufferpool_->getInternalAudioFormat());
return true;
}
......@@ -1166,7 +1166,7 @@ Manager::createConfFromParticipantList(const std::vector< std::string > &partici
if (successCounter >= 2) {
conferenceMap_[conf->getConfID()] = conf;
emitSignal<DRing::CallSignal::ConferenceCreated>(conf->getConfID());
conf->setRecordingFormat(ringbufferpool_->getInternalAudioFormat());
conf->setRecordingAudioFormat(ringbufferpool_->getInternalAudioFormat());
}
}
......@@ -2110,7 +2110,7 @@ Manager::toggleRecordingCall(const std::string& id)
}
const bool result = rec->toggleRecording();
emitSignal<DRing::CallSignal::RecordPlaybackFilepath>(id, rec->getFilename());
emitSignal<DRing::CallSignal::RecordPlaybackFilepath>(id, rec->getAudioFilename());
emitSignal<DRing::CallSignal::RecordingStateChanged>(id, result);
return result;
}
......
/*
* Copyright (C) 2004-2015 Savoir-faire Linux Inc.
* Copyright (C) 2004-2016 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
......@@ -25,6 +26,7 @@
#include "audiorecord.h"
#include "logger.h"
#include "fileutils.h"
#include "manager.h"
#include <sndfile.hh>
......@@ -80,10 +82,16 @@ AudioRecord::AudioRecord()
: sndFormat_(AudioFormat::MONO())
, filename_(createFilename())
, savePath_()
, recorder_(this, Manager::instance().getRingBufferPool())
{
RING_DBG("Generate filename for this call %s ", filename_.c_str());
}
AudioRecord::~AudioRecord()
{
closeFile();
}
void AudioRecord::setSndFormat(AudioFormat format)
{
sndFormat_ = format;
......@@ -141,7 +149,6 @@ AudioRecord::openFile()
{
fileHandle_.reset(); // do it before calling fileExists()
bool result = false;
const bool doAppend = fileExists();
const int access = doAppend ? SFM_RDWR : SFM_WRITE;
......@@ -162,7 +169,7 @@ AudioRecord::openFile()
if (doAppend and fileHandle_->seek(0, SEEK_END) < 0)
RING_WARN("Couldn't seek to the end of the file ");
return result;
return true;
}
void
......@@ -193,8 +200,10 @@ AudioRecord::toggleRecording()
{
if (isOpenFile())
recordingEnabled_ = !recordingEnabled_;
else if (openFile())
else if (openFile()) {
recordingEnabled_ = true;
recorder_.start();
}
return recordingEnabled_;
}
......@@ -202,7 +211,7 @@ AudioRecord::toggleRecording()
void
AudioRecord::stopRecording() const noexcept
{
RING_DBG("Stop recording");
RING_DBG("Stop recording %s", savePath_.c_str());
recordingEnabled_ = false;
}
......
/*
* Copyright (C) 2004-2015 Savoir-faire Linux Inc.
* Copyright (C) 2004-2016 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
......@@ -18,10 +19,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _AUDIO_RECORD_H
#define _AUDIO_RECORD_H
#pragma once
#include "audiobuffer.h"
#include "audiorecorder.h"
#include "noncopyable.h"
#include <atomic>
......@@ -36,6 +37,7 @@ namespace ring {
class AudioRecord {
public:
AudioRecord();
~AudioRecord();
void setSndFormat(AudioFormat format);
void setRecordingOptions(AudioFormat format, const std::string &path);
......@@ -96,6 +98,10 @@ class AudioRecord {
*/
void recData(AudioBuffer& buffer);
std::string getRecorderID() const {
return recorder_.getRecorderID();
}
private:
NON_COPYABLE(AudioRecord);
......@@ -138,8 +144,11 @@ class AudioRecord {
* Path for this recording
*/
std::string savePath_;
/**
* Audio recording thread
*/
AudioRecorder recorder_;
};
} // namespace ring
#endif // _AUDIO_RECORD_H
/*
* Copyright (C) 2004-2015 Savoir-faire Linux Inc.
* Copyright (C) 2004-2016 Savoir-faire Linux Inc.
*
* Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
* Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
......@@ -20,6 +20,7 @@
*/
#include "audiorecorder.h"
#include "audiorecord.h"
#include "ringbufferpool.h"
#include "audiobuffer.h"
......@@ -32,11 +33,11 @@
namespace ring {
static constexpr std::size_t BUFFER_LENGTH {10000};
static constexpr std::chrono::milliseconds SLEEP_TIME {20};
static constexpr auto SLEEP_TIME = std::chrono::milliseconds(20);
AudioRecorder::AudioRecorder(AudioRecord* arec, RingBufferPool& rbp)
: ringBufferPool_(rbp)
, buffer_(new AudioBuffer(BUFFER_LENGTH, ringBufferPool_.getInternalAudioFormat()))
, buffer_(new AudioBuffer(BUFFER_LENGTH, AudioFormat::NONE()))
, arecord_(arec)
, thread_(
[this] { return true; },
......@@ -54,6 +55,11 @@ AudioRecorder::AudioRecorder(AudioRecord* arec, RingBufferPool& rbp)
recorderId_ = id.append(s);
}
AudioRecorder::~AudioRecorder()
{
thread_.join();
}
unsigned
AudioRecorder::nextProcessID() noexcept
{
......@@ -61,17 +67,12 @@ AudioRecorder::nextProcessID() noexcept
return ++id;
}
void
AudioRecorder::init() {
if (!arecord_->isRecording())
arecord_->setSndFormat(ringBufferPool_.getInternalAudioFormat());
}
void
AudioRecorder::start()
{
if (thread_.isRunning())
return;
buffer_->setFormat(ringBufferPool_.getInternalAudioFormat());
thread_.start();
}
......
/*
* Copyright (C) 2004-2015 Savoir-faire Linux Inc.
* Copyright (C) 2004-2016 Savoir-faire Linux Inc.
*
* Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
* Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
......@@ -36,17 +36,12 @@ class AudioBuffer;
class AudioRecorder {
public:
AudioRecorder(AudioRecord* arec, RingBufferPool& rbp);
~AudioRecorder();
std::string getRecorderID() const noexcept {
std::string getRecorderID() const {
return recorderId_;
}
/**
* Set the record to the current audio format.
* Should be called before start() at least once.
*/
void init();
/**
* Call to start recording.
*/
......
......@@ -20,7 +20,7 @@
#include "recordable.h"
#include "audio/audiorecord.h"
#include "audio/audiorecorder.h"
#include "audio/ringbufferpool.h"
#include "manager.h"
#include "logger.h"
......@@ -28,7 +28,6 @@ namespace ring {
Recordable::Recordable()
: recAudio_(new AudioRecord)
, recorder_(new AudioRecorder {recAudio_.get(), Manager::instance().getRingBufferPool()})
{
auto record_path = Manager::instance().audioPreference.getRecordPath();
RING_DBG("Set recording options: %s", record_path.c_str());
......@@ -36,46 +35,46 @@ Recordable::Recordable()
}
Recordable::~Recordable()
{
if (recAudio_->isOpenFile())
recAudio_->closeFile();
}
{}
void
Recordable::initRecFilename(const std::string &filename)
Recordable::initRecFilename(const std::string& filename)
{
recAudio_->initFilename(filename);
}
std::string
Recordable::getFilename() const
Recordable::getAudioFilename() const
{
return recAudio_->getFilename();
}
void
Recordable::setRecordingFormat(AudioFormat format)
Recordable::setRecordingAudioFormat(AudioFormat format)
{
recAudio_->setSndFormat(format);
}
bool
Recordable::isRecording() const
{
return recAudio_->isRecording();
}
bool
Recordable::toggleRecording()
{
if (not isRecording())
recorder_->init();
return recAudio_->toggleRecording();
std::lock_guard<std::mutex> lk {apiMutex_};
if (not recording_) {
recAudio_->setSndFormat(Manager::instance().getRingBufferPool().getInternalAudioFormat());
recAudio_->toggleRecording();
} else {
recAudio_->stopRecording();
}
recording_ = not recording_;
return recording_;
}
void
Recordable::stopRecording()
{
std::lock_guard<std::mutex> lk {apiMutex_};
if (not recording_)
return;
recAudio_->stopRecording();
}
......
......@@ -25,11 +25,11 @@
#include <string>
#include <memory>
#include <mutex>
namespace ring {
class AudioRecord;
class AudioRecorder;
class Recordable {
public:
......@@ -39,7 +39,10 @@ public:
/**
* Return recording state (true/false)
*/
bool isRecording() const;
bool isRecording() const {
std::lock_guard<std::mutex> lk {apiMutex_};
return recording_;
}
/**
* This method must be implemented for this interface as calls and conferences
......@@ -59,18 +62,19 @@ public:
void initRecFilename(const std::string& filename);
/**
* Return the file path for this recording
* Return the audio file path for this recording
*/
virtual std::string getFilename() const;
virtual std::string getAudioFilename() const;
/**
* Set recording sampling rate.
* Set audio recording sampling rate.
*/
void setRecordingFormat(AudioFormat format);
void setRecordingAudioFormat(AudioFormat format);
protected:
mutable std::mutex apiMutex_;
bool recording_ {false};
std::unique_ptr<AudioRecord> recAudio_;
std::unique_ptr<AudioRecorder> recorder_;
};
} // namespace ring
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