Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
savoirfairelinux
jami-daemon
Commits
c90d7416
Commit
c90d7416
authored
Mar 25, 2013
by
Adrien Béraud
Browse files
RingBuffer backed by one AudioBuffer
parent
b1a9caed
Changes
10
Hide whitespace changes
Inline
Side-by-side
daemon/src/audio/audiobuffer.cpp
View file @
c90d7416
...
...
@@ -160,18 +160,21 @@ void AudioBuffer::fromInterleaved(const SFLAudioSample* in, size_t sample_num, u
}
}
size_t
AudioBuffer
::
mix
(
const
AudioBuffer
&
other
)
size_t
AudioBuffer
::
mix
(
const
AudioBuffer
&
other
,
bool
up
/* = true */
)
{
const
bool
upmix
=
up
&&
(
other
.
channels_
<
channels_
);
const
size_t
samp_num
=
std
::
min
(
sampleNum_
,
other
.
sampleNum_
);
const
unsigned
chan_num
=
std
::
min
(
channels_
,
other
.
channels_
);
const
unsigned
chan_num
=
upmix
?
channels_
:
std
::
min
(
channels_
,
other
.
channels_
);
for
(
unsigned
i
=
0
;
i
<
chan_num
;
i
++
)
{
unsigned
src_chan
=
upmix
?
std
::
min
(
i
,
other
.
channels_
-
1
)
:
i
;
for
(
unsigned
j
=
0
;
j
<
samp_num
;
j
++
)
samples_
[
i
][
j
]
+=
other
.
samples_
[
i
][
j
];
samples_
[
i
][
j
]
+=
other
.
samples_
[
src_chan
][
j
];
}
return
samp_num
;
}
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
*/
,
bool
up
/* = true
*/
)
{
if
(
sample_num
==
-
1
)
sample_num
=
in
.
samples
();
...
...
@@ -179,7 +182,8 @@ size_t AudioBuffer::copy(AudioBuffer& in, int sample_num /* = -1 */, size_t pos_
int
to_copy
=
std
::
min
((
int
)
in
.
samples
()
-
(
int
)
pos_in
,
sample_num
);
if
(
to_copy
<=
0
)
return
0
;
const
size_t
chan_num
=
std
::
min
(
in
.
channels_
,
channels_
);
const
bool
upmix
=
up
&&
(
in
.
channels_
<
channels_
);
const
size_t
chan_num
=
upmix
?
channels_
:
std
::
min
(
in
.
channels_
,
channels_
);
if
(
pos_out
+
to_copy
>
sampleNum_
)
resize
(
pos_out
+
to_copy
);
...
...
@@ -189,7 +193,8 @@ size_t AudioBuffer::copy(AudioBuffer& in, int sample_num /* = -1 */, size_t pos_
unsigned
i
;
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
);
unsigned
src_chan
=
upmix
?
std
::
min
(
i
,
in
.
channels_
-
1
)
:
i
;
std
::
copy
(
in
.
samples_
[
src_chan
].
begin
()
+
pos_in
,
in
.
samples_
[
src_chan
].
begin
()
+
pos_in
+
to_copy
,
samples_
[
i
].
begin
()
+
pos_out
);
}
return
to_copy
;
...
...
daemon/src/audio/audiobuffer.h
View file @
c90d7416
...
...
@@ -35,7 +35,6 @@
#include
<cstddef>
// for size_t
#include
"sfl_types.h"
//#include "noncopyable.h"
class
AudioBuffer
{
public:
...
...
@@ -98,8 +97,8 @@ class AudioBuffer {
* Return the total number of single samples in the buffer (same as samples()*channels()).
*/
inline
size_t
capacity
()
const
{
return
samples
()
*
channels
();
}
return
samples
()
*
channels
();
}
/**
* Resize the buffer to make it able to hold sample_num multichannel samples.
...
...
@@ -165,12 +164,20 @@ class AudioBuffer {
void
applyGain
(
double
gain
);
/**
* Mix elements of the other buffer with this buffer (in-place simple addition).
* Mix elements of the other buffer within this buffer (in-place simple addition).
* If other.channels() is higher than this.channels(), only the first this.channels() channels are imported.
* If other.channels() is lower than this.channels(), behavior depends on upmix.
* Sample rate is not considered by this function.
*
* TODO: some kind of check for overflow/saturation.
*
* @param other: the other buffer to mix in this one.
* @param upmix: if true, upmixing occurs when other.channels() < this.channels().
* If false, only the first other.channels() channels are edited in this buffer.
*
* @returns Number of samples modified.
*/
size_t
mix
(
const
AudioBuffer
&
other
);
size_t
mix
(
const
AudioBuffer
&
other
,
bool
upmix
=
true
);
/**
* Copy sample_num samples from in (from sample pos_in) to this buffer (at sample pos_out).
...
...
@@ -179,7 +186,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
,
bool
upmix
=
true
);
/**
* Copy sample_num samples from in to this buffer (at sample pos_out).
...
...
@@ -190,8 +197,6 @@ class AudioBuffer {
size_t
copy
(
SFLAudioSample
*
in
,
size_t
sample_num
,
size_t
pos_out
=
0
);
private:
//NON_COPYABLE(AudioBuffer);
int
sampleRate_
;
unsigned
channels_
;
// should allways be the same as samples_.size()
size_t
sampleNum_
;
...
...
daemon/src/audio/audioloop.cpp
View file @
c90d7416
...
...
@@ -49,7 +49,6 @@ AudioLoop::AudioLoop(unsigned int sampleRate) : buffer_(), pos_(0), isRecording_
AudioLoop
::~
AudioLoop
()
{
//delete [] buffer_;
delete
buffer_
;
}
...
...
@@ -64,7 +63,6 @@ AudioLoop::seek(double relative_position)
static
unsigned
int
updatePlaybackScale
=
0
;
void
//AudioLoop::getNext(SFLAudioSample* output, size_t total_samples, short volume)
AudioLoop
::
getNext
(
AudioBuffer
&
output
,
unsigned
int
volume
)
{
if
(
!
buffer_
)
{
...
...
@@ -88,23 +86,8 @@ AudioLoop::getNext(AudioBuffer& output, unsigned int volume)
while
(
total_samples
>
0
)
{
size_t
samples
=
std
::
min
(
total_samples
,
buf_samples
-
pos
);
/* if (samples > (buf_samples - pos))
samples = buf_samples - pos;*/
// short->char conversion
//memcpy(output, buffer_ + pos, samples * sizeof(SFLAudioSample));
//buffer_.copy(output, pos, samples);
output
.
copy
(
*
buffer_
,
samples
,
pos
,
output_pos
);
// Scaling needed
/*if (volume != 100) {
const double gain = volume * 0.01;
for (size_t i = 0; i < samples; ++i, ++output)
*output *= gain;
} else
output_pos += samples;*/
//output += samples; // this is the destination...
output_pos
+=
samples
;
pos
=
(
pos
+
samples
)
%
buf_samples
;
...
...
daemon/src/audio/audioloop.h
View file @
c90d7416
...
...
@@ -56,7 +56,6 @@ class AudioLoop {
* @param nb of int16 to send
* @param volume The volume
*/
//void getNext(SFLAudioSample* output, size_t samples, short volume=100);
void
getNext
(
AudioBuffer
&
output
,
unsigned
int
volume
=
100
);
void
seek
(
double
relative_position
);
...
...
@@ -73,7 +72,7 @@ class AudioLoop {
* @return unsigned int The size
*/
size_t
getSize
()
{
return
buffer_
->
samples
();
//size_;
return
buffer_
->
samples
();
}
/**
...
...
@@ -87,17 +86,10 @@ class AudioLoop {
protected:
/** The data buffer */
AudioBuffer
*
buffer_
;
//SFLAudioSample* buffer_;
/** Number of samples inside the buffer */
//size_t size_;
/** current position, set to 0, when initialize */
size_t
pos_
;
/** Sample rate */
//unsigned int sampleRate_;
/** Is a playback recording */
bool
isRecording_
;
...
...
daemon/src/audio/pulseaudio/pulselayer.cpp
View file @
c90d7416
...
...
@@ -135,8 +135,6 @@ PulseLayer::~PulseLayer()
if
(
mainloop_
)
pa_threaded_mainloop_free
(
mainloop_
);
//delete [] mic_buffer_;
}
void
PulseLayer
::
context_state_callback
(
pa_context
*
c
,
void
*
user_data
)
...
...
@@ -365,6 +363,8 @@ void PulseLayer::writeToSpeaker()
}
else
if
(
ret
==
0
)
return
;
DEBUG
(
"writeToSpeaker with n_channels=%d"
,
n_channels
);
size_t
writableBytes
=
ret
;
size_t
writableSamples
=
writableBytes
/
sample_size
;
...
...
daemon/src/audio/pulseaudio/pulselayer.h
View file @
c90d7416
...
...
@@ -55,15 +55,15 @@ typedef struct PaDeviceInfos {
pa_channel_map
channel_map
;
PaDeviceInfos
(
unsigned
idx
,
const
char
*
ep_name
,
pa_sample_spec
samp_spec
,
pa_channel_map
chan_map
)
:
index
(
idx
),
name
(
ep_name
),
sample_spec
(
samp_spec
),
channel_map
(
chan_map
)
{}
:
index
(
idx
),
name
(
ep_name
),
sample_spec
(
samp_spec
),
channel_map
(
chan_map
)
{}
virtual
~
PaDeviceInfos
()
{}
/**
* Unary function to search for a device by name in a list using std functions.
*/
struct
nameComparator
:
public
std
::
unary_function
<
const
PaDeviceInfos
,
bool
>
{
explicit
nameComparator
(
const
std
::
string
&
baseline
)
:
baseline
(
baseline
)
{}
explicit
nameComparator
(
const
std
::
string
&
ref
)
:
baseline
(
ref
)
{}
bool
operator
()
(
const
PaDeviceInfos
&
arg
)
{
return
arg
.
name
==
baseline
;
}
...
...
daemon/src/audio/ringbuffer.cpp
View file @
c90d7416
...
...
@@ -3,6 +3,7 @@
* Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
* Author: Yan Morin <yan.morin@savoirfairelinux.com>
* Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com>
* Author: Adrien Beraud <adrien.beraud@gmail.com>
*
* Portions (c) Dominic Mazzoni (Audacity)
*
...
...
@@ -40,15 +41,14 @@
#include
"ringbuffer.h"
namespace
{
// corresponds to 1
0
6 ms (about 5 rtp packets)
// corresponds to 16
0
ms (about 5 rtp packets)
const
size_t
MIN_BUFFER_SIZE
=
1280
;
}
// Create a ring buffer with 'size' bytes
RingBuffer
::
RingBuffer
(
size_t
size
,
const
std
::
string
&
call_id
)
:
endPos_
(
0
)
,
bufferSize_
(
std
::
max
(
size
,
MIN_BUFFER_SIZE
))
,
buffer_
(
1
,
std
::
vector
<
SFLAudioSample
>
(
bufferSize_
))
,
buffer_
(
std
::
max
(
size
,
MIN_BUFFER_SIZE
),
1
)
,
readpointers_
()
,
buffer_id_
(
call_id
)
{
...
...
@@ -73,19 +73,21 @@ RingBuffer::flushAll()
size_t
RingBuffer
::
putLength
()
const
{
const
size_t
buffer_size
=
buffer_
.
samples
();
const
size_t
startPos
=
(
not
readpointers_
.
empty
())
?
getSmallestReadPointer
()
:
0
;
return
(
endPos_
+
buffer
S
ize
_
-
startPos
)
%
buffer
S
ize
_
;
return
(
endPos_
+
buffer
_s
ize
-
startPos
)
%
buffer
_s
ize
;
}
size_t
RingBuffer
::
getLength
(
const
std
::
string
&
call_id
)
const
{
return
(
endPos_
+
bufferSize_
-
getReadPointer
(
call_id
))
%
bufferSize_
;
const
size_t
buffer_size
=
buffer_
.
samples
();
return
(
endPos_
+
buffer_size
-
getReadPointer
(
call_id
))
%
buffer_size
;
}
void
RingBuffer
::
debug
()
{
DEBUG
(
"Start=%d; End=%d; BufferSize=%d"
,
getSmallestReadPointer
(),
endPos_
,
buffer
Size_
);
DEBUG
(
"Start=%d; End=%d; BufferSize=%d"
,
getSmallestReadPointer
(),
endPos_
,
buffer
_
.
samples
()
);
}
size_t
RingBuffer
::
getReadPointer
(
const
std
::
string
&
call_id
)
const
...
...
@@ -103,7 +105,7 @@ RingBuffer::getSmallestReadPointer() const
if
(
hasNoReadPointers
())
return
0
;
size_t
smallest
=
buffer
Size_
;
size_t
smallest
=
buffer
_
.
samples
()
;
ReadPointer
::
const_iterator
iter
;
...
...
@@ -161,22 +163,20 @@ bool RingBuffer::hasNoReadPointers() const
//
// This one puts some data inside the ring buffer.
//void RingBuffer::put(void* buffer, size_t toCopy)
void
RingBuffer
::
put
(
AudioBuffer
&
buf
)
{
const
size_t
len
=
putLength
();
const
unsigned
chans
=
buf
.
channels
();
const
size_t
sample_num
=
buf
.
samples
();
const
size_t
buffer_size
=
buffer_
.
samples
();
size_t
toCopy
=
sample_num
;
// Add more channels if the input buffer holds more channels than the ring.
if
(
buffer_
.
size
()
<
chans
)
buffer_
.
resize
(
chans
,
std
::
vector
<
SFLAudioSample
>
(
bufferSize_
,
0
));
if
(
buffer_
.
channels
()
<
buf
.
channels
()
)
buffer_
.
setChannelNum
(
buf
.
channels
(
));
if
(
toCopy
>
buffer
S
ize
_
-
len
)
toCopy
=
buffer
S
ize
_
-
len
;
if
(
toCopy
>
buffer
_s
ize
-
len
)
toCopy
=
buffer
_s
ize
-
len
;
//unsigned char *src = static_cast<SFLAudioSample *>(buffer);
size_t
in_pos
=
0
;
size_t
pos
=
endPos_
;
...
...
@@ -184,14 +184,12 @@ void RingBuffer::put(AudioBuffer& buf)
size_t
block
=
toCopy
;
size_t
i
;
if
(
block
>
buffer
S
ize
_
-
pos
)
// Wrap block around ring ?
block
=
buffer
S
ize
_
-
pos
;
// Fill in to the end of the buffer
if
(
block
>
buffer
_s
ize
-
pos
)
// Wrap block around ring ?
block
=
buffer
_s
ize
-
pos
;
// Fill in to the end of the buffer
for
(
i
=
0
;
i
<
chans
;
i
++
)
{
copy
(
buf
.
getChannel
(
i
)
->
begin
()
+
in_pos
,
buf
.
getChannel
(
i
)
->
begin
()
+
in_pos
+
block
,
buffer_
[
i
].
begin
()
+
pos
);
}
buffer_
.
copy
(
buf
,
block
,
in_pos
,
pos
);
in_pos
+=
block
;
pos
=
(
pos
+
block
)
%
buffer
S
ize
_
;
pos
=
(
pos
+
block
)
%
buffer
_s
ize
;
toCopy
-=
block
;
}
endPos_
=
pos
;
...
...
@@ -209,7 +207,6 @@ RingBuffer::availableForGet(const std::string &call_id) const
}
// Get will move 'toCopy' bytes from the internal FIFO to 'buffer'
//size_t RingBuffer::get(void *buffer, size_t toCopy, const std::string &call_id)
size_t
RingBuffer
::
get
(
AudioBuffer
&
buf
,
const
std
::
string
&
call_id
)
{
if
(
hasNoReadPointers
())
...
...
@@ -220,12 +217,9 @@ size_t RingBuffer::get(AudioBuffer& buf, const std::string &call_id)
const
size_t
len
=
getLength
(
call_id
);
const
size_t
sample_num
=
buf
.
samples
();
const
size_t
chans
=
std
::
min
((
unsigned
)
buffer_
.
size
(),
buf
.
channel
s
()
)
;
const
size_t
buffer_size
=
buf
fer_
.
sample
s
();
size_t
toCopy
=
std
::
min
(
sample_num
,
len
);
/* if (toCopy > len)
toCopy = len;*/
const
size_t
copied
=
toCopy
;
size_t
dest
=
0
;
...
...
@@ -235,17 +229,13 @@ size_t RingBuffer::get(AudioBuffer& buf, const std::string &call_id)
size_t
block
=
toCopy
;
unsigned
i
;
if
(
block
>
buffer
S
ize
_
-
startPos
)
block
=
buffer
S
ize
_
-
startPos
;
if
(
block
>
buffer
_s
ize
-
startPos
)
block
=
buffer
_s
ize
-
startPos
;
for
(
i
=
0
;
i
<
chans
;
i
++
)
{
copy
(
buffer_
[
i
].
begin
()
+
startPos
,
buffer_
[
i
].
begin
()
+
startPos
+
block
,
buf
.
getChannel
(
i
)
->
begin
()
+
dest
);
// memcpy(buf->getChannel(i), &(*buffer_[i].begin()) + startPos, block);
}
buf
.
copy
(
buffer_
,
block
,
startPos
,
dest
);
//memcpy(dest, &(*buffer_.begin()) + startPos, block);
dest
+=
block
;
startPos
=
(
startPos
+
block
)
%
buffer
S
ize
_
;
startPos
=
(
startPos
+
block
)
%
buffer
_s
ize
;
toCopy
-=
block
;
}
...
...
@@ -261,7 +251,8 @@ RingBuffer::discard(size_t toDiscard, const std::string &call_id)
if
(
toDiscard
>
len
)
toDiscard
=
len
;
size_t
startPos
=
(
getReadPointer
(
call_id
)
+
toDiscard
)
%
bufferSize_
;
size_t
buffer_size
=
buffer_
.
samples
();
size_t
startPos
=
(
getReadPointer
(
call_id
)
+
toDiscard
)
%
buffer_size
;
storeReadPointer
(
startPos
,
call_id
);
...
...
daemon/src/audio/ringbuffer.h
View file @
c90d7416
...
...
@@ -3,6 +3,7 @@
* Author: Yan Morin <yan.morin@savoirfairelinux.com>
* Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com>
* Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
* Author: Adrien Beraud <adrien.beraud@gmail.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
...
...
@@ -98,7 +99,6 @@ class RingBuffer {
* @param toCopy Number of bytes to copy
*/
void
put
(
AudioBuffer
&
buf
);
//void put(void* buffer, size_t toCopy);
/**
* To get how much samples are available in the buffer to read in
...
...
@@ -113,7 +113,6 @@ class RingBuffer {
* @return size_t Number of bytes copied
*/
size_t
get
(
AudioBuffer
&
buf
,
const
std
::
string
&
call_id
);
//size_t get(void* buffer, size_t toCopy, const std::string &call_id);
/**
* Discard data from the buffer
...
...
@@ -141,10 +140,8 @@ class RingBuffer {
/** Pointer on the last data */
size_t
endPos_
;
/** Buffer size */
size_t
bufferSize_
;
/** Data */
std
::
vector
<
std
::
vector
<
SFLAudioSample
>
>
buffer_
;
AudioBuffer
buffer_
;
ReadPointer
readpointers_
;
std
::
string
buffer_id_
;
...
...
daemon/src/audio/sound/dtmf.h
View file @
c90d7416
...
...
@@ -58,7 +58,7 @@ class DTMF {
/**
* Copy the sound inside the sampling* buffer
* @param buffer : a vector of SFL
DataFormat
* @param buffer : a vector of SFL
AudioSample
*/
bool
generateDTMF
(
std
::
vector
<
SFLAudioSample
>
&
buffer
);
...
...
daemon/test/mainbuffertest.cpp
View file @
c90d7416
...
...
@@ -422,7 +422,7 @@ void MainBufferTest::testTwoPointer()
input_buffer
->
put
(
test_input
);
CPPUNIT_ASSERT
(
output_buffer
->
get
(
test_output
,
MainBuffer
::
DEFAULT_ID
)
==
1
);
CPPUNIT_ASSERT
(
(
*
test_
input
.
getChannel
())[
0
]
==
(
*
test_output
.
getChannel
())[
0
]);
CPPUNIT_ASSERT
(
test_
sample
==
(
*
test_output
.
getChannel
())[
0
]);
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment