mirror of
https://git.jami.net/savoirfairelinux/jami-daemon.git
synced 2025-08-07 22:02:12 +08:00
[#1314] Test pulse audio and audio streams connect and disconnect
This commit is contained in:
@ -34,7 +34,7 @@ AudioStream::AudioStream( pa_context* context, int type, std::string desc, doubl
|
||||
|
||||
_context = context;
|
||||
|
||||
connectStream();
|
||||
// connectStream();
|
||||
}
|
||||
|
||||
AudioStream::~AudioStream()
|
||||
@ -42,7 +42,7 @@ AudioStream::~AudioStream()
|
||||
disconnectStream();
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
AudioStream::connectStream()
|
||||
{
|
||||
ost::MutexLock guard(_mutex);
|
||||
@ -52,10 +52,12 @@ AudioStream::connectStream()
|
||||
else {
|
||||
disconnectStream();
|
||||
_audiostream = createStream( _context );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
AudioStream::disconnectStream( void )
|
||||
{
|
||||
ost::MutexLock guard(_mutex);
|
||||
@ -65,6 +67,8 @@ AudioStream::disconnectStream( void )
|
||||
pa_stream_unref( _audiostream );
|
||||
|
||||
_audiostream = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -73,12 +73,12 @@ class AudioStream {
|
||||
/**
|
||||
* Connect the pulse audio stream
|
||||
*/
|
||||
void connectStream();
|
||||
bool connectStream();
|
||||
|
||||
/**
|
||||
* Disconnect the pulseaudio stream
|
||||
*/
|
||||
void disconnectStream();
|
||||
bool disconnectStream();
|
||||
|
||||
/**
|
||||
* Accessor: Get the pulseaudio stream object
|
||||
|
@ -41,6 +41,7 @@ static void audioCallback ( pa_stream* s, size_t bytes, void* userdata )
|
||||
{
|
||||
PulseLayer::streamState = 0;
|
||||
_debug("PulseLayer::Pulse audio constructor: Create context\n");
|
||||
|
||||
}
|
||||
|
||||
// Destructor
|
||||
@ -132,11 +133,11 @@ bool PulseLayer::disconnectPulseAudioServer( void )
|
||||
_debug(" PulseLayer::disconnectPulseAudioServer( void ) \n");
|
||||
|
||||
if( playback ){
|
||||
playback->disconnectStream();
|
||||
// playback->disconnectStream();
|
||||
delete playback; playback=NULL;
|
||||
}
|
||||
if( record ){
|
||||
record->disconnectStream();
|
||||
// record->disconnectStream();
|
||||
delete record; record=NULL;
|
||||
}
|
||||
if (!playback && !record)
|
||||
@ -146,22 +147,26 @@ bool PulseLayer::disconnectPulseAudioServer( void )
|
||||
}
|
||||
|
||||
|
||||
void PulseLayer::createStreams( pa_context* c )
|
||||
bool PulseLayer::createStreams( pa_context* c )
|
||||
{
|
||||
_debug("PulseLayer::createStreams \n");
|
||||
|
||||
playback = new AudioStream(c, PLAYBACK_STREAM, PLAYBACK_STREAM_NAME, _manager->getSpkrVolume());
|
||||
playback->connectStream();
|
||||
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());
|
||||
record->connectStream();
|
||||
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);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -189,7 +194,7 @@ bool PulseLayer::openDevice(int indexIn UNUSED, int indexOut UNUSED, int sampleR
|
||||
// startStream();
|
||||
|
||||
_debug("Connection Done!! \n");
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
void PulseLayer::closeCaptureStream( void )
|
||||
|
@ -153,7 +153,7 @@ class PulseLayer : public AudioLayer {
|
||||
* Create the audio streams into the given context
|
||||
* @param c The pulseaudio context
|
||||
*/
|
||||
void createStreams( pa_context* c );
|
||||
bool createStreams( pa_context* c );
|
||||
|
||||
/**
|
||||
* Drop the pending frames and close the playback device
|
||||
@ -192,9 +192,12 @@ class PulseLayer : public AudioLayer {
|
||||
int spkrVolume;
|
||||
int micVolume;
|
||||
|
||||
// private:
|
||||
|
||||
public:
|
||||
static int streamState;
|
||||
|
||||
friend class AudioLayerTest;
|
||||
};
|
||||
|
||||
#endif // _PULSE_LAYER_H_
|
||||
|
206
sflphone-common/test/audiolayerTest.cpp
Normal file
206
sflphone-common/test/audiolayerTest.cpp
Normal file
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (C) 2009 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 <stdio.h>
|
||||
#include <sstream>
|
||||
|
||||
#include "audiolayerTest.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
|
||||
|
||||
void AudioLayerTest::setUp(){
|
||||
|
||||
// Instanciate the manager
|
||||
Manager::instance().initConfigFile();
|
||||
Manager::instance().init();
|
||||
|
||||
// _audiodriver = Manager::instance().getAudioDriver();
|
||||
|
||||
// std::string alsaPlugin;
|
||||
// AlsaLayer *alsalayer;
|
||||
|
||||
// int numCardIn, numCardOut, sampleRate, frameSize;
|
||||
// layer = _audiodriver->getLayerType();
|
||||
|
||||
/*
|
||||
alsaPlugin = Manager::instance().getConfigString( AUDIO , ALSA_PLUGIN );
|
||||
numCardIn = Manager::instance().getConfigInt( AUDIO , ALSA_CARD_ID_IN );
|
||||
numCardOut = Manager::instance().getConfigInt( AUDIO , ALSA_CARD_ID_OUT );
|
||||
sampleRate = Manager::instance().getConfigInt( AUDIO , ALSA_SAMPLE_RATE );
|
||||
if (sampleRate <=0 || sampleRate > 48000) {
|
||||
sampleRate = 44100;
|
||||
}
|
||||
frameSize = Manager::instance().getConfigInt(AUDIO, ALSA_FRAME_SIZE );
|
||||
*/
|
||||
|
||||
// get a pointer to the audio layer
|
||||
// _audiodriver = Manager::instance().getAudioDriver();
|
||||
|
||||
}
|
||||
|
||||
void AudioLayerTest::testAudioLayerConfig(){
|
||||
int sampling_rate = Manager::instance().getConfigInt(AUDIO, ALSA_SAMPLE_RATE);
|
||||
int frame_size = Manager::instance().getConfigInt(AUDIO, ALSA_FRAME_SIZE);
|
||||
|
||||
CPPUNIT_ASSERT(Manager::instance().getAudioDriver()->getSampleRate() == sampling_rate);
|
||||
CPPUNIT_ASSERT(Manager::instance().getAudioDriver()->getFrameSize() == frame_size);
|
||||
}
|
||||
|
||||
void AudioLayerTest::testAudioLayerSwitch(){
|
||||
|
||||
_debug("---------- AudioLayerTest::testAudioLayerSwitch ---------------------------\n");
|
||||
|
||||
|
||||
int previous_layer = Manager::instance().getAudioDriver()->getLayerType();
|
||||
|
||||
for(int i = 0; i < 2; i++) {
|
||||
_debug("---------- AudioLayerTest::testAudioLayerSwitch - %i -------------\n",i);
|
||||
Manager::instance().switchAudioManager();
|
||||
if(previous_layer == ALSA) {
|
||||
CPPUNIT_ASSERT(Manager::instance().getAudioDriver()->getLayerType() == PULSEAUDIO);
|
||||
}
|
||||
else {
|
||||
CPPUNIT_ASSERT(Manager::instance().getAudioDriver()->getLayerType() == ALSA);
|
||||
}
|
||||
previous_layer = Manager::instance().getAudioDriver()->getLayerType();
|
||||
usleep(100000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AudioLayerTest::testPulseConnect(){
|
||||
|
||||
_debug("---------- AudioLayerTest::testPulseConnect ---------------------------\n");
|
||||
|
||||
ManagerImpl* manager;
|
||||
manager = &Manager::instance();
|
||||
|
||||
_pulselayer = new PulseLayer(manager);
|
||||
|
||||
CPPUNIT_ASSERT(_pulselayer->getLayerType() == PULSEAUDIO);
|
||||
|
||||
std::string alsaPlugin;
|
||||
int numCardIn, numCardOut, sampleRate, frameSize;
|
||||
|
||||
alsaPlugin = manager->getConfigString( AUDIO , ALSA_PLUGIN );
|
||||
numCardIn = manager->getConfigInt( AUDIO , ALSA_CARD_ID_IN );
|
||||
numCardOut = manager->getConfigInt( AUDIO , ALSA_CARD_ID_OUT );
|
||||
sampleRate = manager->getConfigInt( AUDIO , ALSA_SAMPLE_RATE );
|
||||
frameSize = manager->getConfigInt(AUDIO, ALSA_FRAME_SIZE );
|
||||
|
||||
CPPUNIT_ASSERT(_pulselayer->getPlaybackStream() == NULL);
|
||||
CPPUNIT_ASSERT(_pulselayer->getRecordStream() == NULL);
|
||||
|
||||
_pulselayer->setErrorMessage(-1);
|
||||
try {
|
||||
CPPUNIT_ASSERT(_pulselayer->openDevice(numCardIn, numCardOut, sampleRate, frameSize, SFL_PCM_BOTH, alsaPlugin) == true);
|
||||
}
|
||||
catch (...) {
|
||||
_debug("Exception occured wile opening device! \n");
|
||||
}
|
||||
|
||||
usleep(100000);
|
||||
|
||||
CPPUNIT_ASSERT(_pulselayer->getPlaybackStream() != NULL);
|
||||
CPPUNIT_ASSERT(_pulselayer->getRecordStream() != NULL);
|
||||
|
||||
CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->pulseStream() != NULL);
|
||||
CPPUNIT_ASSERT(_pulselayer->getRecordStream()->pulseStream() != NULL);
|
||||
|
||||
// Must return Access failure "PA_ERR_ACCESS" == 2
|
||||
CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->getStreamState() == 2);
|
||||
CPPUNIT_ASSERT(_pulselayer->getRecordStream()->getStreamState() == 2);
|
||||
|
||||
CPPUNIT_ASSERT(_pulselayer->createStreams(_pulselayer->context) == true);
|
||||
|
||||
// usleep(1000000);
|
||||
|
||||
CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->pulseStream() != NULL);
|
||||
CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->pulseStream() != NULL);
|
||||
|
||||
// Must return No error "PA_OK" == 1
|
||||
CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->getStreamState() == 1);
|
||||
CPPUNIT_ASSERT(_pulselayer->getRecordStream()->getStreamState() == 1);
|
||||
|
||||
CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->disconnectStream() == true);
|
||||
CPPUNIT_ASSERT(_pulselayer->getRecordStream()->disconnectStream() == true);
|
||||
|
||||
// _debug("%i\n",_pulselayer->getPlaybackStream()->getStreamState());
|
||||
|
||||
CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->connectStream() == true);
|
||||
CPPUNIT_ASSERT(_pulselayer->getRecordStream()->connectStream() == true);
|
||||
|
||||
CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->getStreamState() == 1);
|
||||
CPPUNIT_ASSERT(_pulselayer->getRecordStream()->getStreamState() == 1);
|
||||
|
||||
CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->connectStream() == true);
|
||||
CPPUNIT_ASSERT(_pulselayer->getRecordStream()->connectStream() == true);
|
||||
|
||||
CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->getStreamState() == 1);
|
||||
CPPUNIT_ASSERT(_pulselayer->getRecordStream()->getStreamState() == 1);
|
||||
|
||||
// usleep(1000000);
|
||||
CPPUNIT_ASSERT(_pulselayer->disconnectPulseAudioServer() == true);
|
||||
}
|
||||
|
||||
|
||||
void AudioLayerTest::testAlsaConnect(){
|
||||
|
||||
_debug("---------- AudioLayerTest::testAlsaConnect ---------------------------\n");
|
||||
|
||||
int layer = Manager::instance().getAudioDriver()->getLayerType();
|
||||
|
||||
int type, samplerate, framesize, numCardIn, numCardOut;
|
||||
std::string alsaPlugin;
|
||||
|
||||
if (layer != ALSA) {
|
||||
Manager::instance().switchAudioManager();
|
||||
usleep(100000);
|
||||
}
|
||||
|
||||
// _audiolayer = Manager::instance().getAudioDriver();
|
||||
|
||||
// CPPUNIT_ASSERT(_audiolayer->closeLayer() == true);
|
||||
// usleep(100000);
|
||||
|
||||
// delete _audiolayer; _audiolayer == NULL;
|
||||
|
||||
Manager::instance().setConfig( PREFERENCES, CONFIG_AUDIO, ALSA);
|
||||
|
||||
|
||||
// _audiolayer->setErrorMessage(-1);
|
||||
// CPPUNIT_ASSERT(Manager::instance().initAudioDriver() == true);
|
||||
|
||||
// _audiolayer = Manager::instance().getAudioDriver();
|
||||
|
||||
// CPPUNIT_ASSERT(_audiolayer->getLayerType() == ALSA);
|
||||
|
||||
}
|
||||
|
||||
void AudioLayerTest::tearDown(){
|
||||
// Delete the audio recorder module
|
||||
// delete _ar; _ar = NULL;
|
||||
}
|
92
sflphone-common/test/audiolayerTest.h
Normal file
92
sflphone-common/test/audiolayerTest.h
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2009 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.
|
||||
*/
|
||||
|
||||
// Cppunit import
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
#include <cppunit/TestCaller.h>
|
||||
#include <cppunit/TestCase.h>
|
||||
#include <cppunit/TestSuite.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
// Application import
|
||||
#include "manager.h"
|
||||
|
||||
#include "config/config.h"
|
||||
#include "user_cfg.h"
|
||||
|
||||
#include "audio/audiolayer.h"
|
||||
#include "audio/alsalayer.h"
|
||||
#include "audio/pulselayer.h"
|
||||
|
||||
/*
|
||||
* @file audiorecorderTest.cpp
|
||||
* @brief Regroups unitary tests related to the plugin manager.
|
||||
*/
|
||||
|
||||
#ifndef _AUDIOLAYER_TEST_
|
||||
#define _AUDIOLAYER_TEST_
|
||||
|
||||
|
||||
|
||||
class AudioLayerTest : public CppUnit::TestCase {
|
||||
|
||||
/*
|
||||
* Use cppunit library macros to add unit test the factory
|
||||
*/
|
||||
CPPUNIT_TEST_SUITE( AudioLayerTest );
|
||||
CPPUNIT_TEST( testAudioLayerConfig );
|
||||
// CPPUNIT_TEST( testAudioLayerSwitch );
|
||||
CPPUNIT_TEST( testPulseConnect );
|
||||
// CPPUNIT_TEST( testAlsaConnect );
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
AudioLayerTest() : CppUnit::TestCase("Audio Layer Tests") {}
|
||||
|
||||
/*
|
||||
* Code factoring - Common resources can be initialized here.
|
||||
* This method is called by unitcpp before each test
|
||||
*/
|
||||
void setUp();
|
||||
|
||||
/*
|
||||
* Code factoring - Common resources can be released here.
|
||||
* This method is called by unitcpp after each test
|
||||
*/
|
||||
inline void tearDown();
|
||||
|
||||
void testAudioLayerConfig();
|
||||
void testAudioLayerSwitch();
|
||||
void testPulseConnect();
|
||||
void testAlsaConnect();
|
||||
|
||||
private:
|
||||
|
||||
ManagerImpl* manager;
|
||||
|
||||
PulseLayer* _pulselayer;
|
||||
|
||||
int layer;
|
||||
};
|
||||
|
||||
/* Register our test module */
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION( AudioLayerTest );
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user