Import upstream version 0.99.2
[fmit.git] / src / CaptureThread.cpp
index 5c6f86b..9b93303 100644 (file)
@@ -42,9 +42,11 @@ void AddValue2ChannelFirst(CaptureThreadImpl* impl, double value, int i)
 void AddValue2ChannelMix(CaptureThreadImpl* impl, double value, int i)
 {
        if(i%2==0)
-               impl->m_capture_thread->m_values.push_front(value);
+        impl->m_tmp_value = value;
+//             impl->m_capture_thread->m_values.push_front(value);
        else
-               impl->m_capture_thread->m_values[0] = (impl->m_capture_thread->m_values[0]+value)/2.0;
+        impl->m_capture_thread->m_values.push_front((impl->m_tmp_value+value)/2.0);
+//             impl->m_capture_thread->m_values[0] = (impl->m_capture_thread->m_values[0]+value)/2.0;
 }
 void AddValue1Channel(CaptureThreadImpl* impl, double value, int i)
 {
@@ -102,7 +104,7 @@ void CaptureThread::autoDetectTransport()
        {
                m_current_impl = impl;
 
-               cerr << "using " << m_current_impl->m_name << endl;
+               cerr << "using " << m_current_impl->m_name.toStdString() << endl;
 
                if(m_current_impl->m_name!=old_name)
                        emit(transportChanged(m_current_impl->m_name));
@@ -120,7 +122,7 @@ void CaptureThread::autoDetectTransport()
 }
 void CaptureThread::selectTransport(const QString& name)
 {
-       cerr << "CaptureThread: INFO: using " << name << " transport" << endl;
+       cerr << "CaptureThread: INFO: using " << name.toStdString() << " transport" << endl;
        if(getCurrentTransport() && name==getCurrentTransport()->getName())     return;
 
        bool was_capturing = isCapturing();
@@ -138,7 +140,7 @@ void CaptureThread::selectTransport(const QString& name)
 
        if(impl==NULL)
        {
-               cerr << "CaptureThread: ERROR: unknown transport '" << name << "'" << endl;
+               cerr << "CaptureThread: ERROR: unknown transport '" << name.toStdString() << "'" << endl;
                throw QString("CaptureThread: ERROR: unknown transport '")+name+"'";
        }
 
@@ -155,7 +157,7 @@ void CaptureThread::selectTransport(int index)
        assert(index>=0 && index<m_impls.size());
 
        if(m_impls[index]==getCurrentTransport())       return;
-       cerr << "CaptureThread: INFO: change transport to " << m_impls[index]->getName() << " transport" << endl;
+               cerr << "CaptureThread: INFO: change transport to " << m_impls[index]->getName().toStdString() << " transport" << endl;
 
        bool was_capturing = isCapturing();
        if(was_capturing)
@@ -176,7 +178,7 @@ void CaptureThread::listTransports()
 {
        cerr << "CaptureThread: INFO: Built in transports" << endl;
        for(vector<CaptureThreadImpl*>::iterator it=m_impls.begin(); it!=m_impls.end(); it++)
-               cerr << "CaptureThread: INFO:   " << (*it)->getStatus() << "    " << (*it)->m_name << " " << (*it)->m_descr << endl;
+               cerr << "CaptureThread: INFO:   " << (*it)->getStatus().toStdString() << "      " << (*it)->m_name.toStdString() << "   " << (*it)->m_descr.toStdString() << endl;
 }
 const CaptureThreadImpl* CaptureThread::getCurrentTransport() const
 {
@@ -368,1177 +370,3 @@ void CaptureThreadImpl::setFormatDescrsAndFns(int format_size, bool format_signe
 
        cerr << "CaptureThread: INFO: format is " << (m_format_signed?"signed":"unsigned") << " " << (m_format_float?"float":"integer") << " " << m_format_size*8 << "bits with " << m_channel_count << " channel(s)" << endl;
 }
-
-// ------------------------------ ALSA implementation ----------------------------
-#ifdef CAPTURE_ALSA
-
-#define ALSA_BUFF_SIZE 1024
-
-void alsa_error_handler(const char *file, int line, const char *function, int err, const char *fmt, ...)
-{
-       cerr << "alsa_error_handler: " << file << ":" << line << " " << function << " err=" << err << endl;
-}
-
-CaptureThreadImplALSA::CaptureThreadImplALSA(CaptureThread* capture_thread)
-       : CaptureThreadImpl(capture_thread, "ALSA", QString("Advanced Linux Sound Architecture (lib:")+snd_asoundlib_version()+")")
-{
-       m_alsa_capture_handle = NULL;
-       m_alsa_hw_params = NULL;
-       m_alsa_buffer = NULL;
-       m_format = SND_PCM_FORMAT_UNKNOWN;
-
-       m_source = "hw:0";
-
-       m_alive = true;
-       m_in_run = false;
-       m_loop = false;
-
-//     snd_lib_error_set_handler(alsa_error_handler);
-}
-
-bool CaptureThreadImplALSA::is_available()
-{
-       if(m_alsa_capture_handle==NULL)
-       {
-               try
-               {
-                       int err = -1;
-                       if((err=snd_pcm_open(&m_alsa_capture_handle, m_source.latin1(), SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0)
-                       {
-                               if(err==-19)    // TODO risks of changes for the error code
-                                       throw QString("invalid source '")+m_source+"'";
-                               else if(err==-16)
-                                       throw QString("device '")+m_source+"' busy";
-                               else
-                                       throw QString("cannot open pcm: ")+QString(snd_strerror(err));
-                       }
-               }
-               catch(QString error)
-               {
-                       m_alsa_capture_handle = NULL;
-
-                       m_status = "N/A ("+error+")";
-
-                       return false;
-               }
-
-               if(m_alsa_capture_handle!=NULL)
-               {
-                       snd_pcm_close(m_alsa_capture_handle);
-                       m_alsa_capture_handle = NULL;
-               }
-       }
-
-       m_status = "OK";
-
-       //      cerr << "CaptureThread: INFO: ALSA seems available" << endl;
-
-       return true;
-}
-
-void CaptureThreadImplALSA::startCapture()
-{
-       if(!running())
-               start();
-
-       m_loop = true;
-
-       m_wait_for_start = true;
-       while(m_wait_for_start) // some implementations take a long time to start
-               msleep(10);
-}
-void CaptureThreadImplALSA::stopCapture()
-{
-       m_loop = false;
-
-       while(m_in_run)
-               msleep(10);
-}
-
-void CaptureThreadImplALSA::set_params(bool test)
-{
-//     cerr << "ALSA: Recognized sample formats are" << endl;
-//     for (int k = 0; k < SND_PCM_FORMAT_LAST; ++(unsigned long) k) {
-//             const char *s = snd_pcm_format_name((snd_pcm_format_t)k);
-//             if (s)  cerr << s << endl;
-//     }
-       int err=0;
-
-       if(m_source=="")
-               throw QString("ALSA: set the source first");
-       if((err=snd_pcm_open(&m_alsa_capture_handle, m_source.latin1(), SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0)
-       {
-               //                                      cerr << "err=" << err << ":" << snd_strerror(err) << endl;
-
-               if(err==-19)    // TODO risks of changes for the error code
-                       throw QString("ALSA: Invalid Source '")+m_source+"'";
-               else if(err==-16)
-                       throw QString("ALSA: Device '")+m_source+"' busy";
-               else
-                       throw QString("ALSA: Cannot open pcm: ")+QString(snd_strerror(err));
-       }
-
-       snd_pcm_hw_params_alloca(&m_alsa_hw_params);
-
-       if((err=snd_pcm_hw_params_any(m_alsa_capture_handle, m_alsa_hw_params)) < 0)
-               throw QString("ALSA: cannot initialize hardware parameter structure (")+QString(snd_strerror(err))+")";
-
-       if((err=snd_pcm_hw_params_set_access(m_alsa_capture_handle, m_alsa_hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
-               throw QString("ALSA: cannot set access type (")+QString(snd_strerror(err))+")";
-
-       if(!test)
-       {
-               // Formats
-               if(m_format==-1)
-               {
-                       list<snd_pcm_format_t> formats;
-                       formats.push_back(SND_PCM_FORMAT_S16);  formats.push_back(SND_PCM_FORMAT_U16);
-                       formats.push_back(SND_PCM_FORMAT_S8);   formats.push_back(SND_PCM_FORMAT_U8);
-
-                       err = -1;
-                       while(err<0)
-                       {
-                               if(formats.empty())
-                                       throw QString("ALSA: cannot set any format (")+QString(snd_strerror(err))+")";
-
-                               m_format = formats.front();
-                               cerr << "CaptureThread: INFO: ALSA: try to set format to " << snd_pcm_format_description(m_format) << flush;
-                               err=snd_pcm_hw_params_set_format(m_alsa_capture_handle, m_alsa_hw_params, m_format);
-
-                               if(err<0)       cerr << " failed" << endl;
-                               else            cerr << " success" << endl;
-
-                               formats.pop_front();
-                       }
-               }
-               else
-               {
-                       if((err=snd_pcm_hw_params_set_format(m_alsa_capture_handle, m_alsa_hw_params, m_format))<0)
-                       {
-                               QString err_msg = QString("ALSA: cannot set format (")+QString(snd_strerror(err))+")";
-                               cerr << "CaptureThread: ERROR: " << err_msg << endl;
-                       }
-               }
-
-               // Channel count
-               unsigned int channel_count = 1;
-               if((err=snd_pcm_hw_params_set_channels_near(m_alsa_capture_handle, m_alsa_hw_params, &channel_count)) < 0)
-               {
-                       QString err_msg = QString("ALSA: cannot set channel count (")+QString(snd_strerror(err))+")";
-                       cerr << "CaptureThread: WARNING: " << err_msg << endl;
-               }
-               if(channel_count>1)
-               {
-                       QString err_msg = QString("ALSA: cannot set channel count to one (")+QString::number(channel_count)+" instead)";
-                       cerr << "CaptureThread: WARNING: " << err_msg << endl;
-               }
-
-               setFormatDescrsAndFns(snd_pcm_format_width(m_format)/8, snd_pcm_format_signed(m_format), false, channel_count);
-       }
-
-       if(m_sampling_rate==CaptureThread::SAMPLING_RATE_MAX || m_sampling_rate==CaptureThread::SAMPLING_RATE_UNKNOWN)
-       {
-               int old_sampling_rate = m_sampling_rate;
-
-               cerr << "CaptureThread: INFO: ALSA: sampling rate set to max or undefined, try to determinate it." << endl;
-
-               list<int> sampling_rates;
-               sampling_rates.push_front(8000);        sampling_rates.push_front(11025);       sampling_rates.push_front(16000);
-               sampling_rates.push_front(22050);       sampling_rates.push_front(24000);       sampling_rates.push_front(32000);
-               sampling_rates.push_front(44100);       sampling_rates.push_front(48000);       sampling_rates.push_front(96000);
-
-               err = -1;
-               while(err<0)
-               {
-                       if(sampling_rates.empty())
-                               throw QString("ALSA: cannot set any sample rate (")+QString(snd_strerror(err))+")";
-
-                       m_sampling_rate = sampling_rates.front();
-                       cerr << "CaptureThread: INFO: ALSA: try to set sampling rate to " << m_sampling_rate << flush;
-                       unsigned int rrate = m_sampling_rate;
-                       err = snd_pcm_hw_params_set_rate(m_alsa_capture_handle, m_alsa_hw_params, rrate, 0);
-
-                       if(err<0)       cerr << " failed" << endl;
-                       else            cerr << " success" << endl;
-
-                       sampling_rates.pop_front();
-               }
-
-               if(old_sampling_rate!=m_sampling_rate)
-                       m_capture_thread->emitSamplingRateChanged();
-       }
-       else
-       {
-               int err;
-               int dir = 0;
-               unsigned int rrate = m_sampling_rate;
-               if((err = snd_pcm_hw_params_set_rate_near(m_alsa_capture_handle, m_alsa_hw_params, &rrate, &dir))<0)
-                       throw QString("ALSA: cannot set sampling rate (")+QString(snd_strerror(err))+")";
-               if(m_sampling_rate!=rrate)
-                       m_capture_thread->emitSamplingRateChanged();
-               m_sampling_rate = rrate;
-       }
-
-       if((err=snd_pcm_hw_params(m_alsa_capture_handle, m_alsa_hw_params)) < 0)
-               throw QString("ALSA: cannot set parameters (")+QString(snd_strerror(err))+")";
-}
-
-void CaptureThreadImplALSA::setSamplingRate(int value)
-{
-//     cerr << "CaptureThreadImplALSA::setSamplingRate " << value << endl;
-
-       assert(value>0 || value==CaptureThread::SAMPLING_RATE_MAX);
-
-       if(m_sampling_rate!=value || value==CaptureThread::SAMPLING_RATE_MAX)
-       {
-               bool was_running = m_capture_thread->isCapturing();
-               if(was_running) m_capture_thread->stopCapture();
-
-               m_sampling_rate = value;
-
-               if(m_sampling_rate==CaptureThread::SAMPLING_RATE_MAX)
-               {
-                       try
-                       {
-                               set_params(true);
-                       }
-                       catch(QString error)
-                       {
-                               cerr << "CaptureThread: ERROR: " << error << endl;
-                               m_capture_thread->emitError(error);
-                       }
-
-                       // it was just for testing
-                       capture_finished();
-               }
-               else
-                       m_capture_thread->emitSamplingRateChanged();
-
-               if(was_running) m_capture_thread->startCapture();
-       }
-
-//     cerr << "~CaptureThreadImplALSA::setSamplingRate" << endl;
-}
-
-void CaptureThreadImplALSA::capture_init()
-{
-       set_params();
-
-       snd_pcm_nonblock(m_alsa_capture_handle, 0);
-
-       m_alsa_buffer = new char[m_channel_count*ALSA_BUFF_SIZE*snd_pcm_format_width(m_format)/8];
-
-       int err=0;
-
-       if((err=snd_pcm_prepare(m_alsa_capture_handle)) < 0)
-               throw QString("ALSA: cannot prepare audio interface for use (")+QString(snd_strerror(err))+")";
-}
-void CaptureThreadImplALSA::capture_loop()
-{
-//     cerr << "CaptureThreadImplALSA::capture_loop" << endl;
-
-       m_wait_for_start = false;
-       while(m_loop)
-       {
-               int ret_val = snd_pcm_readi(m_alsa_capture_handle, m_alsa_buffer, ALSA_BUFF_SIZE);
-               if(ret_val<0)
-               {
-                       cerr << "CaptureThread: WARNING: ALSA: " << snd_strerror(ret_val) << endl;
-                       while((ret_val = snd_pcm_prepare(m_alsa_capture_handle)) < 0)
-                       {
-                               msleep(1000);
-                               cerr << QString("ALSA: cannot prepare audio interface (")+QString(snd_strerror(ret_val))+")" << endl;
-//                             throw QString("ALSA: cannot prepare audio interface (")+QString(snd_strerror(ret_val))+")";
-                       }
-               }
-               else
-               {
-                       if(!m_capture_thread->m_pause)
-                       {
-                               m_capture_thread->m_lock.lock();
-
-//                             cerr << "CaptureThreadImplALSA::capture_loop " << m_capture_thread->m_values.size() << endl;
-
-                               for(int i=0; i<ret_val*m_channel_count; i++)
-                                       addValue(this, decodeValue(m_alsa_buffer, i), i);
-
-                               m_capture_thread->m_packet_size = ret_val;
-                               if(m_capture_thread->m_ext_lock)
-                               {
-                                       m_capture_thread->m_packet_size_sll = 0;
-                                       m_capture_thread->m_ext_lock = false;
-                               }
-                               m_capture_thread->m_packet_size_sll += ret_val;
-
-                               m_capture_thread->m_lock.unlock();
-                       }
-               }
-       }
-
-//     cerr << "~CaptureThreadImplALSA::capture_loop" << endl;
-}
-void CaptureThreadImplALSA::capture_finished()
-{
-       if(m_alsa_buffer!=NULL)
-       {
-               delete[] m_alsa_buffer;
-               m_alsa_buffer = NULL;
-       }
-
-       if(m_alsa_capture_handle!=NULL)
-       {
-               snd_pcm_hw_free(m_alsa_capture_handle);
-               snd_pcm_close(m_alsa_capture_handle);
-               m_alsa_capture_handle = NULL;
-       }
-}
-
-void CaptureThreadImplALSA::run()
-{
-//     cerr << "CaptureThread: INFO: ALSA: capture thread entered" << endl;
-
-//     while(m_alive)  // TODO need to keep alsa thread alive to let PortAudio working after ALSA !!
-       {
-               while(m_alive && !m_loop)
-                       msleep(10);
-
-               m_in_run = true;
-
-               try
-               {
-                       //                      cerr << "CaptureThread: INFO: capture thread running" << endl;
-
-                       capture_init();
-
-                       m_capture_thread->m_capturing = true;
-                       m_capture_thread->emitCaptureStarted();
-                       m_capture_thread->emitCaptureToggled(true);
-
-                       capture_loop();
-
-                       m_capture_thread->m_capturing = false;
-                       m_capture_thread->emitCaptureStoped();
-                       m_capture_thread->emitCaptureToggled(false);
-               }
-               catch(QString error)
-               {
-                       m_loop = false;
-                       cerr << "CaptureThread: ERROR: " << error << endl;
-                       m_capture_thread->emitError(error);
-               }
-               m_wait_for_start = false;
-
-               capture_finished();
-
-               m_in_run = false;
-
-               //              cerr << "CaptureThread: INFO: capture thread stop running" << endl;
-       }
-
-//     cerr << "CaptureThread: INFO: ALSA: capture thread exited" << endl;
-}
-
-CaptureThreadImplALSA::~CaptureThreadImplALSA()
-{
-//     cerr << "CaptureThreadImplALSA::~CaptureThreadImplALSA" << endl;
-
-       m_alive = false;
-
-       stopCapture();
-
-       while(running())
-               msleep(10);
-
-//     cerr << "~CaptureThreadImplALSA::~CaptureThreadImplALSA" << endl;
-}
-
-#endif
-
-// ------------------------------ JACK implementation ----------------------------
-#ifdef CAPTURE_JACK
-CaptureThreadImplJACK::CaptureThreadImplJACK(CaptureThread* capture_thread)
-: CaptureThreadImpl(capture_thread, "JACK", "Jack Audio Connection Kit")
-{
-       m_jack_client = NULL;
-       m_jack_port = NULL;
-}
-
-bool CaptureThreadImplJACK::is_available()
-{
-       if(m_jack_client==NULL)
-       {
-               try
-               {
-                       m_jack_client = jack_client_new((m_capture_thread->m_name+"_test").latin1());
-                       if(m_jack_client==NULL)
-                               throw QString("unknown reason");
-               }
-               catch(QString error)
-               {
-                       m_jack_client = NULL;
-                       m_status = "N/A";
-                       return false;
-               }
-               capture_finished();
-       }
-
-       m_status = "available";
-
-       return true;
-}
-
-void CaptureThreadImplJACK::setSamplingRate(int value)
-{
-       cerr << "CaptureThread: ERROR: JACK: setSamplingRate not available with JACK ! change the JACK server sampling rate instead" << endl;
-}
-
-void CaptureThreadImplJACK::startCapture()
-{
-       try
-       {
-               capture_init();
-       }
-       catch(QString error)
-       {
-               capture_finished();
-               cerr << "CaptureThread: ERROR: " << error << endl;
-               m_capture_thread->emitError(error);
-       }
-}
-void CaptureThreadImplJACK::stopCapture()
-{
-       try
-       {
-               capture_finished();
-       }
-       catch(QString error)
-       {
-               cerr << "CaptureThread: ERROR: " << error << endl;
-               m_capture_thread->emitError(error);
-       }
-}
-
-void CaptureThreadImplJACK::JackShutdown(void* arg){((CaptureThreadImplJACK*)arg)->jackShutdown();}
-void CaptureThreadImplJACK::jackShutdown()
-{
-       m_jack_client = NULL;
-
-       m_capture_thread->emitError("JACK: server shutdown !");
-}
-
-int CaptureThreadImplJACK::JackSampleRate(jack_nframes_t nframes, void* arg){return ((CaptureThreadImplJACK*)arg)->jackSampleRate(nframes);}
-int CaptureThreadImplJACK::jackSampleRate(jack_nframes_t nframes)
-{
-       if(m_sampling_rate!=int(nframes))
-       {
-               m_sampling_rate = nframes;
-               m_capture_thread->emitSamplingRateChanged();
-       }
-
-       return 0;
-}
-
-int CaptureThreadImplJACK::JackProcess(jack_nframes_t nframes, void* arg){return ((CaptureThreadImplJACK*)arg)->jackProcess(nframes);}
-int CaptureThreadImplJACK::jackProcess(jack_nframes_t nframes)
-{
-//     cerr << "'" << nframes << "'" << endl;
-
-       if(m_capture_thread->m_pause || !m_capture_thread->m_capturing || nframes<=0)   return 0;
-
-       void* pin = jack_port_get_buffer(m_jack_port, nframes);
-
-       if(!pin) return 0;
-
-       jack_default_audio_sample_t* in = (jack_default_audio_sample_t*)pin;
-
-       m_capture_thread->m_lock.lock();
-
-       for(jack_nframes_t i=0; i<nframes; i++)
-               m_capture_thread->m_values.push_front(in[i]);
-
-       m_capture_thread->m_lock.unlock();
-
-       m_capture_thread->m_packet_size = nframes;
-       if(m_capture_thread->m_ext_lock)
-       {
-               m_capture_thread->m_packet_size_sll = 0;
-               m_capture_thread->m_ext_lock = false;
-       }
-       m_capture_thread->m_packet_size_sll += nframes;
-
-       return 0;
-}
-
-void CaptureThreadImplJACK::capture_init()
-{
-       m_jack_client = jack_client_new(m_capture_thread->m_name.latin1());
-       if(!m_jack_client)
-               throw QString("JACK: cannot create client, JACK deamon is running ?");
-
-       jack_set_process_callback(m_jack_client, JackProcess, (void*)this);
-       jack_on_shutdown(m_jack_client, JackShutdown, (void*)this);
-       jack_set_error_function(jack_error_callback);
-       jack_set_sample_rate_callback(m_jack_client, JackSampleRate, (void*)this);
-
-       int err=0;
-       if((err=jack_activate(m_jack_client))!=0)
-               throw QString("JACK: cannot activate client");
-
-       setFormatDescrsAndFns(sizeof(jack_default_audio_sample_t), true, true, 1);
-
-       m_jack_port = jack_port_register(m_jack_client, "input", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput,0);
-
-       if(m_source!="")
-               if((err=jack_connect(m_jack_client, m_source.latin1(), (m_capture_thread->m_name+":input").latin1()))!=0)
-                       m_capture_thread->emitError(QString("JACK: Invalid source '")+m_source+"'");
-
-       int old_sampling_rate = m_sampling_rate;
-       m_sampling_rate = jack_get_sample_rate(m_jack_client);
-       if(m_sampling_rate!=old_sampling_rate)
-               m_capture_thread->emitSamplingRateChanged();
-
-       m_capture_thread->m_capturing = true;
-       m_capture_thread->emitCaptureStarted();
-       m_capture_thread->emitCaptureToggled(true);
-}
-void CaptureThreadImplJACK::capture_finished()
-{
-//     cerr << "CaptureThreadImplJACK::capture_finished" << endl;
-
-       if(m_jack_client!=NULL)
-       {
-               jack_client_close(m_jack_client);
-               m_jack_client = NULL;
-
-               m_capture_thread->m_capturing = false;
-               m_capture_thread->emitCaptureStoped();
-               m_capture_thread->emitCaptureToggled(false);
-       }
-}
-#endif
-
-// ------------------------------ PortAudio implementation ----------------------------
-#ifdef CAPTURE_PORTAUDIO
-CaptureThreadImplPortAudio::CaptureThreadImplPortAudio(CaptureThread* capture_thread)
-       : CaptureThreadImpl(capture_thread, "PortAudio", QString("Portable cross-platform Audio API (lib:")+Pa_GetVersionText()+"["+QString::number(Pa_GetVersion())+"])")
-{
-       m_stream = NULL;
-
-       m_source = "default";
-}
-
-bool CaptureThreadImplPortAudio::is_available()
-{
-       if(!m_stream)
-       {
-               try
-               {
-                       m_err = Pa_Initialize();
-                       if(m_err != paNoError)  throw QString("PortAudio: is_available:Pa_Initialize ")+Pa_GetErrorText(m_err);
-
-                       PaError err;
-                       int numDevices;
-
-                       numDevices = Pa_GetDeviceCount();
-                       if(numDevices < 0)
-                               throw QString("PortAudio: is_available:Pa_GetDeviceCount ")+Pa_GetErrorText(numDevices);
-                       else if(numDevices == 0)
-                               throw QString("PortAudio: is_available:Pa_GetDeviceCount no devices available")+Pa_GetErrorText(numDevices);
-
-/*                     const   PaDeviceInfo *deviceInfo;
-
-                       for(int i=0; i<numDevices; i++ )
-                       {
-                               deviceInfo = Pa_GetDeviceInfo( i );
-                               cerr << deviceInfo->name << endl;
-                               cerr << deviceInfo->defaultSampleRate << endl;
-                       }*/
-               }
-               catch(QString error)
-               {
-                       Pa_Terminate();
-                       m_stream = NULL;
-                       m_status = "N/A";
-                       return false;
-               }
-               capture_finished();
-       }
-
-       m_status = "OK";
-
-       return true;
-}
-
-void CaptureThreadImplPortAudio::setSamplingRate(int value)
-{
-//     cerr << "CaptureThreadImplPortAudio::setSamplingRate " << value << endl;
-
-       assert(value>0 || value==CaptureThread::SAMPLING_RATE_MAX);
-
-       if(m_sampling_rate!=value || value==CaptureThread::SAMPLING_RATE_MAX)
-       {
-               bool was_running = m_capture_thread->isCapturing();
-               if(was_running) m_capture_thread->stopCapture();
-
-               m_sampling_rate = value;
-
-               if(m_sampling_rate==CaptureThread::SAMPLING_RATE_MAX)
-               {
-                       try
-                       {
-                               set_params(true);
-                       }
-                       catch(QString error)
-                       {
-                               cerr << "CaptureThread: ERROR: " << error << endl;
-                               m_capture_thread->emitError(error);
-                       }
-
-                       try{
-                               // it was just for testing
-                               capture_finished();
-                       }
-                       catch(QString error)
-                       {
-                               cerr << "CaptureThread: ERROR: " << error << endl;
-                               m_capture_thread->emitError(error);
-                       }
-               }
-               else
-                       m_capture_thread->emitSamplingRateChanged();
-
-               if(was_running) m_capture_thread->startCapture();
-       }
-
-//     cerr << "~CaptureThreadImplPortAudio::setSamplingRate" << endl;
-}
-
-int CaptureThreadImplPortAudio::PortAudioCallback( const void *inputBuffer, void *outputBuffer,
-                                                                 unsigned long framesPerBuffer,
-                                                                 const PaStreamCallbackTimeInfo* timeInfo,
-                                                                 PaStreamCallbackFlags statusFlags,
-                                                                 void *userData )
-{((CaptureThreadImplPortAudio*)userData)->portAudioCallback(inputBuffer, framesPerBuffer, timeInfo, statusFlags);}
-int CaptureThreadImplPortAudio::portAudioCallback(const void *inputBuffer,
-                                               unsigned long framesPerBuffer,
-                                               const PaStreamCallbackTimeInfo* timeInfo,
-                                               PaStreamCallbackFlags statusFlags)
-{
-       if(m_capture_thread->m_pause)
-               return 0;
-
-       m_capture_thread->m_lock.lock();
-
-       float *in = (float*)inputBuffer;
-
-       for(unsigned long i=0; i<framesPerBuffer; i++)
-               m_capture_thread->m_values.push_front(*in++);
-//     addValue(*in++, i, m_channel_count);                            // TODO
-
-       m_capture_thread->m_packet_size = framesPerBuffer;
-       if(m_capture_thread->m_ext_lock)
-       {
-               m_capture_thread->m_packet_size_sll = 0;
-               m_capture_thread->m_ext_lock = false;
-       }
-       m_capture_thread->m_packet_size_sll += framesPerBuffer;
-
-       m_capture_thread->m_lock.unlock();
-
-       return 0;
-}
-
-void CaptureThreadImplPortAudio::set_params(bool test)
-{
-       m_err = Pa_Initialize();
-       if(m_err != paNoError)  throw QString("PortAudio: set_params:Pa_Initialize ")+Pa_GetErrorText(m_err);
-
-       PaStreamParameters params;
-       params.device = paNoDevice;
-       params.channelCount = 1;
-       params.sampleFormat = paFloat32;
-       params.suggestedLatency = 0;
-       params.hostApiSpecificStreamInfo = NULL;
-
-       if(m_source!="default") // TODO hum hum
-       {
-               int     numDevices = Pa_GetDeviceCount();
-               const PaDeviceInfo* deviceInfo;
-               int index = -1;
-               for(int i=0; params.device==paNoDevice && i<numDevices; i++)
-               {
-                       deviceInfo = Pa_GetDeviceInfo(i);
-                       if(QString(deviceInfo->name)==m_source)
-                               params.device = i;
-               }
-
-               if(params.device==paNoDevice)
-                       cerr << "CaptureThread: INFO: PortAudio: cannot determine selected source \"" << m_source << "\"" << endl;
-       }
-
-       if(!test)
-       {
-               if(params.device==paNoDevice)
-                       cerr << "CaptureThread: INFO: PortAudio: using default device" << endl;
-               else
-                       cerr << "CaptureThread: INFO: PortAudio: using \"" << m_source << "\"" << endl;
-
-               setFormatDescrsAndFns(4, true, true, 1);
-       }
-
-       if(m_sampling_rate==CaptureThread::SAMPLING_RATE_MAX || m_sampling_rate==CaptureThread::SAMPLING_RATE_UNKNOWN)
-       {
-               int old_sampling_rate = m_sampling_rate;
-
-               cerr << "CaptureThread: INFO: PortAudio: sampling rate set to max or undefined, try to determinate it." << endl;
-
-               list<int> sampling_rates;
-               sampling_rates.push_front(8000);        sampling_rates.push_front(11025);       sampling_rates.push_front(16000);
-               sampling_rates.push_front(22050);       sampling_rates.push_front(24000);       sampling_rates.push_front(32000);
-               sampling_rates.push_front(44100);       sampling_rates.push_front(48000);       sampling_rates.push_front(96000);
-
-               m_err = -1;
-               while(m_err!=paNoError)
-               {
-                       if(sampling_rates.empty())
-                               throw QString("PortAudio: cannot set any sample rate (")+Pa_GetErrorText(m_err)+")";
-
-                       m_err = Pa_Initialize();
-                       if(m_err != paNoError)  throw QString("PortAudio: set_params:Pa_Initialize ")+Pa_GetErrorText(m_err);
-
-                       m_sampling_rate = sampling_rates.front();
-                       cerr << "CaptureThread: INFO: PortAudio: try to set sampling rate to " << m_sampling_rate << flush;
-
-//                     cerr << "nbc1 " << params.channelCount << endl;
-
-                       if(params.device==paNoDevice)
-                               m_err = Pa_OpenDefaultStream(&m_stream, 1, 0, paFloat32, m_sampling_rate, 0, PortAudioCallback, this);
-                       else
-                               m_err = Pa_OpenStream(&m_stream, &params, NULL, m_sampling_rate, 0, paNoFlag, PortAudioCallback, this);
-
-                       if(m_err != paNoError)  cerr << " failed" << endl;
-                       else                                    cerr << " success" << endl;
-
-                       sampling_rates.pop_front();
-               }
-
-               if(old_sampling_rate!=m_sampling_rate)
-                       m_capture_thread->emitSamplingRateChanged();
-       }
-       else
-       {
-//             cerr << "nbc2 " << params.channelCount << endl;
-//             cerr << "dev2 " << params.device << "/" << paNoDevice << endl;
-
-               if(params.device==paNoDevice)
-               {
-                       m_err = Pa_OpenDefaultStream(&m_stream, 1, 0, paFloat32, m_sampling_rate, 0, PortAudioCallback, this);
-                       if(m_err != paNoError)
-                               throw QString("PortAudio: set_params:Pa_OpenDefaultStream ")+Pa_GetErrorText(m_err);
-               }
-               else
-               {
-                       m_err = Pa_OpenStream(&m_stream, &params, NULL, m_sampling_rate, 0, paNoFlag, PortAudioCallback, this);
-                       if(m_err != paNoError)
-                               throw QString("PortAudio: set_params:Pa_OpenStream ")+Pa_GetErrorText(m_err);
-               }
-       }
-}
-
-void CaptureThreadImplPortAudio::capture_init()
-{
-       set_params(false);
-
-       m_err = Pa_StartStream(m_stream);
-       if(m_err != paNoError)
-               throw QString("PortAudio: capture_init:Pa_StartStream ")+Pa_GetErrorText(m_err);
-
-       m_capture_thread->m_capturing = true;
-       m_capture_thread->emitCaptureStarted();
-       m_capture_thread->emitCaptureToggled(true);
-}
-void CaptureThreadImplPortAudio::capture_finished()
-{
-       if(m_stream)
-       {
-               if(!Pa_IsStreamStopped(m_stream))
-               {
-                       m_err = Pa_StopStream(m_stream);
-                       if(m_err != paNoError)  throw QString("PortAudio: capture_finished: ")+Pa_GetErrorText(m_err);
-               }
-
-               if(m_stream)
-               {
-                       m_err = Pa_CloseStream(m_stream);
-                       if(m_err != paNoError)  throw QString("PortAudio: capture_finished: ")+Pa_GetErrorText(m_err);
-               }
-
-               m_stream = NULL;
-
-               m_capture_thread->m_capturing = false;
-               m_capture_thread->emitCaptureStoped();
-               m_capture_thread->emitCaptureToggled(false);
-       }
-
-       m_err = Pa_Terminate();
-//     if(m_err != paNoError)  throw QString("PortAudio: capture_finished: ")+Pa_GetErrorText(m_err);
-}
-void CaptureThreadImplPortAudio::startCapture()
-{
-       try
-       {
-               capture_init();
-       }
-       catch(QString error)
-       {
-               capture_finished();
-               cerr << "CaptureThread: ERROR: " << error << endl;
-               m_capture_thread->emitError(error);
-       }
-}
-void CaptureThreadImplPortAudio::stopCapture()
-{
-       try
-       {
-               capture_finished();
-       }
-       catch(QString error)
-       {
-               cerr << "CaptureThread: ERROR: " << error << endl;
-               m_capture_thread->emitError(error);
-       }
-}
-CaptureThreadImplPortAudio::~CaptureThreadImplPortAudio()
-{
-       stopCapture();
-}
-
-#endif
-
-// ------------------------------ OSS implementation ----------------------------
-#ifdef CAPTURE_OSS
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <sys/soundcard.h>
-
-
-#define OSS_BUFF_SIZE 1024
-
-CaptureThreadImplOSS::CaptureThreadImplOSS(CaptureThread* capture_thread)
-       : CaptureThreadImpl(capture_thread, "OSS", QString("Open Sound System"))
-{
-       m_fd_in = 0;
-       m_oss_buffer = NULL;
-       m_format = -1;
-
-       m_source = "/dev/dsp";
-
-       //      oss_sysinfo si; // definition ??
-//     ioctl(m_fd_in, OSS_SYSINFO, &si);
-//     m_fd_in = open(m_source, O_RDONLY, 0));
-//     m_descr = QString("Open Sound System (")+QString::number(SOUND_VERSION, 16)+":"+si.version+")");
-//     close(m_fd_in);
-//     m_fd_in = 0;
-       m_descr = QString("Open Sound System (lib:")+QString::number(SOUND_VERSION, 16)+")";
-
-       m_alive = true;
-       m_in_run = false;
-       m_loop = false;
-}
-
-bool CaptureThreadImplOSS::is_available()
-{
-       if(m_fd_in==0)
-       {
-               try
-               {
-                       if((m_fd_in = open (m_source.latin1(), O_RDONLY, 0)) == -1)
-                               throw QString(strerror(errno));
-               }
-               catch(QString error)
-               {
-                       m_fd_in = 0;
-
-                       m_status = "N/A ("+error+")";
-
-                       return false;
-               }
-
-               capture_finished();
-       }
-
-       m_status = "OK";
-
-       //      cerr << "CaptureThread: INFO: OSS seems available" << endl;
-
-       return true;
-}
-
-void CaptureThreadImplOSS::startCapture()
-{
-       if(!running())
-               start();
-
-       m_loop = true;
-
-       m_wait_for_start = true;
-       while(m_wait_for_start) // some implementations take a long time to start
-               msleep(10);
-}
-void CaptureThreadImplOSS::stopCapture()
-{
-       m_loop = false;
-
-       while(m_in_run)
-               msleep(10);
-}
-
-void CaptureThreadImplOSS::set_params(bool test)
-{
-       if(m_source=="")
-               throw QString("OSS: set the source first");
-       if((m_fd_in = open (m_source.latin1(), O_RDONLY, 0))==-1)
-               throw QString("OSS: ")+QString(strerror(errno));
-
-       if(!test)
-       {
-               if(m_format==-1)
-               {
-                       // Formats
-                       m_format = AFMT_S16_NE; /* Native 16 bits */
-                       if(ioctl(m_fd_in, SNDCTL_DSP_SETFMT, &m_format)==-1)
-                               throw QString("OSS: cannot set format (")+strerror(errno)+")";
-
-                       if(m_format != AFMT_S16_NE)
-                               throw QString("OSS: cannot set format to signed 16bits");
-               }
-               else
-               {
-                       if(ioctl(m_fd_in, SNDCTL_DSP_SETFMT, &m_format)==-1)
-                               throw QString("OSS: cannot set format (")+strerror(errno)+")";
-               }
-
-               m_format_size = 2;
-               m_format_signed = true;
-               m_format_float = false;
-
-               // Channel count
-               unsigned int channel_count = 1;
-               if(ioctl(m_fd_in, SNDCTL_DSP_CHANNELS, &channel_count)==-1)
-                       throw QString("OSS: cannot set channel count to 1 (")+strerror(errno)+")";
-
-               if(channel_count != 1)
-                       throw QString("OSS: the device doesn't support mono mode");
-
-               /*              if(m_channel_count>1)   // TODO
-               {
-                       QString err_msg = QString("OSS: cannot set channel count to one (")+QString::number(m_channel_count)+" instead)";
-                       cerr << "CaptureThread: WARNING: " << err_msg << endl;
-               }*/
-
-               setFormatDescrsAndFns(2, true, false, channel_count);
-       }
-
-       if(m_sampling_rate==CaptureThread::SAMPLING_RATE_MAX || m_sampling_rate==CaptureThread::SAMPLING_RATE_UNKNOWN)
-       {
-               int old_sampling_rate = m_sampling_rate;
-
-               cerr << "CaptureThread: INFO: OSS: sampling rate set to max or undefined, try to determinate it." << endl;
-
-               list<int> sampling_rates;
-               sampling_rates.push_front(8000);        sampling_rates.push_front(11025);       sampling_rates.push_front(16000);
-               sampling_rates.push_front(22050);       sampling_rates.push_front(24000);       sampling_rates.push_front(32000);
-               sampling_rates.push_front(44100);       sampling_rates.push_front(48000);       sampling_rates.push_front(96000);
-
-               int err = -1;
-               while(err<0)
-               {
-                       if(sampling_rates.empty())
-                               throw QString("OSS: cannot set any sample rate (")+strerror(errno)+")";
-
-                       m_sampling_rate = sampling_rates.front();
-                       cerr << "CaptureThread: INFO: OSS: try to set sampling rate to " << m_sampling_rate << flush;
-                       err = ioctl(m_fd_in, SNDCTL_DSP_SPEED, &m_sampling_rate);
-
-                       if(err==-1)     cerr << " failed" << endl;
-                       else            cerr << " success" << endl;
-
-                       sampling_rates.pop_front();
-               }
-
-               if(old_sampling_rate!=m_sampling_rate)
-                       m_capture_thread->emitSamplingRateChanged();
-       }
-       else
-       {
-               if(ioctl(m_fd_in, SNDCTL_DSP_SPEED, &m_sampling_rate)==-1)
-                       throw QString("OSS: cannot set sampling rate (")+QString(strerror(errno))+")";
-       }
-}
-
-void CaptureThreadImplOSS::setSamplingRate(int value)
-{
-//     cerr << "CaptureThreadImplOSS::setSamplingRate " << value << endl;
-
-       assert(value>0 || value==CaptureThread::SAMPLING_RATE_MAX);
-
-       if(m_sampling_rate!=value || value==CaptureThread::SAMPLING_RATE_MAX)
-       {
-               bool was_running = m_capture_thread->isCapturing();
-               if(was_running) m_capture_thread->stopCapture();
-
-               m_sampling_rate = value;
-
-               if(m_sampling_rate==CaptureThread::SAMPLING_RATE_MAX)
-               {
-                       try
-                       {
-                               set_params(true);
-                       }
-                       catch(QString error)
-                       {
-                               cerr << "CaptureThread: ERROR: " << error << endl;
-                               m_capture_thread->emitError(error);
-                       }
-
-                       // it was just for testing
-                       capture_finished();
-               }
-               else
-                       m_capture_thread->emitSamplingRateChanged();
-
-               if(was_running) m_capture_thread->startCapture();
-       }
-
-//     cerr << "~CaptureThreadImplOSS::setSamplingRate" << endl;
-}
-
-void CaptureThreadImplOSS::capture_init()
-{
-       set_params(false);
-
-       m_oss_buffer = new char[m_channel_count*OSS_BUFF_SIZE*16/8];
-}
-void CaptureThreadImplOSS::capture_loop()
-{
-//     cerr << "CaptureThreadImplOSS::capture_loop" << endl;
-
-       bool format_signed = true;
-       int l=0;
-
-       m_wait_for_start = false;
-       while(m_loop)
-       {
-               int ret_val = read(m_fd_in, m_oss_buffer, sizeof(m_oss_buffer));
-
-               if(ret_val==-1)
-               {
-                       cerr << "CaptureThread: WARNING: OSS: " << strerror(errno) << endl;
-                       msleep(1000);   // TODO which behavior ?
-//                     m_loop = false;// TODO which behavior ?
-               }
-               else
-               {
-                       ret_val /= m_format_size;
-
-                       if(!m_capture_thread->m_pause)
-                       {
-                               m_capture_thread->m_lock.lock();
-
-                               for(int i=0; i<ret_val*m_channel_count; i++)
-                                       addValue(this, decodeValue(m_oss_buffer, i), i);
-
-                               m_capture_thread->m_packet_size = ret_val;
-                               if(m_capture_thread->m_ext_lock)
-                               {
-                                       m_capture_thread->m_packet_size_sll = 0;
-                                       m_capture_thread->m_ext_lock = false;
-                               }
-                               m_capture_thread->m_packet_size_sll += ret_val;
-
-                               m_capture_thread->m_lock.unlock();
-                       }
-               }
-       }
-
-//     cerr << "~CaptureThreadImplOSS::capture_loop" << endl;
-}
-void CaptureThreadImplOSS::capture_finished()
-{
-       if(m_oss_buffer!=NULL)
-       {
-               delete[] m_oss_buffer;
-               m_oss_buffer = NULL;
-       }
-
-       if(m_fd_in!=0)
-       {
-               close(m_fd_in);
-               m_fd_in = 0;
-       }
-}
-
-void CaptureThreadImplOSS::run()
-{
-//     cerr << "CaptureThread: INFO: OSS: capture thread entered" << endl;
-
-//     while(m_alive)  // TODO ?? need to keep oss thread alive to let PortAudio working after ALSA ??
-       {
-               while(m_alive && !m_loop)
-                       msleep(10);
-
-               m_in_run = true;
-
-               try
-               {
-                       //                      cerr << "CaptureThread: INFO: capture thread running" << endl;
-
-                       capture_init();
-
-                       m_capture_thread->m_capturing = true;
-                       m_capture_thread->emitCaptureStarted();
-                       m_capture_thread->emitCaptureToggled(true);
-
-                       capture_loop();
-
-                       m_capture_thread->m_capturing = false;
-                       m_capture_thread->emitCaptureStoped();
-                       m_capture_thread->emitCaptureToggled(false);
-               }
-               catch(QString error)
-               {
-                       m_loop = false;
-                       cerr << "CaptureThread: ERROR: " << error << endl;
-                       m_capture_thread->emitError(error);
-               }
-               m_wait_for_start = false;
-
-               capture_finished();
-
-               m_in_run = false;
-
-               //              cerr << "CaptureThread: INFO: capture thread stop running" << endl;
-       }
-
-//     cerr << "CaptureThread: INFO: OSS: capture thread exited" << endl;
-}
-
-CaptureThreadImplOSS::~CaptureThreadImplOSS()
-{
-//     cerr << "CaptureThreadImplOSS::~CaptureThreadImplOSS" << endl;
-
-       m_alive = false;
-
-       stopCapture();
-
-       while(running())
-               msleep(10);
-
-//     cerr << "~CaptureThreadImplOSS::~CaptureThreadImplOSS" << endl;
-}
-
-#endif