Skip to content
Snippets Groups Projects
Commit 6154e940 authored by Emmanuel Milou's avatar Emmanuel Milou
Browse files

Functionnal playback and capture

parent e2946414
No related branches found
Tags android/release_354
No related merge requests found
...@@ -19,12 +19,12 @@ ...@@ -19,12 +19,12 @@
#include "pulselayer.h" #include "pulselayer.h"
static pa_channel_map channel_map ; /*static pa_channel_map channel_map ;
static pa_stream_flags_t flag; static pa_stream_flags_t flag;
static pa_sample_spec sample_spec ; static pa_sample_spec sample_spec ;
static pa_volume_t volume; static pa_volume_t volume;
*/
int framesPerBuffer = 4096; int framesPerBuffer = 2048;
const pa_buffer_attr *a; const pa_buffer_attr *a;
PulseLayer::PulseLayer(ManagerImpl* manager) PulseLayer::PulseLayer(ManagerImpl* manager)
...@@ -39,7 +39,8 @@ const pa_buffer_attr *a; ...@@ -39,7 +39,8 @@ const pa_buffer_attr *a;
// Destructor // Destructor
PulseLayer::~PulseLayer (void) PulseLayer::~PulseLayer (void)
{ {
////delete cache; delete playback;
delete record;
pa_context_disconnect(context); pa_context_disconnect(context);
} }
...@@ -94,67 +95,18 @@ void PulseLayer::context_state_callback( pa_context* c, void* user_data ) ...@@ -94,67 +95,18 @@ void PulseLayer::context_state_callback( pa_context* c, void* user_data )
} }
} }
void
PulseLayer::stream_state_callback( pa_stream* s, void* user_data )
{
_debug("The state of the stream changed\n");
assert(s);
switch(pa_stream_get_state(s)){
case PA_STREAM_CREATING:
case PA_STREAM_TERMINATED:
_debug("Stream is creating...\n");
break;
case PA_STREAM_READY:
_debug("Stream successfully created\n");
break;
case PA_STREAM_FAILED:
default:
_debug("Stream error: %s\n" , pa_strerror(pa_context_errno(pa_stream_get_context(s))));
break;
}
}
void void
PulseLayer::createStreams( pa_context* c ) PulseLayer::createStreams( pa_context* c )
{ {
_debug("Creating streams...\n"); playback = new AudioStream(c, PLAYBACK_STREAM, "SFLphone out");
sample_spec.format = PA_SAMPLE_S16LE; pa_stream_set_write_callback( playback->pulseStream() , audioCallback, this);
sample_spec.rate = 44100; //pa_stream_set_overflow_callback( playback , overflow , this);
sample_spec.channels = 1; record = new AudioStream(c, CAPTURE_STREAM, "SFLphone in");
channel_map.channels = 1; pa_stream_set_read_callback( record->pulseStream() , audioCallback, this);
flag = PA_STREAM_AUTO_TIMING_UPDATE ; //pa_stream_set_underflow_callback( record , underflow , this);
volume = PA_VOLUME_NORM;
pa_cvolume cv;
assert(pa_sample_spec_valid(&sample_spec));
assert(pa_channel_map_valid(&channel_map));
if( !( playback = pa_stream_new( c, "SFLphone OUT" , &sample_spec, &channel_map ) ) )
_debug("Playback: pa_stream_new() failed : %s\n" , pa_strerror( pa_context_errno( c)));
assert( playback );
pa_stream_set_write_callback( playback , audioCallback, this);
pa_stream_connect_playback( playback , NULL , NULL ,
PA_STREAM_INTERPOLATE_TIMING,
pa_cvolume_set(&cv, sample_spec.channels , volume) , NULL );
if( !( record = pa_stream_new( c, "SFLphone IN" , &sample_spec, &channel_map ) ) )
_debug("Record: pa_stream_new() failed : %s\n" , pa_strerror( pa_context_errno( c)));
assert( record );
pa_stream_connect_record( record , NULL , NULL , PA_STREAM_INTERPOLATE_TIMING );
pa_stream_set_state_callback( record , stream_state_callback, NULL);
pa_stream_set_state_callback( playback , stream_state_callback, NULL);
//playback = new AudioStream(c, PLAYBACK_STREAM, "SFLphone out");
pa_stream_set_overflow_callback( playback , overflow , this);
//record = new AudioStream(c, CAPTURE_STREAM, "SFLphone in");
pa_stream_set_read_callback( record , audioCallback, this);
pa_stream_set_underflow_callback( record , underflow , this);
//cache = new AudioStream(c, UPLOAD_STREAM, "Cache samples"); //cache = new AudioStream(c, UPLOAD_STREAM, "Cache samples");
pa_threaded_mainloop_signal(m , 0); pa_threaded_mainloop_signal(m , 0);
} }
bool bool
...@@ -235,13 +187,7 @@ PulseLayer::putUrgent(void* buffer, int toCopy) ...@@ -235,13 +187,7 @@ PulseLayer::putUrgent(void* buffer, int toCopy)
PulseLayer::canGetMic() PulseLayer::canGetMic()
{ {
if( record ) if( record )
{ return _micRingBuffer.AvailForGet();
//int a = _micRingBuffer.AvailForGet();
//return a;
int a = pa_stream_readable_size( record );
_debug("available: %i\n" , a);
return 2048;
}
else else
return 0; return 0;
} }
...@@ -250,8 +196,7 @@ PulseLayer::canGetMic() ...@@ -250,8 +196,7 @@ PulseLayer::canGetMic()
PulseLayer::getMic(void *buffer, int toCopy) PulseLayer::getMic(void *buffer, int toCopy)
{ {
if( record ){ if( record ){
//return _micRingBuffer.Get(buffer, toCopy, 100); return _micRingBuffer.Get(buffer, toCopy, 100);
return readbuffer( buffer, toCopy );
} }
else else
return 0; return 0;
...@@ -263,24 +208,23 @@ PulseLayer::flushMic() ...@@ -263,24 +208,23 @@ PulseLayer::flushMic()
_micRingBuffer.flush(); _micRingBuffer.flush();
} }
/* bool
PulseLayer::isStreamStopped (void)
{
}
*/
void void
PulseLayer::startStream (void) PulseLayer::startStream (void)
{ {
_micRingBuffer.flush();
_debug("Start stream\n"); _debug("Start stream\n");
//pa_stream_cork( record, NULL, NULL, NULL); pa_threaded_mainloop_lock(m);
//pa_stream_cork( playback, NULL, NULL, NULL); pa_stream_cork( record->pulseStream(), NULL, NULL, NULL);
pa_threaded_mainloop_unlock(m);
} }
void void
PulseLayer::stopStream (void) PulseLayer::stopStream (void)
{ {
_debug("Stop stream\n"); _debug("Stop stream\n");
//pa_stream_drop( playback ); pa_stream_flush( playback->pulseStream(), NULL, NULL );
pa_stream_flush( record->pulseStream(), NULL, NULL );
flushMic();
} }
bool bool
...@@ -294,8 +238,7 @@ PulseLayer::audioCallback ( pa_stream* s, size_t bytes, void* userdata ) ...@@ -294,8 +238,7 @@ PulseLayer::audioCallback ( pa_stream* s, size_t bytes, void* userdata )
PulseLayer* pulse = (PulseLayer*) userdata; PulseLayer* pulse = (PulseLayer*) userdata;
assert( s && bytes ); assert( s && bytes );
assert( bytes > 0 ); assert( bytes > 0 );
pulse->write(); pulse->processData();
//pulse->read();
} }
void void
...@@ -312,15 +255,32 @@ PulseLayer::overflow ( pa_stream* s, void* userdata ) ...@@ -312,15 +255,32 @@ PulseLayer::overflow ( pa_stream* s, void* userdata )
} }
void void
PulseLayer::write( void ) PulseLayer::processData( void )
{ {
// a = pa_stream_get_buffer_attr(record->pulseStream()); const char* data;
//if (a) size_t r;
//_debug("Buffer attributes: maxlength=%u , fragsize=%u\n" , a->maxlength, a->fragsize );
//_debug("Device name = %s ; device index = %i\n" , pa_stream_get_device_name( playback->pulseStream()) , pa_stream_get_device_index( playback->pulseStream()));
int toGet; int toGet;
int urgentAvail; // number of data right and data left int urgentAvail; // number of data right and data left
int normalAvail; // number of data right and data left int normalAvail; // number of data right and data left
// Handle the mic also
if( (record->pulseStream()) && pa_stream_get_state( record->pulseStream()) == PA_STREAM_READY) {
if( pa_stream_peek( record->pulseStream() , (const void**)&data , &r ) < 0 || !data ){
_debug("pa_stream_peek() failed: %s\n" , pa_strerror( pa_context_errno( context) ));
return;
}
if( data != 0 ){
_micRingBuffer.Put( (void*)data , r, 100);
}
if( pa_stream_drop( record->pulseStream() ) < 0 ) {
_debug("pa_stream_drop() failed: %s\n" , pa_strerror( pa_context_errno( context) ));
return;
}
}
SFLDataFormat* out = (SFLDataFormat*)pa_xmalloc(framesPerBuffer * sizeof(SFLDataFormat)); SFLDataFormat* out = (SFLDataFormat*)pa_xmalloc(framesPerBuffer * sizeof(SFLDataFormat));
urgentAvail = _urgentRingBuffer.AvailForGet(); urgentAvail = _urgentRingBuffer.AvailForGet();
if (urgentAvail > 0) { if (urgentAvail > 0) {
...@@ -352,36 +312,7 @@ PulseLayer::write( void ) ...@@ -352,36 +312,7 @@ PulseLayer::write( void )
} }
} }
} }
pa_stream_write( playback , out , toGet , pa_xfree, 0 , PA_SEEK_RELATIVE); pa_stream_write( playback->pulseStream() , out , toGet , pa_xfree, 0 , PA_SEEK_RELATIVE);
}
void
PulseLayer::read( void )
{
if( (record) && pa_stream_get_state( record) == PA_STREAM_READY) {
size_t n = pa_stream_readable_size( record);
if( n == (size_t) -1 ){
_debug("pa_stream_readable_size(): %s\n" , pa_strerror( pa_context_errno( context )) );
return;
}
const char* data;
size_t r;
/*if( pa_stream_peek( record , (const void**)&data , &r ) < 0 || !data ){
_debug("pa_stream_peek() failed: %s\n" , pa_strerror( pa_context_errno( context) ));
return;
}
_micRingBuffer.Put( (void*)data , r, 100);
if( pa_stream_drop( record ) < 0 ) {
_debug("pa_stream_drop() failed: %s\n" , pa_strerror( pa_context_errno( context) ));
return;
}*/
}
} }
int int
...@@ -392,20 +323,3 @@ PulseLayer::putInCache( char code, void *buffer, int toCopy ) ...@@ -392,20 +323,3 @@ PulseLayer::putInCache( char code, void *buffer, int toCopy )
//pa_stream_finish_upload( cache->pulseStream() ); //pa_stream_finish_upload( cache->pulseStream() );
} }
int
PulseLayer::readbuffer( void* data , int bytes )
{
if( (record) && pa_stream_get_state( record) == PA_STREAM_READY) {
size_t r = (size_t) bytes;
if( pa_stream_peek( record , (const void**)&data , &r ) < 0 || !data ){
_debug("pa_stream_peek() failed: %s\n" , pa_strerror( pa_context_errno( context) ));
return 0;
if( pa_stream_drop( record ) < 0 ) {
_debug("pa_stream_drop() failed: %s\n" , pa_strerror( pa_context_errno( context) ));
return 0;
}
}
return bytes;
}
}
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#define _PULSE_LAYER_H #define _PULSE_LAYER_H
#include "audiolayer.h" #include "audiolayer.h"
//#include "audiostream.h" #include "audiostream.h"
class RingBuffer; class RingBuffer;
class ManagerImpl; class ManagerImpl;
...@@ -126,9 +126,7 @@ class PulseLayer : public AudioLayer { ...@@ -126,9 +126,7 @@ class PulseLayer : public AudioLayer {
*/ */
void closeCaptureStream( void ); void closeCaptureStream( void );
void write( void ); void processData( void );
void read( void );
int readbuffer( void* data, int bytes );
void createStreams( pa_context* c ); void createStreams( pa_context* c );
/** /**
* Drop the pending frames and close the playback device * Drop the pending frames and close the playback device
...@@ -146,12 +144,12 @@ class PulseLayer : public AudioLayer { ...@@ -146,12 +144,12 @@ class PulseLayer : public AudioLayer {
pa_context* context; pa_context* context;
pa_threaded_mainloop* m; pa_threaded_mainloop* m;
//AudioStream* playback; AudioStream* playback;
//AudioStream* record; AudioStream* record;
//AudioStream* cache; //AudioStream* cache;
pa_stream* playback; //pa_stream* playback;
pa_stream* record; //pa_stream* record;
}; };
#endif // _PULSE_LAYER_H_ #endif // _PULSE_LAYER_H_
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment