Commit 174478a6 authored by Adrien Béraud's avatar Adrien Béraud
Browse files

multichannel compiles

parent f0d1257b
......@@ -14,6 +14,7 @@ SFL_SPEEXDSP_HEAD=noisesuppress.h
endif
libaudio_la_SOURCES = \
audiobuffer.cpp \
audioloop.cpp \
ringbuffer.cpp \
mainbuffer.cpp \
......@@ -28,6 +29,7 @@ libaudio_la_SOURCES = \
dcblocker.cpp
noinst_HEADERS = \
audiobuffer.h \
audioloop.h \
ringbuffer.h \
mainbuffer.h \
......
......@@ -756,7 +756,7 @@ void AlsaLayer::playback(int maxSamples)
const size_t samplesToGet = bytesToGet / sizeof(SFLAudioSample);
//std::vector<SFLAudioSample> out(samplesToGet, 0);
AudioBuffer out(samplesToGet, 1, sampleRate_);
AudioBuffer out(samplesToGet, 1, mainBufferSampleRate);
//SFLAudioSample * const out_ptr = &(*out.getChannel()->begin());
Manager::instance().getMainBuffer().getData(&out, MainBuffer::DEFAULT_ID);
......@@ -766,7 +766,7 @@ void AlsaLayer::playback(int maxSamples)
if (resample) {
const size_t outSamples = samplesToGet * resampleFactor;
const size_t outBytes = outSamples * sizeof(SFLAudioSample);
AudioBuffer rsmpl_out(outSamples, 1, mainBufferSampleRate);
AudioBuffer rsmpl_out(outSamples, 1, sampleRate_);
//std::vector<SFLAudioSample> rsmpl_out(outSamples);
//SFLAudioSample * const rsmpl_out_ptr = &(*rsmpl_out.begin());
//converter_.resample(out_ptr, rsmpl_out_ptr, rsmpl_out.size(), mainBufferSampleRate, sampleRate_, samplesToGet);
......
......@@ -28,19 +28,21 @@
* as that of the covered work.
*/
AudioBuffer::AudioBuffer(size_t sample_num /* = 0 */, size_t channel_num /* = 1 */, int sample_rate /* = 8000 */)
#include "audiobuffer.h"
AudioBuffer::AudioBuffer(size_t sample_num /* = 0 */, unsigned channel_num /* = 1 */, int sample_rate /* = 8000 */)
: sampleRate_(sample_rate),
sampleNum_(sample_num),
channels_(channel_num),
samples_(channel_num, vector<SFLAudioSample>(sample_num, 0))
samples_(channel_num, std::vector<SFLAudioSample>(sample_num, 0))
{
}
AudioBuffer(const AudioBuffer& other, bool copy_content /* = false */)
AudioBuffer::AudioBuffer(const AudioBuffer& other, bool copy_content /* = false */)
: sampleRate_(other.sampleRate_),
sampleNum_(other.sampleNum_),
channels_(other.channels_),
samples_(channel_num, vector<SFLAudioSample>())
samples_(channels_, std::vector<SFLAudioSample>())
{
unsigned i;
if(copy_content) {
......@@ -52,40 +54,39 @@ AudioBuffer(const AudioBuffer& other, bool copy_content /* = false */)
}
}
int AudioBuffer::getSampleRate()
int AudioBuffer::getSampleRate() const
{
return sampleRate_;
}
void setSampleRate(int sr)
void AudioBuffer::setSampleRate(int sr)
{
sampleRate_ = sr;
}
size_t AudioBuffer::getChannelNum()
unsigned AudioBuffer::getChannelNum() const
{
return channels_;
}
void AudioBuffer::setChannelNum(size_t n, bool copy_content /* = false */)
void AudioBuffer::setChannelNum(unsigned n, bool copy_content /* = false */)
{
if(channels_ != n) {
channels_ = n;
samples_.resize(n, std::vector<SFLAudioSample>(sampleNum_, (copy_content && samples_.size()>0)?samples_[0]:0));
samples_.resize(n, (copy_content && samples_.size()>0)?samples_[0]:std::vector<SFLAudioSample>(sampleNum_, 0));
}
}
size_t AudioBuffer::samples()
size_t AudioBuffer::samples() const
{
return sampleNum_;
}
void AudioBuffer::resize(size_t sample_num)
{
unsigned i;
if(sampleNum_ != sample_num) {
sampleNum_ = sample_num;
for(i=0; i<channels_; i++)
for(unsigned i=0; i<channels_; i++)
samples_[i].resize(sample_num);
}
}
......@@ -93,58 +94,57 @@ void AudioBuffer::resize(size_t sample_num)
void AudioBuffer::clear()
{
unsigned i, j;
for(i=0; i<channels_; i++)
for(i=0; i<channels_; i++)
samples_[i].assign(sampleNum_, 0);
}
void AudioBuffer::empty()
{
unsigned i;
for(i=0; i<channels_; i++)
for(unsigned i=0; i<channels_; i++)
samples_[i].clear();
sampleNum_ = 0;
}
std::vector<SFLAudioSample> *
AudioBuffer::getChannel(size_t chan /* = 0 */)
AudioBuffer::getChannel(unsigned chan /* = 0 */)
{
return samples_[chan];
return &samples_[chan];
}
void AudioBuffer::applyGain(AudioBuffer *src, unsigned int gain)
void AudioBuffer::applyGain(unsigned int gain)
{
if(gain != 100)
applyGain(gain*0.01);
}
void AudioBuffer::applyGain(AudioBuffer *src, double gain)
void AudioBuffer::applyGain(double gain)
{
if(gain == 1.0) return;
unsigned i, j;
for(i=0; i<channels_; i++)
for(j=0; j<sampleNum_; j++)
for(i=0; i<channels_; i++)
for(j=0; j<sampleNum_; j++)
samples_[i][j] *= gain;
}
size_t AudioBuffer::interleave(SFLAudioSample* out)
size_t AudioBuffer::interleave(SFLAudioSample* out) const
{
unsigned i, j;
for(i=0; i<sampleNum_; i++)
for(j=0; j<channels_; j++)
for(i=0; i<sampleNum_; i++)
for(j=0; j<channels_; j++)
*out++ = samples_[j][i];
return sampleNum_*channels_;
}
size_t AudioBuffer::interleaveFloat(float* out)
size_t AudioBuffer::interleaveFloat(float* out) const
{
unsigned i, j;
for(i=0; i<sampleNum_; i++)
for(j=0; j<channels_; j++)
for(i=0; i<sampleNum_; i++)
for(j=0; j<channels_; j++)
*out++ = (float) samples_[j][i] * .000030517578125f;
return sampleNum_*channels_;
}
void AudioBuffer::fromInterleaved(SFLAudioSample* in, size_t sample_num, size_t channel_num)
void AudioBuffer::fromInterleaved(const SFLAudioSample* in, size_t sample_num, unsigned channel_num)
{
unsigned i;
......@@ -164,38 +164,33 @@ size_t AudioBuffer::mix(const AudioBuffer& other)
const size_t samp_num = std::min(sampleNum_, other.sampleNum_);
const size_t chan_num = std::min(channels_, other.channels_);
unsigned i;
for(i=0; i<chan_num; i++) {
for(i=0; i<chan_num; i++) {
unsigned j;
for(j=0; j<samp_num; j++)
for(j=0; j<samp_num; j++)
samples_[i][j] += other.samples_[i][j];
}
return samp_num;
}
size_t AudioBuffer::sub(AudioBuffer& out, size_t pos)
{
out.copy(this, samples(), pos);
}
size_t AudioBuffer::copy(AudioBuffer& in, int sample_num /* = -1 */, size_t pos_in /* = 0 */, size_t pos_out /* = 0 */)
size_t AudioBuffer::copy(AudioBuffer* in, int sample_num /* = -1 */, size_t pos_in /* = 0 */, size_t pos_out /* = 0 */)
{
if(sample_num == -1)
sample_num = in.samples();
sample_num = in->samples();
int to_copy = std::min(in.samples()-(int)pos_in, (int)sample_num);
int to_copy = std::min((int)in->samples()-(int)pos_in, sample_num);
if(to_copy <= 0) return 0;
const size_t chan_num = in.channels_;
const size_t chan_num = std::min(in->channels_, channels_);
if(pos_out+to_copy > sampleNum_)
resize(pos_out+to_copy);
sampleRate_ = in.sampleRate_;
setChannelNum(chan_num);
sampleRate_ = in->sampleRate_;
//setChannelNum(chan_num);
unsigned i;
for(i=0; i<chan_num; i++) {
copy(in.samples_[i].begin()+pos_in, in.samples_[i].begin()+pos_in+to_copy, samples_[i].begin()+pos_out);
for(i=0; i<chan_num; i++) {
std::copy(in->samples_[i].begin()+pos_in, in->samples_[i].begin()+pos_in+to_copy, samples_[i].begin()+pos_out);
}
return to_copy;
......@@ -204,11 +199,11 @@ size_t AudioBuffer::copy(AudioBuffer& in, int sample_num /* = -1 */, size_t pos_
size_t AudioBuffer::copy(SFLAudioSample* in, size_t sample_num, size_t pos_out /* = 0 */)
{
if(pos_out+sample_num > sampleNum_)
resize(pos_out+to_copy);
resize(pos_out+sample_num);
const size_t chan_num = channels_;
unsigned i;
for(i=0; i<chan_num; i++) {
copy(in, in+to_copy, samples_[i].begin()+pos_out);
for(i=0; i<chan_num; i++) {
std::copy(in, in+sample_num, samples_[i].begin()+pos_out);
}
}
......@@ -35,12 +35,12 @@
#include <cstddef> // for size_t
#include "sfl_types.h"
#include "noncopyable.h"
//#include "noncopyable.h"
class AudioBuffer {
public:
AudioBuffer(size_t sample_num=0, size_t channel_num=1, int sample_rate=8000);
AudioBuffer(size_t sample_num=0, unsigned channel_num=1, int sample_rate=8000);
/**
* Copy constructor that by default only copies the buffer parameters (channel number, sample rate and buffer size).
......@@ -51,7 +51,7 @@ class AudioBuffer {
/**
* Returns the sample rate (in samples/sec) associated to this buffer.
*/
int getSampleRate();
int getSampleRate() const;
/**
* Set the sample rate (in samples/sec) associated to this buffer.
......@@ -61,9 +61,9 @@ class AudioBuffer {
/**
* Returns the number of channels in this buffer.
*/
size_t getChannelNum();
unsigned getChannelNum() const;
inline size_t channels() {
inline unsigned channels() const {
return channels_;
}
......@@ -74,12 +74,12 @@ class AudioBuffer {
*
* @param copy_first: if set to true and n > getChannelNum(), new channels are initialised with samples from the first channel. If set to false, new channels are initialised to 0.
*/
void setChannelNum(size_t n, bool copy_first=false);
void setChannelNum(unsigned n, bool copy_first=false);
/**
* Returns the number of (multichannel) samples in this buffer.
*/
size_t samples();
size_t samples() const;
/**
* Resize the buffer to make it able to hold sample_num multichannel samples.
......@@ -100,15 +100,15 @@ class AudioBuffer {
* Return the data (audio samples) for a given channel number.
* Channel data can be modified but size of individual channel vectors should not be changed manually.
*/
std::vector<SFLAudioSample> *getChannel(size_t chan=0);
std::vector<SFLAudioSample> *getChannel(unsigned chan=0);
/**
* Write interleaved multichannel data to the out buffer.
* Write interleaved multichannel data to the out buffer (fixed-point 16-bits).
* The out buffer must be at least of size getChannelNum()*samples()*sizeof(SFLAudioSample).
*
* @returns Number of samples writen.
*/
size_t interleave(SFLAudioSample* out);
size_t interleave(SFLAudioSample* out) const;
/**
* Write interleaved multichannel data to the out buffer, while samples are converted to float.
......@@ -116,12 +116,12 @@ class AudioBuffer {
*
* @returns Number of samples writen.
*/
size_t interleaveFloat(float* out);
size_t interleaveFloat(float* out) const;
/**
* Import interleaved multichannel data. Internal buffer is resized as needed. Function will read sample_num*channel_num elements of the in buffer.
*/
void fromInterleaved(SFLAudioSample* in, size_t sample_num, size_t channel_num=1);
void fromInterleaved(const SFLAudioSample* in, size_t sample_num, unsigned channel_num=1);
/**
* In-place gain transformation with integer parameter.
......@@ -152,7 +152,7 @@ class AudioBuffer {
* The number of channels is changed to match the in channel number.
* Buffer sample number is also increased if required to hold the new requested samples.
*/
size_t copy(AudioBuffer& in, int sample_num=-1, size_t pos_in=0, size_t pos_out=0);
size_t copy(AudioBuffer* in, int sample_num=-1, size_t pos_in=0, size_t pos_out=0);
/**
* Copy sample_num samples from in to this (at sample pos_out).
......@@ -163,10 +163,10 @@ class AudioBuffer {
size_t copy(SFLAudioSample* in, size_t sample_num, size_t pos_out=0);
private:
NON_COPYABLE(AudioBuffer);
//NON_COPYABLE(AudioBuffer);
int sampleRate_;
size_t channels_; // should allways be samples_.size()
unsigned channels_; // should allways be samples_.size()
size_t sampleNum_;
// main buffers holding data for each channels
......
......@@ -70,24 +70,12 @@ void AudioLayer::flushUrgent()
urgentRingBuffer_.flushAll();
}
void AudioLayer::putUrgent(void* buffer, int toCopy)
void AudioLayer::putUrgent(AudioBuffer* buffer)
{
sfl::ScopedLock guard(mutex_);
urgentRingBuffer_.put(buffer, toCopy);
urgentRingBuffer_.put(buffer);
}
/*
//void AudioLayer::applyGain(SFLDataFormat *src , int samples, int gain)
void AudioLayer::applyGain(AudioBuffer *src, int gain)
{
size_t len = src->sample_num * src->channels;
SFLAudioSample *buf = src->samples;
if (gain != 100)
for (int i = 0 ; i < len; i++)
buf[i] = buf[i] * gain* 0.01;
}*/
// Notify (with a beep) an incoming call when there is already a call in progress
void AudioLayer::notifyIncomingCall()
{
......@@ -108,11 +96,11 @@ void AudioLayer::notifyIncomingCall()
Tone tone("440/160", getSampleRate());
unsigned int nbSample = tone.getSize();
SFLAudioSample buf[nbSample];
tone.getNext(buf, nbSample);
AudioBuffer buf(nbSample);
tone.getNext(&buf);
/* Put the data in the urgent ring buffer */
flushUrgent();
putUrgent(buf, sizeof buf);
putUrgent(&buf);
}
......@@ -121,9 +121,8 @@ class AudioLayer {
* Send a chunk of data to the hardware buffer to start the playback
* Copy data in the urgent buffer.
* @param buffer The buffer containing the data to be played ( ringtones )
* @param toCopy The size of the buffer
*/
void putUrgent(void* buffer, int toCopy);
void putUrgent(AudioBuffer* buffer);
/**
* Flush main buffer
......@@ -135,12 +134,6 @@ class AudioLayer {
*/
void flushUrgent();
/**
* Apply gain to audio frame
*/
//static void applyGain(SFLDataFormat *src , int samples, int gain);
// static void applyGain(SFLAudioBuffer *src, int gain)
/**
* Convert audio amplitude value from linear value to dB
*/
......
......@@ -41,8 +41,11 @@
#include <cassert>
#include "logger.h"
AudioLoop::AudioLoop(unsigned int sampleRate) : buffer_(0), pos_(0), sampleRate_(sampleRate), isRecording_(false)
{}
AudioLoop::AudioLoop(unsigned int sampleRate) : buffer_(), pos_(0), isRecording_(false)
{
buffer_ = new AudioBuffer();
buffer_->setSampleRate(sampleRate);
}
AudioLoop::~AudioLoop()
{
......@@ -53,7 +56,7 @@ AudioLoop::~AudioLoop()
void
AudioLoop::seek(double relative_position)
{
size_t new_pos = (size_t)((double)size_ * (relative_position * 0.01));
size_t new_pos = (size_t)((double)buffer_->samples() * (relative_position * 0.01));
pos_ = new_pos;
}
......@@ -62,14 +65,14 @@ static unsigned int updatePlaybackScale = 0;
void
//AudioLoop::getNext(SFLAudioSample* output, size_t total_samples, short volume)
AudioLoop::getNext(AudioBuffer* output, short volume)
AudioLoop::getNext(AudioBuffer* output, unsigned int volume)
{
if(!buffer_) {
ERROR("AudioLoop::buffer_ is not set (NULL pointer)");
return;
}
const size_t buf_samples = buffer_.samples();
const size_t buf_samples = buffer_->samples();
size_t pos = pos_;
size_t total_samples = output->samples();
size_t output_pos = 0;
......@@ -91,7 +94,7 @@ AudioLoop::getNext(AudioBuffer* output, short volume)
// short->char conversion
//memcpy(output, buffer_ + pos, samples * sizeof(SFLAudioSample));
//buffer_.copy(output, pos, samples);
output.copy(buffer_, samples, pos, output_pos);
output->copy(buffer_, samples, pos, output_pos);
// Scaling needed
/*if (volume != 100) {
......@@ -103,17 +106,17 @@ AudioLoop::getNext(AudioBuffer* output, short volume)
output_pos += samples;*/
//output += samples; // this is the destination...
output_pos += samples;
pos = (pos + samples) % size_;
pos = (pos + samples) % buf_samples;
total_samples -= samples;
}
output.applyGain(volume); // apply volume
output->applyGain(volume); // apply volume
pos_ = pos;
// We want to send values in milisecond
int divisor = sampleRate_ / 1000;
int divisor = buffer_->getSampleRate() / 1000;
if(divisor == 0) {
ERROR("Error cannot update playback slider, sampling rate is 0");
return;
......@@ -122,7 +125,7 @@ AudioLoop::getNext(AudioBuffer* output, short volume)
if(isRecording_) {
if((updatePlaybackScale % 5) == 0) {
CallManager *cm = Manager::instance().getDbusManager()->getCallManager();
cm->updatePlaybackScale(pos_ / divisor, size_ / divisor);
cm->updatePlaybackScale(pos_ / divisor, buf_samples / divisor);
}
updatePlaybackScale++;
}
......
......@@ -57,7 +57,7 @@ class AudioLoop {
* @param volume The volume
*/
//void getNext(SFLAudioSample* output, size_t samples, short volume=100);
void getNext(AudioBuffer* output, short volume=100);
void getNext(AudioBuffer* output, unsigned int volume=100);
void seek(double relative_position);
......
......@@ -421,9 +421,9 @@ void AudioRecord::recData(AudioBuffer* buffer)
return;
}
size_t nSamples = buffer->sample_num;
size_t nSamples = buffer->samples();
if (fwrite(&(buffer->getChannel(0)), sizeof(SFLAudioSample), nSamples, fileHandle_) != nSamples)
if (fwrite(buffer->getChannel(), sizeof(SFLAudioSample), nSamples, fileHandle_) != nSamples)
WARN("Could not record data! ");
else {
fflush(fileHandle_);
......
......@@ -37,6 +37,7 @@
#include "sfl_types.h"
#include "noncopyable.h"
#include "audiobuffer.h"
class AudioRecord {
......@@ -103,7 +104,7 @@ class AudioRecord {
* @param nSamples Number of samples (number of bytes) to be recorded
*/
//void recData(SFLDataFormat* buffer, size_t nSamples);
void recData(SFLAudioSample* buffer);
void recData(AudioBuffer* buffer);
protected:
......
......@@ -81,16 +81,18 @@ AudioRecorder::runCallback(void *data)
*/
void AudioRecorder::run()
{
const size_t BUFFER_LENGTH = 10000;
std::tr1::array<SFLDataFormat, BUFFER_LENGTH> buffer;
buffer.assign(0);
static const size_t BUFFER_LENGTH = 10000;
//std::tr1::array<SFLAudioSample, BUFFER_LENGTH> buffer;
AudioBuffer buffer(BUFFER_LENGTH);
//buffer.assign(0);
while (running_) {
const size_t availableBytes = mbuffer_->availableForGet(recorderId_);
mbuffer_->getData(buffer.data(), std::min(availableBytes, buffer.size()), recorderId_);
buffer.resize(std::min(availableBytes, BUFFER_LENGTH));
mbuffer_->getData(&buffer, recorderId_);
if (availableBytes > 0)
arecord_->recData(buffer.data(), availableBytes / sizeof(SFLDataFormat));
arecord_->recData(&buffer);
usleep(20000); // 20 ms
}
......
......@@ -30,16 +30,13 @@
#include "dcblocker.h"
DcBlocker::DcBlocker(size_t channels /* = 1 */)
: state(channels, (struct StreamState){0, 0, 0, 0})
DcBlocker::DcBlocker(unsigned channels /* = 1 */)
: states(channels, (struct StreamState){0, 0, 0, 0})
{}
void DcBlocker::reset()
{
y_ = 0;
x_ = 0;
xm1_ = 0;
ym1_ = 0;
states.assign(states.size(), (struct StreamState){0, 0, 0, 0});
}
void DcBlocker::doProcess(SFLAudioSample *out, SFLAudioSample *in, int samples, struct StreamState * state)
......@@ -47,9 +44,9 @@ void DcBlocker::doProcess(SFLAudioSample *out, SFLAudioSample *in, int samples,
for (int i = 0; i < samples; ++i) {
state->x_ = in[i];
y_ = (SFLDataFormat) ((float) state->x_ - (float) state->xm1_ + 0.9999 * (float) state->y_);
xm1_ = state->x_;
ym1_ = state->y_;
state->y_ = (SFLAudioSample) ((float) state->x_ - (float) state->xm1_ + 0.9999 * (float) state->y_);
state->xm1_ = state->x_;
state->ym1_ = state->y_;
out[i] = state->y_;
}
......@@ -58,20 +55,20 @@ void DcBlocker::doProcess(SFLAudioSample *out, SFLAudioSample *in, int samples,
void DcBlocker::process(SFLAudioSample *out, SFLAudioSample *in, int samples)
{
doProcess(out, in, samples, &state[0]);
doProcess(out, in, samples, &states[0]);
}
void process(AudioBuffer *buf)
void DcBlocker::process(AudioBuffer *buf)
{
const size_t chans = buf->channels();
const size_t samples = buf->samples();
if(chans > state.size())
state.resize(buf->channels(), (struct StreamState){0, 0, 0, 0});