diff --git a/src/audio/Makefile.am b/src/audio/Makefile.am index 13bb710847217ab361407cd1306492841f5b7030..c65f297c5a4906131d65769d2e21be80c7d80783 100644 --- a/src/audio/Makefile.am +++ b/src/audio/Makefile.am @@ -23,15 +23,15 @@ endif SUBDIRS = codecs libaudio_la_SOURCES = audiofile.cpp tonelist.cpp \ -audiortp.cpp dtmf.cpp tone.cpp alsalayer.cpp pulselayer.cpp audiodevice.cpp dtmfgenerator.cpp \ -tonegenerator.cpp codecDescriptor.cpp \ +audiortp.cpp audiostream.cpp dtmf.cpp tone.cpp alsalayer.cpp pulselayer.cpp audiodevice.cpp dtmfgenerator.cpp \ +tonegenerator.cpp codecDescriptor.cpp samplecache.cpp\ audioloop.cpp ringbuffer.cpp $(SPEEX_SOURCES_CPP) AM_CXXFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/libs $(libccext2_CFLAGS) $(libdbuscpp_CFLAGS) $(libccrtp1_CFLAGS) $(USER_INCLUDES) \ -DCODECS_DIR=\""$(sflcodecdir)"\" $(SPEEX_FLAG) $(GSM_FLAG) $(ILBC_FLAG) -noinst_HEADERS = audioloop.h common.h ringbuffer.h audiofile.h \ +noinst_HEADERS = audioloop.h audiostream.h common.h ringbuffer.h audiofile.h \ tonelist.h audiortp.h audiolayer.h alsalayer.h pulselayer.h audiodevice.h \ - dtmfgenerator.h tonegenerator.h \ + dtmfgenerator.h tonegenerator.h samplecache.h \ codecDescriptor.h dtmf.h tone.h diff --git a/src/audio/audiostream.cpp b/src/audio/audiostream.cpp new file mode 100644 index 0000000000000000000000000000000000000000..02deda2559781a3a81756e31af42bf144c67010a --- /dev/null +++ b/src/audio/audiostream.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2008 Savoir-Faire Linux inc. + * Author: Emmanuel Milou <emmanuel.milou@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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <audiostream.h> + +static pa_channel_map channel_map ; + +AudioStream::AudioStream( pa_context* context, int type, std::string desc ) +{ + _streamType = type; + _streamDescription = desc; + sample_spec.format = PA_SAMPLE_S16LE; + sample_spec.rate = 44100; + sample_spec.channels = 1; + channel_map.channels = 1; + flag = PA_STREAM_AUTO_TIMING_UPDATE; + + _audiostream = createStream( context ); +} + +AudioStream::~AudioStream() +{ +} + + void +AudioStream::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; + } +} + + + pa_stream* +AudioStream::createStream( pa_context* c ) +{ + _debug("Creating %s stream...\n" , _streamDescription.c_str()); + pa_stream* s; + + assert(pa_sample_spec_valid(&sample_spec)); + assert(pa_channel_map_valid(&channel_map)); + + if( !( s = pa_stream_new( c, _streamDescription.c_str() , &sample_spec, &channel_map ) ) ) + _debug("%s: pa_stream_new() failed : %s\n" , _streamDescription.c_str(), pa_strerror( pa_context_errno( c))); + + assert( s ); + + if( _streamType == PLAYBACK_STREAM ){ + pa_stream_connect_playback( s , NULL , NULL , flag , NULL, NULL ); + //pa_stream_set_write_callback( s , audioCallback, this); + } + else if( _streamType == CAPTURE_STREAM ){ + pa_stream_connect_record( s , NULL , NULL , flag ); + //pa_stream_set_read_callback( s , audioCallback, this); + } + else if( _streamType == UPLOAD_STREAM ){ + //pa_stream_connect_upload( s , 1024 ); + } + else{ + _debug( "Stream type unknown \n"); + } + + pa_stream_set_state_callback( s , stream_state_callback, NULL); + + return s; +} + diff --git a/src/audio/audiostream.h b/src/audio/audiostream.h new file mode 100644 index 0000000000000000000000000000000000000000..a4464500f58759463daf1affaf9ef64b36169565 --- /dev/null +++ b/src/audio/audiostream.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2008 Savoir-Faire Linux inc. + * Author: Emmanuel Milou <emmanuel.milou@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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _AUDIO_STREAM_H +#define _AUDIO_STREAM_H + +#include <pulse/pulseaudio.h> +#include <string> + +#include "../global.h" +#include "ringbuffer.h" +#include "audioloop.h" + +enum STREAM_TYPE { + PLAYBACK_STREAM, + CAPTURE_STREAM, + UPLOAD_STREAM +}; + + +class AudioStream { + public: + AudioStream(pa_context* context , int type, std::string desc); + ~AudioStream(); + + int putMain( void* buffer , int toCopy ); + int putUrgent( void* buffer , int toCopy ); + + pa_stream* pulseStream(){ return _audiostream; } + + private: + pa_stream* createStream( pa_context* c ); + + static void stream_state_callback( pa_stream* s, void* user_data ); + static void audioCallback ( pa_stream* s, size_t bytes, void* userdata ); + void write( void ); + + int _streamType; + std::string _streamDescription; + + + pa_stream* _audiostream; + pa_stream_flags_t flag; + pa_sample_spec sample_spec ; + //pa_channel_map channel_map; + +}; + +#endif // _AUDIO_STREAM_H diff --git a/src/audio/dtmf.cpp b/src/audio/dtmf.cpp index a5e9f7fa6b2e6cd796033b3234dbf7d90df2a8aa..faabf1d69aad7fe79369b669e157756066534d15 100644 --- a/src/audio/dtmf.cpp +++ b/src/audio/dtmf.cpp @@ -77,3 +77,4 @@ DTMF::generateDTMF (SFLDataFormat* buffer, size_t n) return false; } } + diff --git a/src/audio/pulselayer.cpp b/src/audio/pulselayer.cpp index 6e1be72dc20e747842d1b9640b7d5723d51c069b..121c7f0048913e25b6d81a1fbfad51a69eef6430 100644 --- a/src/audio/pulselayer.cpp +++ b/src/audio/pulselayer.cpp @@ -19,23 +19,13 @@ #include "pulselayer.h" -static pa_context *context = NULL; -static pa_stream* playback = NULL; -static pa_stream* record = NULL; -static pa_mainloop_api *mainloop_api = NULL; -static pa_threaded_mainloop *m = NULL; -static pa_sample_spec sample_spec ; +int framesPerBuffer = 1024; -static pa_channel_map channel_map; - -static std::string pcm_p, pcm_r; - -int framesPerBuffer = 882; - - PulseLayer::PulseLayer(ManagerImpl* manager) +PulseLayer::PulseLayer(ManagerImpl* manager) : AudioLayer( manager , PULSEAUDIO ) - , _mainSndRingBuffer( SIZEBUF ) + , _urgentRingBuffer( SIZEBUF) + ,_mainSndRingBuffer( SIZEBUF ) { _debug("Pulse audio constructor: Create context\n"); } @@ -43,11 +33,10 @@ int framesPerBuffer = 882; // Destructor PulseLayer::~PulseLayer (void) { - assert(mainloop_api); - //mainloop_api->quit( mainloop_api, 0 ); - pa_stream_flush( playback , NULL, NULL); - pa_stream_disconnect( playback ); - pa_context_disconnect(context); + delete playback; + delete record; + ////delete cache; + pa_context_disconnect(context); } void @@ -75,33 +64,12 @@ PulseLayer::connectPulseServer( void ) _debug("Context creation done\n"); } - 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 PulseLayer::context_state_callback( pa_context* c, void* user_data ) { _debug("The state of the context changed\n"); PulseLayer* pulse = (PulseLayer*)user_data; - //pa_stream_flags_t flag = PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE ; - assert(c && m); + assert(c && pulse->m); switch(pa_context_get_state(c)){ case PA_CONTEXT_CONNECTING: case PA_CONTEXT_AUTHORIZING: @@ -110,7 +78,6 @@ PulseLayer::context_state_callback( pa_context* c, void* user_data ) break; case PA_CONTEXT_READY: pa_cvolume cv; - assert(c && !playback && !record); pulse->createStreams( c ); _debug("Connection to PulseAudio server established\n"); break; @@ -119,7 +86,7 @@ PulseLayer::context_state_callback( pa_context* c, void* user_data ) break; case PA_CONTEXT_FAILED: default: - _debug(" Error : %s" , pa_strerror(pa_context_errno(context))); + _debug(" Error : %s" , pa_strerror(pa_context_errno(c))); exit(1); } } @@ -127,47 +94,13 @@ PulseLayer::context_state_callback( pa_context* c, void* user_data ) void PulseLayer::createStreams( pa_context* c ) { - _debug( " Create Audio Streams \n "); - //pa_stream_flags_t flag = PA_STREAM_AUTO_TIMING_UPDATE; - pa_stream_flags_t flag = PA_STREAM_FIX_RATE; - sample_spec.format = PA_SAMPLE_S16LE; - sample_spec.rate = 44100; - sample_spec.channels = 1; - channel_map.channels = 1; - - if( !pa_sample_spec_valid( &sample_spec ) ){ - _debug("Invalid sample specifications\n"); - exit(0); - } - - 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))); - exit(0); - } - - if(!(record = pa_stream_new( c, "SFLphone Mic" , &sample_spec, &channel_map))){ - _debug("Capture: pa_stream_new() failed : %s\n" , pa_strerror( pa_context_errno( c))); - exit(0); - } - - assert(playback); - assert(record); - assert(m); - - // Set up the parameters required to open a (Callback)Stream: - - pa_stream_connect_playback( playback, NULL , NULL , flag , NULL, NULL ); - pa_stream_set_state_callback(playback, stream_state_callback, NULL); - // Transferring Data - Asynchronous Mode - pa_stream_set_write_callback(playback, audioCallback, this); + playback = new AudioStream(c, PLAYBACK_STREAM, "SFLphone out"); + pa_stream_set_write_callback( playback->pulseStream() , audioCallback, this); + record = new AudioStream(c, CAPTURE_STREAM, "SFLphone in"); + pa_stream_set_read_callback( record->pulseStream() , audioCallback, this); + //cache = new AudioStream(c, UPLOAD_STREAM, "Cache samples"); pa_threaded_mainloop_signal(m , 0); - - pa_stream_set_state_callback(record, stream_state_callback, NULL); - // Transferring Data - Asynchronous Mode - pa_stream_set_read_callback(record, audioCallback, this); - pa_stream_connect_record( record, NULL , NULL , flag ); - } bool @@ -223,7 +156,6 @@ PulseLayer::putMain(void* buffer, int toCopy) _debug("Chopping sound, Ouch! RingBuffer full ?\n"); return _mainSndRingBuffer.Put(buffer, a, 100); } - return 0; } @@ -235,6 +167,13 @@ PulseLayer::flushMain() int PulseLayer::putUrgent(void* buffer, int toCopy) { + int a = _urgentRingBuffer.AvailForPut(); + if ( a >= toCopy ) { + return _urgentRingBuffer.Put(buffer, toCopy, 100 ); + } else { + return _urgentRingBuffer.Put(buffer, a, 100 ); + } + return 0; } int @@ -254,23 +193,22 @@ PulseLayer::flushMic() { } - bool +/* bool PulseLayer::isStreamStopped (void) { } - +*/ void PulseLayer::startStream (void) { _debug("Start stream\n"); - //pa_stream_cork( playback , 0, NULL, NULL); } void PulseLayer::stopStream (void) { _debug("Stop stream\n"); - pa_stream_drop( playback ); + //pa_stream_drop( playback ); } bool @@ -281,67 +219,47 @@ PulseLayer::isStreamActive (void) void PulseLayer::audioCallback ( pa_stream* s, size_t bytes, void* userdata ) { - pa_threaded_mainloop_signal( m , 0); - - assert( s && bytes ); - PulseLayer* pulse = (PulseLayer*) userdata; + assert( s && bytes ); pulse->write(); - //if(pa_stream_get_state(s) == PA_STREAM_READY ) - //{ - //if( bytes > 0 ){ - // pa_stream_write( s, user_data, bytes, pa_xfree, 0, PA_SEEK_RELATIVE ); - //} - //} - // pa_stream_write - // // pa_stream_peek ( to read the next fragment from the buffer ) / pa_stream_drop( to remove the data from the buffer ) - // - // int toPut; - // int urgentAvail; // number of data right and data left - // int micAvailPut; - // - // // AvailForGet tell the number of chars inside the buffer - // // framePerBuffer are the number of data for one channel (left) - // urgentAvail = _urgentRingBuffer.AvailForGet(); - // if (urgentAvail > 0) { - // // Urgent data (dtmf, incoming call signal) come first. - // toGet = (urgentAvail < (int)(framesPerBuffer * sizeof(SFLDataFormat))) ? urgentAvail : framesPerBuffer * sizeof(SFLDataFormat); - // _urgentRingBuffer.Get(out, toGet, spkrVolume); - // // Consume the regular one as well (same amount of bytes) - // _mainSndRingBuffer.Discard(toGet); - // } else { - // AudioLoop* tone = _manager->getTelephoneTone(); - // if ( tone != 0) { - // tone->getNext(out, framesPerBuffer, spkrVolume); - // } else if ( (tone=_manager->getTelephoneFile()) != 0 ) { - // tone->getNext(out, framesPerBuffer, spkrVolume); - // } else { - - // } - // } - // - // // Additionally handle the mic's audio stream - // micAvailPut = _micRingBuffer.AvailForPut(); - // toPut = (micAvailPut <= (int)(framesPerBuffer * sizeof(SFLDataFormat))) ? micAvailPut : framesPerBuffer * sizeof(SFLDataFormat); - // //_debug("AL: Nb sample: %d char, [0]=%f [1]=%f [2]=%f\n", toPut, in[0], in[1], in[2]); - // _micRingBuffer.Put(in, toPut, micVolume); - } void PulseLayer::write( void ) { int toGet; + int urgentAvail; // number of data right and data left int normalAvail; // number of data right and data left SFLDataFormat* out = (SFLDataFormat*)malloc(framesPerBuffer * sizeof(SFLDataFormat)); - normalAvail = _mainSndRingBuffer.AvailForGet(); - toGet = (normalAvail < (int)(framesPerBuffer * sizeof(SFLDataFormat))) ? normalAvail : framesPerBuffer * sizeof(SFLDataFormat); - if (toGet) { - _mainSndRingBuffer.Get(out, toGet, 100); - _debug("Write %i bytes\n" , toGet); - pa_stream_write( playback , out , toGet , pa_xfree, 0 , PA_SEEK_RELATIVE); + urgentAvail = _urgentRingBuffer.AvailForGet(); + if (urgentAvail > 0) { + // Urgent data (dtmf, incoming call signal) come first. + _debug("Play urgent!\n"); + toGet = (urgentAvail < (int)(framesPerBuffer * sizeof(SFLDataFormat))) ? urgentAvail : framesPerBuffer * sizeof(SFLDataFormat); + _urgentRingBuffer.Get(out, toGet, 100); + // Consume the regular one as well (same amount of bytes) _mainSndRingBuffer.Discard(toGet); - } else { - bzero(out, framesPerBuffer * sizeof(SFLDataFormat)); } -} + else + { + AudioLoop* tone = _manager->getTelephoneTone(); + if ( tone != 0) { + tone->getNext(out, framesPerBuffer, 100); + toGet = framesPerBuffer; + } else if ( (tone=_manager->getTelephoneFile()) != 0 ) { + tone->getNext(out, framesPerBuffer, 100); + toGet = framesPerBuffer; + } else { + normalAvail = _mainSndRingBuffer.AvailForGet(); + toGet = (normalAvail < (int)(framesPerBuffer * sizeof(SFLDataFormat))) ? normalAvail : framesPerBuffer * sizeof(SFLDataFormat); + if (toGet) { + _mainSndRingBuffer.Get(out, toGet, 100); + _debug("Write %i bytes\n" , toGet); + _mainSndRingBuffer.Discard(toGet); + } else { + bzero(out, framesPerBuffer * sizeof(SFLDataFormat)); + } + } + } + pa_stream_write( playback->pulseStream() , out , toGet , pa_xfree, 0 , PA_SEEK_RELATIVE); +} diff --git a/src/audio/pulselayer.h b/src/audio/pulselayer.h index a63ce2319b635c524061e1722e5c4a3c658dd173..1593862c1eded324eef11c55d6e1d5b1d30e69fe 100644 --- a/src/audio/pulselayer.h +++ b/src/audio/pulselayer.h @@ -21,6 +21,7 @@ #define _PULSE_LAYER_H #include "audiolayer.h" +#include "audiostream.h" class RingBuffer; class ManagerImpl; @@ -48,8 +49,6 @@ class PulseLayer : public AudioLayer { void startStream(void); void stopStream(void); - bool isStreamActive(void); - bool isStreamStopped(void); /** * Check if the capture is running @@ -57,6 +56,7 @@ class PulseLayer : public AudioLayer { * false otherwise */ bool isCaptureActive( void ) { return true; } + bool isStreamActive (void); void flushMain(); int putMain(void* buffer, int toCopy); @@ -76,7 +76,6 @@ class PulseLayer : public AudioLayer { static void audioCallback ( pa_stream* s, size_t bytes, void* userdata ); - static void stream_state_callback( pa_stream* s, void* user_data ); static void context_state_callback( pa_context* c, void* user_data ); /** @@ -117,6 +116,8 @@ class PulseLayer : public AudioLayer { */ std::string getAudioPlugin( void ) { return "default"; } + //pa_stream* getCacheStream( void ) { return caching; } + private: /** * Drop the pending frames and close the capture device @@ -132,10 +133,17 @@ class PulseLayer : public AudioLayer { void connectPulseServer( void ); + /** Ringbuffers for data */ RingBuffer _mainSndRingBuffer; + RingBuffer _urgentRingBuffer; + + /** PulseAudio streams and context */ + pa_context* context; + pa_threaded_mainloop* m; - //pa_stream* playback; - //pa_stream* record; + AudioStream* playback; + AudioStream* record; + AudioStream* cache; }; diff --git a/src/audio/samplecache.cpp b/src/audio/samplecache.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2d15d82c64a682c892ddf003039bff5926a64fb8 --- /dev/null +++ b/src/audio/samplecache.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2008 Savoir-Faire Linux inc. + * Author: Emmanuel Milou <emmanuel.milou@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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <samplecache.h> + +SampleCache::SampleCache( pa_stream* s ) +{ + _stream = s ; +} + +SampleCache::~SampleCache() +{ + //delete _pulse; +} + +bool +SampleCache::uploadSample( SFLDataFormat* buffer , size_t size ) +{ + //pa_stream_write( pulse->caching , buffer , size , pa_xfree, 0 , PA_SEEK_RELATIVE); + //pa_stream_finish_upload( pulse->caching ); +} diff --git a/src/audio/samplecache.h b/src/audio/samplecache.h new file mode 100644 index 0000000000000000000000000000000000000000..655f791197134d2dddc60736e40d6ebd266de4d1 --- /dev/null +++ b/src/audio/samplecache.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2008 Savoir-Faire Linux inc. + * Author: Emmanuel Milou <emmanuel.milou@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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _SAMPLE_CACHE_H +#define _SAMPLE_CACHE_H + +#include <pulse/pulseaudio.h> +#include <audiolayer.h> + +class SampleCache { + + public: + SampleCache( pa_stream* stream ); + ~SampleCache(); + + bool uploadSample( SFLDataFormat* buffer, size_t size ); + bool removeSample( ); + bool isSampleCached( ); + + private: + pa_stream* _stream; + +}; + +#endif // _SAMPLE_CACHE_H diff --git a/src/global.h b/src/global.h index f6e9cd00f09f1a9476535cf569452198d965b7bb..a89b070f3e31b868b4fb8f48e21787a4b0b84ec0 100644 --- a/src/global.h +++ b/src/global.h @@ -124,7 +124,6 @@ typedef short int16; #define ALSA 0 #define PULSEAUDIO 1 -//#define AUDIODRIVER ALSA -#define CHECK_INTERFACE( layer , api ) (layer == api) +#define CHECK_INTERFACE( layer , api ) (layer != api) #endif // __GLOBAL_H__ diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp index 08f0360d4f35879c86b950b657e165a5d9042c39..7c176428fd3dfb19cacf4f1aae08b30c9243334c 100644 --- a/src/managerimpl.cpp +++ b/src/managerimpl.cpp @@ -473,6 +473,7 @@ ManagerImpl::playDtmf(char code, bool isTalking) // numbers of int = length in milliseconds / 1000 (number of seconds) // = number of seconds * SAMPLING_RATE by SECONDS AudioLayer* audiolayer = getAudioDriver(); + int layer = audiolayer->getLayerType(); // fast return, no sound, so no dtmf if (audiolayer==0 || _dtmfKey == 0) { return false; } @@ -496,7 +497,13 @@ ManagerImpl::playDtmf(char code, bool isTalking) // Put buffer to urgentRingBuffer // put the size in bytes... // so size * 1 channel (mono) * sizeof (bytes for the data) +#if CHECK_INTERFACE( layer , ALSA ) + _debug("%i No good\n", layer); audiolayer->playSamples(_buf, size * sizeof(SFLDataFormat), isTalking); +#else + _debug("%i Good\n" , layer); + audiolayer->putUrgent( _buf, size * sizeof(SFLDataFormat) ); +#endif } returnValue = true; @@ -822,13 +829,14 @@ ManagerImpl::ringtone() _audiofile.start(); _toneMutex.leaveMutex(); #if CHECK_INTERFACE( layer, ALSA ) + _debug() int size = _audiofile.getSize(); SFLDataFormat output[ size ]; _audiofile.getNext(output, size , 100); audiolayer->putUrgent( output , size ); #else // pulseaudio code - startStream(); + audiolayer->startStream(); #endif } else { ringback(); @@ -1491,7 +1499,6 @@ ManagerImpl::selectAudioDriver (void) int layer = _audiodriver->getLayerType(); _debug("Audio layer type: %i\n" , layer); -#if CHECK_INTERFACE( layer , ALSA ) std::string alsaPlugin = getConfigString( AUDIO , ALSA_PLUGIN ); int numCardIn = getConfigInt( AUDIO , ALSA_CARD_ID_IN ); int numCardOut = getConfigInt( AUDIO , ALSA_CARD_ID_OUT ); @@ -1514,13 +1521,15 @@ ManagerImpl::selectAudioDriver (void) setConfig( AUDIO , ALSA_CARD_ID_OUT , ALSA_DFT_CARD_ID ); } +#if CHECK_INTERFACE( layer , ALSA ) + _debug("No good\n"); _debugInit(" AudioLayer Opening Device"); _audiodriver->setErrorMessage(-1); _audiodriver->openDevice( numCardIn , numCardOut, sampleRate, frameSize, SFL_PCM_BOTH, alsaPlugin ); if( _audiodriver -> getErrorMessage() != -1 ) notifyErrClient( _audiodriver -> getErrorMessage()); #else - + _debug("Good\n"); _debug(" Pulse audio driver \n"); _audiodriver->openDevice( numCardIn , numCardOut, sampleRate, frameSize, SFL_PCM_BOTH, alsaPlugin ); if( _audiodriver -> getErrorMessage() != -1 )