mirror of
https://git.jami.net/savoirfairelinux/jami-daemon.git
synced 2025-08-12 22:09:25 +08:00
Pulse Audio PA_STREAM_START_CORKED mode now working
This commit is contained in:
@ -79,6 +79,8 @@ AudioStream::stream_state_callback( pa_stream* s, void* user_data UNUSED )
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
pa_stream*
|
||||
AudioStream::createStream( pa_context* c )
|
||||
{
|
||||
@ -100,7 +102,7 @@ AudioStream::createStream( pa_context* c )
|
||||
attributes->prebuf = 10000;
|
||||
attributes->minreq = 940;
|
||||
pa_stream_connect_playback( s , NULL , attributes,
|
||||
PA_STREAM_INTERPOLATE_TIMING,
|
||||
PA_STREAM_START_CORKED,
|
||||
&_volume, NULL);
|
||||
}
|
||||
else if( _streamType == CAPTURE_STREAM ){
|
||||
|
@ -30,6 +30,8 @@ static void audioCallback ( pa_stream* s, size_t bytes, void* userdata )
|
||||
static_cast<PulseLayer*>(userdata)->processData();
|
||||
}
|
||||
|
||||
|
||||
|
||||
PulseLayer::PulseLayer(ManagerImpl* manager)
|
||||
: AudioLayer( manager , PULSEAUDIO )
|
||||
, context(NULL)
|
||||
@ -106,7 +108,8 @@ void PulseLayer::context_state_callback( pa_context* c, void* user_data )
|
||||
break;
|
||||
case PA_CONTEXT_READY:
|
||||
pulse->createStreams( c );
|
||||
_debug("Connection to PulseAudio server established\n");
|
||||
_debug("Connection to PulseAudio server established\n");
|
||||
|
||||
break;
|
||||
case PA_CONTEXT_TERMINATED:
|
||||
_debug("Context terminated\n");
|
||||
@ -130,22 +133,27 @@ void PulseLayer::disconnectPulseAudioServer( void )
|
||||
delete record; record=NULL;
|
||||
}
|
||||
|
||||
void
|
||||
PulseLayer::createStreams( pa_context* c )
|
||||
|
||||
void PulseLayer::createStreams( pa_context* c )
|
||||
{
|
||||
_debug("PulseLayer::createStreams \n");
|
||||
|
||||
playback = new AudioStream(c, PLAYBACK_STREAM, PLAYBACK_STREAM_NAME, _manager->getSpkrVolume());
|
||||
pa_stream_set_write_callback( playback->pulseStream() , audioCallback, this);
|
||||
pa_stream_set_write_callback( playback->pulseStream(), audioCallback, this);
|
||||
//pa_stream_set_overflow_callback( playback->pulseStream() , overflow , this);
|
||||
// pa_stream_set_suspended_callback( playback->pulseStream(), stream_suspended_callback, this);
|
||||
|
||||
record = new AudioStream(c, CAPTURE_STREAM, CAPTURE_STREAM_NAME , _manager->getMicVolume());
|
||||
pa_stream_set_read_callback( record->pulseStream() , audioCallback, this);
|
||||
//pa_stream_set_underflow_callback( record->pulseStream() , underflow , this);
|
||||
// pa_stream_set_suspended_callback(record->pulseStream(), stream_suspended_callback, this);
|
||||
|
||||
|
||||
pa_threaded_mainloop_signal(m , 0);
|
||||
}
|
||||
|
||||
bool
|
||||
PulseLayer::openDevice(int indexIn UNUSED, int indexOut UNUSED, int sampleRate, int frameSize , int stream UNUSED, std::string plugin UNUSED)
|
||||
|
||||
bool PulseLayer::openDevice(int indexIn UNUSED, int indexOut UNUSED, int sampleRate, int frameSize , int stream UNUSED, std::string plugin UNUSED)
|
||||
{
|
||||
_debug("PulseLayer::openDevice \n");
|
||||
_sampleRate = sampleRate;
|
||||
@ -170,18 +178,15 @@ PulseLayer::openDevice(int indexIn UNUSED, int indexOut UNUSED, int sampleRate,
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
PulseLayer::closeCaptureStream( void )
|
||||
void PulseLayer::closeCaptureStream( void )
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
PulseLayer::closePlaybackStream( void )
|
||||
void PulseLayer::closePlaybackStream( void )
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
PulseLayer::canGetMic()
|
||||
int PulseLayer::canGetMic()
|
||||
{
|
||||
if( record )
|
||||
return _micRingBuffer.AvailForGet();
|
||||
@ -189,8 +194,7 @@ PulseLayer::canGetMic()
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
PulseLayer::getMic(void *buffer, int toCopy)
|
||||
int PulseLayer::getMic(void *buffer, int toCopy)
|
||||
{
|
||||
if( record ){
|
||||
return _micRingBuffer.Get(buffer, toCopy, 100);
|
||||
@ -199,15 +203,14 @@ PulseLayer::getMic(void *buffer, int toCopy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
PulseLayer::startStream (void)
|
||||
void PulseLayer::startStream (void)
|
||||
{
|
||||
flushMic();
|
||||
_debug("PulseLayer::Start stream\n");
|
||||
pa_threaded_mainloop_lock(m);
|
||||
|
||||
pa_stream_cork( playback->pulseStream(), NULL, NULL, NULL);
|
||||
pa_stream_cork( record->pulseStream(), NULL, NULL, NULL);
|
||||
pa_stream_cork( playback->pulseStream(), 0, NULL, NULL);
|
||||
pa_stream_cork( record->pulseStream(), 0, NULL, NULL);
|
||||
|
||||
pa_threaded_mainloop_unlock(m);
|
||||
|
||||
@ -220,8 +223,8 @@ PulseLayer::stopStream (void)
|
||||
pa_stream_flush( playback->pulseStream(), NULL, NULL );
|
||||
pa_stream_flush( record->pulseStream(), NULL, NULL );
|
||||
|
||||
pa_stream_cork( playback->pulseStream(), NULL, NULL, NULL);
|
||||
pa_stream_cork( record->pulseStream(), NULL, NULL, NULL);
|
||||
pa_stream_cork( playback->pulseStream(), 1, NULL, NULL);
|
||||
pa_stream_cork( record->pulseStream(), 1, NULL, NULL);
|
||||
|
||||
flushMic();
|
||||
flushMain();
|
||||
@ -230,44 +233,48 @@ PulseLayer::stopStream (void)
|
||||
|
||||
|
||||
|
||||
void
|
||||
PulseLayer::underflow ( pa_stream* s UNUSED, void* userdata UNUSED )
|
||||
void PulseLayer::underflow ( pa_stream* s UNUSED, void* userdata UNUSED )
|
||||
{
|
||||
_debug("PulseLayer::Buffer Underflow\n");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PulseLayer::overflow ( pa_stream* s, void* userdata UNUSED )
|
||||
void PulseLayer::overflow ( pa_stream* s, void* userdata UNUSED )
|
||||
{
|
||||
//PulseLayer* pulse = (PulseLayer*) userdata;
|
||||
pa_stream_drop( s );
|
||||
pa_stream_trigger( s, NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
PulseLayer::processData( void )
|
||||
void PulseLayer::stream_suspended_callback(pa_stream *s, void *userdata UNUSED )
|
||||
{
|
||||
// Handle the mic
|
||||
// We check if the stream is ready
|
||||
if( (record->pulseStream()) && (pa_stream_get_state( record->pulseStream()) == PA_STREAM_READY) && record)
|
||||
// _debug("PulseLayer::processData() readFromMic() \n");
|
||||
readFromMic();
|
||||
|
||||
}
|
||||
|
||||
// Handle the data for the speakers
|
||||
if( (playback->pulseStream()) && (pa_stream_get_state( playback->pulseStream()) == PA_STREAM_READY) && playback){
|
||||
void PulseLayer::processData( void )
|
||||
{
|
||||
|
||||
_debug("PulseLayer::processData() \n");
|
||||
|
||||
// Handle the mic
|
||||
// We check if the stream is ready
|
||||
if( (record->pulseStream()) && (pa_stream_get_state( record->pulseStream()) == PA_STREAM_READY))
|
||||
readFromMic();
|
||||
|
||||
// _debug("PulseLayer::processData() playback->pulseStream() \n");
|
||||
|
||||
// Handle the data for the speakers
|
||||
if( (playback->pulseStream()) && (pa_stream_get_state( playback->pulseStream()) == PA_STREAM_READY)){
|
||||
|
||||
// If the playback buffer is full, we don't overflow it; wait for it to have free space
|
||||
if( pa_stream_writable_size(playback->pulseStream()) == 0 )
|
||||
return;
|
||||
|
||||
// _debug("PulseLayer::processData() writeToSpeaker()\n");
|
||||
writeToSpeaker();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PulseLayer::writeToSpeaker( void )
|
||||
void PulseLayer::writeToSpeaker( void )
|
||||
{
|
||||
/** Bytes available in the urgent ringbuffer ( reserved for DTMF ) */
|
||||
int urgentAvail;
|
||||
@ -316,6 +323,7 @@ PulseLayer::writeToSpeaker( void )
|
||||
else {
|
||||
bzero(out, framesPerBuffer * sizeof(SFLDataFormat));
|
||||
}
|
||||
|
||||
pa_stream_write( playback->pulseStream() , out , toGet , NULL, 0 , PA_SEEK_RELATIVE);
|
||||
pa_xfree(out);
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "audiostream.h"
|
||||
|
||||
#include <pulse/pulseaudio.h>
|
||||
#include <pulse/stream.h>
|
||||
|
||||
#define PLAYBACK_STREAM_NAME "SFLphone out"
|
||||
#define CAPTURE_STREAM_NAME "SFLphone in"
|
||||
@ -74,7 +75,8 @@ class PulseLayer : public AudioLayer {
|
||||
static void overflow ( pa_stream* s, void* userdata );
|
||||
static void underflow ( pa_stream* s, void* userdata );
|
||||
static void stream_state_callback( pa_stream* s, void* user_data );
|
||||
static void context_state_callback( pa_context* c, void* user_data );
|
||||
static void context_state_callback( pa_context* c, void* user_data );
|
||||
static void stream_suspended_callback ( pa_stream* s, void* userdata );
|
||||
|
||||
bool isCaptureActive (void){return true;}
|
||||
|
||||
@ -127,6 +129,7 @@ class PulseLayer : public AudioLayer {
|
||||
void setMicVolume( int value ) { micVolume = value; }
|
||||
|
||||
void processData( void );
|
||||
|
||||
private:
|
||||
// Copy Constructor
|
||||
PulseLayer(const PulseLayer& rh);
|
||||
|
Reference in New Issue
Block a user