微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

pa_devs.c 检测设备但其他代码没有

如何解决pa_devs.c 检测设备但其他代码没有

我目前正在尝试使以下代码工作,但是当尝试使用 portaudio 访问设备时 我使用的是 linux 计算机,卡使用 ALSA。并且两个代码都使用相同版本的portaudio

下面的代码是 pa_dev.c 是与 portaudio 一起提供的。此代码可以访问设备,并打印设备:

/** @file pa_devs.c
    @ingroup examples_src
    @brief List available devices,including device information.
    @author Phil Burk http://www.softsynth.com

    @note Define PA_USE_ASIO=0 to compile this code on Windows without
        ASIO support.
*/
/*
 * $Id: pa_devs.c 1752 2011-09-08 03:21:55Z philburk $
 *
 * This program uses the PortAudio Portable Audio Library.
 * For more information see: http://www.portaudio.com
 * copyright (c) 1999-2000 Ross Bencina and Phil Burk
 *
 * Permission is hereby granted,free of charge,to any person obtaining
 * a copy of this software and associated documentation files
 * (the "Software"),to deal in the Software without restriction,* including without limitation the rights to use,copy,modify,merge,* publish,distribute,sublicense,and/or sell copies of the Software,* and to permit persons to whom the Software is furnished to do so,* subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS",WITHOUT WARRANTY OF ANY KIND,* EXPRESS OR IMPLIED,INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY,fitness FOR A PARTIculaR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR copYRIGHT HOLDERS BE LIABLE FOR
 * ANY CLaim,damAGES OR OTHER LIABILITY,WHETHER IN AN ACTION OF
 * CONTRACT,TORT OR OTHERWISE,ARISING FROM,OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/*
 * The text above constitutes the entire PortAudio license; however,* the PortAudio community also makes the following non-binding requests:
 *
 * Any person wishing to distribute modifications to the Software is
 * requested to send the modifications to the original developer so that
 * they can be incorporated into the canonical version. It is also 
 * requested that these non-binding requests be included along with the 
 * license above.
 */

#include <stdio.h>
#include <math.h>
#include "portaudio.h"

#ifdef WIN32
#if PA_USE_ASIO
#include "pa_asio.h"
#endif
#endif

/*******************************************************************/
static void PrintSupportedStandardSampleRates(
        const PaStreamParameters *inputParameters,const PaStreamParameters *outputParameters )
{
    static double standardSampleRates[] = {
        8000.0,9600.0,11025.0,12000.0,16000.0,22050.0,24000.0,32000.0,44100.0,48000.0,88200.0,96000.0,192000.0,-1 /* negative terminated  list */
    };
    int     i,printCount;
    PaError err;

    printCount = 0;
    for( i=0; standardSampleRates[i] > 0; i++ )
    {
        err = Pa_IsFormatSupported( inputParameters,outputParameters,standardSampleRates[i] );
        if( err == paFormatIsSupported )
        {
            if( printCount == 0 )
            {
                printf( "\t%8.2f",standardSampleRates[i] );
                printCount = 1;
            }
            else if( printCount == 4 )
            {
                printf( ",\n\t%8.2f",standardSampleRates[i] );
                printCount = 1;
            }
            else
            {
                printf( ",%8.2f",standardSampleRates[i] );
                ++printCount;
            }
        }
    }
    if( !printCount )
        printf( "None\n" );
    else
        printf( "\n" );
}

/*******************************************************************/
int main(void);
int main(void)
{
    int     i,numDevices,defaultdisplayed;
    const   PaDeviceInfo *deviceInfo;
    PaStreamParameters inputParameters,outputParameters;
    PaError err;

    
    Pa_Initialize();

    printf( "PortAudio version number = %d\nPortAudio version text = '%s'\n",Pa_GetVersion(),Pa_GetVersionText() );

            
    numDevices = Pa_GetDeviceCount();
    
    if( numDevices < 0 )
    {
        printf( "ERROR: Pa_GetDeviceCount returned 0x%x\n",numDevices );
        err = numDevices;
        goto error;
    }
    
    printf( "Number of devices = %d\n",numDevices );
    for( i=0; i<numDevices; i++ )
    {
        deviceInfo = Pa_GetDeviceInfo( i );
        printf( "--------------------------------------- device #%d\n",i );
                
    /* Mark global and API specific default devices */
        defaultdisplayed = 0;
        if( i == Pa_GetDefaultInputDevice() )
        {
            printf( "[ Default Input" );
            defaultdisplayed = 1;
        }
        else if( i == Pa_GetHostApiInfo( deviceInfo->hostApi )->defaultInputDevice )
        {
            const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo( deviceInfo->hostApi );
            printf( "[ Default %s Input",hostInfo->name );
            defaultdisplayed = 1;
        }
        
        if( i == Pa_GetDefaultOutputDevice() )
        {
            printf( (defaultdisplayed ? "," : "[") );
            printf( " Default Output" );
            defaultdisplayed = 1;
        }
        else if( i == Pa_GetHostApiInfo( deviceInfo->hostApi )->defaultOutputDevice )
        {
            const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo( deviceInfo->hostApi );
            printf( (defaultdisplayed ? "," : "[") );                
            printf( " Default %s Output",hostInfo->name );
            defaultdisplayed = 1;
        }

        if( defaultdisplayed )
            printf( " ]\n" );

    /* print device info fields */
        printf( "Name                        = %s\n",deviceInfo->name );
        printf( "Host API                    = %s\n",Pa_GetHostApiInfo( deviceInfo->hostApi )->name );
        printf( "Max inputs = %d",deviceInfo->maxInputChannels  );
        printf( ",Max outputs = %d\n",deviceInfo->maxOutputChannels  );

        printf( "Default low input latency   = %8.4f\n",deviceInfo->defaultLowInputLatency  );
        printf( "Default low output latency  = %8.4f\n",deviceInfo->defaultLowOutputLatency  );
        printf( "Default high input latency  = %8.4f\n",deviceInfo->defaultHighInputLatency  );
        printf( "Default high output latency = %8.4f\n",deviceInfo->defaultHighOutputLatency  );

#ifdef WIN32
#if PA_USE_ASIO
/* ASIO specific latency information */
        if( Pa_GetHostApiInfo( deviceInfo->hostApi )->type == paASIO ){
            long minLatency,maxLatency,preferredLatency,granularity;

            err = PaAsio_GetAvailableLatencyValues( i,&minLatency,&maxLatency,&preferredLatency,&granularity );

            printf( "ASIO minimum buffer size    = %ld\n",minLatency  );
            printf( "ASIO maximum buffer size    = %ld\n",maxLatency  );
            printf( "ASIO preferred buffer size  = %ld\n",preferredLatency  );

            if( granularity == -1 )
                printf( "ASIO buffer granularity     = power of 2\n" );
            else
                printf( "ASIO buffer granularity     = %ld\n",granularity  );
        }
#endif /* PA_USE_ASIO */
#endif /* WIN32 */

        printf( "Default sample rate         = %8.2f\n",deviceInfo->defaultSampleRate );

    /* poll for standard sample rates */
        inputParameters.device = i;
        inputParameters.channelCount = deviceInfo->maxInputChannels;
        inputParameters.sampleFormat = paInt16;
        inputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
        inputParameters.hostApiSpecificStreamInfo = NULL;
        
        outputParameters.device = i;
        outputParameters.channelCount = deviceInfo->maxOutputChannels;
        outputParameters.sampleFormat = paInt16;
        outputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
        outputParameters.hostApiSpecificStreamInfo = NULL;

        if( inputParameters.channelCount > 0 )
        {
            printf("Supported standard sample rates\n for half-duplex 16 bit %d channel input = \n",inputParameters.channelCount );
            PrintSupportedStandardSampleRates( &inputParameters,NULL );
        }

        if( outputParameters.channelCount > 0 )
        {
            printf("Supported standard sample rates\n for half-duplex 16 bit %d channel output = \n",outputParameters.channelCount );
            PrintSupportedStandardSampleRates( NULL,&outputParameters );
        }

        if( inputParameters.channelCount > 0 && outputParameters.channelCount > 0 )
        {
            printf("Supported standard sample rates\n for full-duplex 16 bit %d channel input,%d channel output = \n",inputParameters.channelCount,outputParameters.channelCount );
            PrintSupportedStandardSampleRates( &inputParameters,&outputParameters );
        }
    }

    Pa_Terminate();

    printf("----------------------------------------------\n");
    return 0;

error:
    Pa_Terminate();
    fprintf( stderr,"An error occured while using the portaudio stream\n" );
    fprintf( stderr,"Error number: %d\n",err );
    fprintf( stderr,"Error message: %s\n",Pa_GetErrorText( err ) );
    return err;
}

但是,当我从以下代码调用函数 Pa_GetDeviceCount() 和 Pa_GetDeviceInfo() 时,portaudio 检测到 0 设备并给我消息“设备不可用”

// online/online-audio-source.cc

// copyright 2012 Cisco Systems (author: Matthias Paulik)

//   Modifications to the original contribution by Cisco Systems made by:
//   Vassil Panayotov

// See ../../copYING for clarification regarding multiple authors
//
// Licensed under the Apache License,Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND,EITHER EXPRESS OR IMPLIED,INCLUDING WITHOUT LIMITATION ANY IMPLIED
// WARRANTIES OR CONDITIONS OF TITLE,fitness FOR A PARTIculaR PURPOSE,// MERCHANTABLITY OR NON-INFRINGEMENT.
// See the Apache 2 License for the specific language governing permissions and
// limitations under the License.

#include <algorithm>
#include <cmath>
#include <vector>


#ifndef KALDI_NO_PORTAUdio
#include "base/timer.h"
#endif  // KALDI_NO_PORTAUdio

#include "online-audio-source.h"

namespace kaldi {

#ifndef KALDI_NO_PORTAUdio

// The actual PortAudio callback - delegates to OnlinePaSource->Callback()
int PaCallback(const void *input,void *output,long unsigned frame_count,const PaStreamCallbackTimeInfo *time_info,PaStreamCallbackFlags status_flags,void *user_data) {
  OnlinePaSource *pa_src = reinterpret_cast<OnlinePaSource*>(user_data);
  return pa_src->Callback(input,output,frame_count,time_info,status_flags);
}


OnlinePaSource::OnlinePaSource(const uint32 timeout,const uint32 sample_rate,const uint32 rb_size,const uint32 report_interval)
    : timeout_(timeout),timed_out_(false),sample_rate_(sample_rate),pa_started_(false),report_interval_(report_interval),nread_calls_(0),noverflows_(0),samples_lost_(0) {
  using namespace std;

  // Note this will work for 32bit integers but not for 64bit.
  // For 64bit integers even double wouldn't work
  // You would have to use something like
  // int64 rb_bits = 0; while (rb_size != 0) {++rb_bits; rb_size >>= 1;}
  // it would be much faster than two logs of FP numbers (even floats),too,// but I don't have the time to test it.
  float f = Log(static_cast<float>(rb_size)) / Log(static_cast<float>(2));
  int32 rb_bits = static_cast<int32>(ceil(f));
  if (rb_bits > 30)  // ok,this limit is somewhat arbitrary
    throw invalid_argument("PortAudio ring buffer too large!");
  rb_size_ = 1 << rb_bits;
  ring_buffer_ = new char[rb_size_];
  ring_buffer_size_t rbs = PaUtil_InitializeRingBuffer(
                               &pa_ringbuf_,sizeof(SampleType),rb_size_ / sizeof(SampleType),ring_buffer_);
  if (rbs != 0)
    KALDI_ERR << "PortAudio ring buffer init error";

  PaError paerr = Pa_Initialize();
  if (paerr != paNoError)
    {
    KALDI_ERR << "PortAudio initialization error";
  // Monophone,16-bit input hardcoded
  KALDI_ASSERT(sizeof(SampleType) == 2 &&
               "The current OnlinePaSource code assumes 16-bit input");
    }
    cout<<"la on va voir si on a des devices"<<endl;
    int numDevices;
    numDevices=Pa_GetDeviceCount();
    cout<< " on a " << numDevices <<endl;
    printf( "PortAudio version number = %d\nPortAudio version text = '%s'\n",Pa_GetVersionText() );
    paerr = Pa_OpenDefaultStream(&pa_stream_,1,paInt16,sample_rate_,PaCallback,this);
    //paerr=Pa_OpenStream
    cout<<"Avant la boucle "<<endl;
    
  if (paerr != paNoError)
    {
    cout<<"On est dans la boucle"<<endl;
    const PaDeviceInfo *deviceInfo;
    int i=0;
    int numDevices;
    numDevices=Pa_GetDeviceCount();
    cout<<numDevices<<endl;
    for (i=0;i<numDevices;i++)
        {
        deviceInfo=Pa_GetDeviceInfo(i);
        cout<<"information sur le device"<<endl;
        cout<<"name: "<<deviceInfo->name<<endl;
        cout<<"maxInputChannels: "<<deviceInfo->maxInputChannels<<endl;
        cout<<"maxOutputChannels: "<<deviceInfo->maxOutputChannels<<endl;
        cout<<"defaultSampleRate: "<<deviceInfo->defaultSampleRate<<endl;
        }
    cout<<Pa_GetErrorText(paerr)<<endl;
    KALDI_ERR << "PortAudio Failed to open the default stream";
    }
}


OnlinePaSource::~OnlinePaSource() {
  if (pa_started_)
    Pa_StopStream(pa_stream_);
  if (pa_stream_ != 0) {
    Pa_CloseStream(pa_stream_);
    Pa_Terminate();
  }
  if (ring_buffer_ != 0)
    delete [] ring_buffer_;
}


bool OnlinePaSource::Read(Vector<BaseFloat> *data) {
  if (!pa_started_) {  // start stream the first time Read() is called
    PaError paerr = Pa_StartStream(pa_stream_);
    if (paerr != paNoError)
      KALDI_ERR << "Error while trying to open PortAudio stream";
    pa_started_ = true;
  }
  Timer timer;
  if (report_interval_ != 0
      && (++nread_calls_ % report_interval_) == 0
      && noverflows_ > 0) {
      KALDI_VLOG(1) << noverflows_
                    << " PortAudio ring buffer overflows detected "
                    << "and " << samples_lost_ << " sample(s) were lost";
      samples_lost_ = noverflows_ = 0;
  }
  uint32 nsamples_req = data->Dim();  // samples to request
  timed_out_ = false;
  while (true) {
    ring_buffer_size_t nsamples;
    nsamples = PaUtil_GetRingBufferReadAvailable(&pa_ringbuf_);
    if (nsamples >= nsamples_req)
      break;
    if (timeout_ > 0) {
      int32 elapsed = static_cast<int32>(timer.Elapsed() * 1000);
      if (elapsed > timeout_) {
        nsamples_req = nsamples;
        timed_out_ = true;
        KALDI_VLOG(2) << "OnlinePaSource::Read() timeout";
        break;
      }
    }
    Pa_Sleep(2);
  }
  std::vector<int16> buf(nsamples_req);
  rbs_t nsamples_rcv;
  nsamples_rcv = PaUtil_ReadRingBuffer(&pa_ringbuf_,buf.data(),nsamples_req);
  if (nsamples_rcv != nsamples_req) {
    KALDI_WARN << "Requested: " << nsamples_req
               << "; Received: " << nsamples_rcv << " samples";
    // This would be a PortAudio error.
  }
  data->Resize(nsamples_rcv);
  for (int i = 0; i < nsamples_rcv; ++i)
    (*data)(i) = static_cast<BaseFloat>(buf[i]);

  return (nsamples_rcv != 0);
  // NOTE (Dan): I'm pretty sure this return value is not right,it Could be
  // this way because we're waiting.  Vassil or someone will have to figure this
  // out.
}


// Accepts the data and writes it to the ring buffer
int OnlinePaSource::Callback(const void *input,ring_buffer_size_t frame_count,PaStreamCallbackFlags status_flags) {
  if (report_interval_ != 0) {
    if (frame_count > PaUtil_GetRingBufferWriteAvailable(&pa_ringbuf_))
      ++noverflows_;
  }
  rbs_t written = PaUtil_WriteRingBuffer(&pa_ringbuf_,input,frame_count);
  samples_lost_ += frame_count - written;
  return paContinue;
}

#endif  // KALDI_NO_PORTAUdio

bool OnlineVectorSource::Read(Vector<BaseFloat> *data) {
  KALDI_ASSERT(data->Dim() > 0);
  int32 n_elem = std::min(src_.Dim() - pos_,static_cast<uint32>(data->Dim()));
  if (n_elem > 0) {
    SubVector<BaseFloat> subsrc(src_,pos_,n_elem);
    if (data->Dim() == subsrc.Dim()) {
      data->copyFromVec(subsrc);
    } else {
      data->Resize(n_elem);
      for (int32 i = 0; i < subsrc.Dim(); ++i)
        (*data)(i) = subsrc(i);
    }
    pos_ += n_elem;
    return true;
  }
  return false;
}

}  // namespace kaldi

这个问题的解决方案是什么?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?