static void alsa_log(snd_pcm_hw_params_t* hw_params, snd_pcm_sw_params_t* sw_params) { unsigned period_time; snd_pcm_uframes_t period_size; unsigned period_count; unsigned buffer_time; snd_pcm_uframes_t buffer_size; unsigned tick_time; snd_pcm_uframes_t xfer_align; snd_pcm_hw_params_get_period_time(hw_params, &period_time, 0); snd_pcm_hw_params_get_period_size(hw_params, &period_size, 0); snd_pcm_hw_params_get_periods(hw_params, &period_count, 0); snd_pcm_hw_params_get_buffer_time(hw_params, &buffer_time, 0); snd_pcm_hw_params_get_buffer_size(hw_params, &buffer_size); snd_pcm_hw_params_get_tick_time(hw_params, &tick_time, 0); log_std(("sound:alsa: hw period_time %g [us], period_size %d, periods %d, buffer_time %g [us], buffer_size %d, tick_time %g [us]\n", (double)(period_time / 1000000.0), (unsigned)period_size, (unsigned)period_count, (double)(buffer_time / 1000000.0), (unsigned)buffer_size, (double)(tick_time / 1000000.0) )); snd_pcm_sw_params_get_xfer_align(sw_params, &xfer_align); log_std(("sound:alsa: sw xfer_align %d\n", (unsigned)xfer_align )); }
bool QAlsaAudioInput::open() { #ifdef DEBUG_AUDIO QTime now(QTime::currentTime()); qDebug()<<now.second()<<"s "<<now.msec()<<"ms :open()"; #endif clockStamp.restart(); timeStamp.restart(); elapsedTimeOffset = 0; int dir; int err = 0; int count=0; unsigned int sampleRate=settings.sampleRate(); if (!settings.isValid()) { qWarning("QAudioInput: open error, invalid format."); } else if (settings.sampleRate() <= 0) { qWarning("QAudioInput: open error, invalid sample rate (%d).", settings.sampleRate()); } else { err = -1; } if (err == 0) { errorState = QAudio::OpenError; deviceState = QAudio::StoppedState; emit errorChanged(errorState); return false; } QString dev = QString(QLatin1String(m_device.constData())); QList<QByteArray> devices = QAlsaAudioDeviceInfo::availableDevices(QAudio::AudioInput); if(dev.compare(QLatin1String("default")) == 0) { #if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) if (devices.size() > 0) dev = QLatin1String(devices.first()); else return false; #else dev = QLatin1String("hw:0,0"); #endif } else { #if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) dev = QLatin1String(m_device); #else int idx = 0; char *name; QString shortName = QLatin1String(m_device.mid(m_device.indexOf('=',0)+1).constData()); while(snd_card_get_name(idx,&name) == 0) { if(qstrncmp(shortName.toLocal8Bit().constData(),name,shortName.length()) == 0) break; idx++; } dev = QString(QLatin1String("hw:%1,0")).arg(idx); #endif } // Step 1: try and open the device while((count < 5) && (err < 0)) { err=snd_pcm_open(&handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_CAPTURE,0); if(err < 0) count++; } if (( err < 0)||(handle == 0)) { errorState = QAudio::OpenError; deviceState = QAudio::StoppedState; emit stateChanged(deviceState); return false; } snd_pcm_nonblock( handle, 0 ); // Step 2: Set the desired HW parameters. snd_pcm_hw_params_alloca( &hwparams ); bool fatal = false; QString errMessage; unsigned int chunks = 8; err = snd_pcm_hw_params_any( handle, hwparams ); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_any: err = %1").arg(err); } if ( !fatal ) { err = snd_pcm_hw_params_set_rate_resample( handle, hwparams, 1 ); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_rate_resample: err = %1").arg(err); } } if ( !fatal ) { err = snd_pcm_hw_params_set_access( handle, hwparams, access ); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_access: err = %1").arg(err); } } if ( !fatal ) { err = setFormat(); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_format: err = %1").arg(err); } } if ( !fatal ) { err = snd_pcm_hw_params_set_channels( handle, hwparams, (unsigned int)settings.channelCount() ); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_channels: err = %1").arg(err); } } if ( !fatal ) { err = snd_pcm_hw_params_set_rate_near( handle, hwparams, &sampleRate, 0 ); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_rate_near: err = %1").arg(err); } } if ( !fatal ) { err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, &dir); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_buffer_time_near: err = %1").arg(err); } } if ( !fatal ) { err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, &dir); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_period_time_near: err = %1").arg(err); } } if ( !fatal ) { err = snd_pcm_hw_params_set_periods_near(handle, hwparams, &chunks, &dir); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_periods_near: err = %1").arg(err); } } if ( !fatal ) { err = snd_pcm_hw_params(handle, hwparams); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params: err = %1").arg(err); } } if( err < 0) { qWarning()<<errMessage; errorState = QAudio::OpenError; deviceState = QAudio::StoppedState; emit stateChanged(deviceState); return false; } snd_pcm_hw_params_get_buffer_size(hwparams,&buffer_frames); buffer_size = snd_pcm_frames_to_bytes(handle,buffer_frames); snd_pcm_hw_params_get_period_size(hwparams,&period_frames, &dir); period_size = snd_pcm_frames_to_bytes(handle,period_frames); snd_pcm_hw_params_get_buffer_time(hwparams,&buffer_time, &dir); snd_pcm_hw_params_get_period_time(hwparams,&period_time, &dir); // Step 3: Set the desired SW parameters. snd_pcm_sw_params_t *swparams; snd_pcm_sw_params_alloca(&swparams); snd_pcm_sw_params_current(handle, swparams); snd_pcm_sw_params_set_start_threshold(handle,swparams,period_frames); snd_pcm_sw_params_set_stop_threshold(handle,swparams,buffer_frames); snd_pcm_sw_params_set_avail_min(handle, swparams,period_frames); snd_pcm_sw_params(handle, swparams); // Step 4: Prepare audio ringBuffer.resize(buffer_size); snd_pcm_prepare( handle ); snd_pcm_start(handle); // Step 5: Setup timer bytesAvailable = checkBytesReady(); if(pullMode) connect(audioSource,SIGNAL(readyRead()),this,SLOT(userFeed())); // Step 6: Start audio processing chunks = buffer_size/period_size; timer->start(period_time*chunks/2000); errorState = QAudio::NoError; totalTimeValue = 0; return true; }
/* ------- PCM INITS --------------------------------- */ static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params,int *chs) { #ifndef ALSAAPI9 unsigned int rrate; int err, dir; int channels_allocated = 0; /* choose all parameters */ err = snd_pcm_hw_params_any(handle, params); if (err < 0) { check_error(err,"Broken configuration: no configurations available"); return err; } /* set the nointerleaved read/write format */ err = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_MMAP_NONINTERLEAVED); if (err >= 0) { #ifdef ALSAMM_DEBUG if(sys_verbose) post("Access type %s available","SND_PCM_ACCESS_MMAP_NONINTERLEAVED"); #endif } else{ check_error(err,"No Accesstype SND_PCM_ACCESS_MMAP_NONINTERLEAVED"); return err; } /* set the sample format */ err = snd_pcm_hw_params_set_format(handle, params, ALSAMM_FORMAT); if (err < 0) { check_error(err,"Sample format not available for playback"); return err; } #ifdef ALSAMM_DEBUG if(sys_verbose) post("Setting format to %s",snd_pcm_format_name(ALSAMM_FORMAT)); #endif /* first check samplerate since channels numbers are samplerate dependent (double speed) */ /* set the stream rate */ rrate = alsamm_sr; #ifdef ALSAMM_DEBUG if(sys_verbose) post("Samplerate request: %i Hz",rrate); #endif dir=-1; err = snd_pcm_hw_params_set_rate_near(handle, params, &rrate, &dir); if (err < 0) { check_error(err,"Rate not available"); return err; } if (rrate != alsamm_sr) { post("Warning: rate %iHz doesn't match requested %iHz", rrate,alsamm_sr); alsamm_sr = rrate; } else if(sys_verbose) post("Samplerate is set to %iHz",alsamm_sr); /* Info on channels */ { int maxchs,minchs,channels = *chs; if((err = snd_pcm_hw_params_get_channels_max(params, (unsigned int *)&maxchs)) < 0){ check_error(err,"Getting channels_max not available"); return err; } if((err = snd_pcm_hw_params_get_channels_min(params, (unsigned int *)&minchs)) < 0){ check_error(err,"Getting channels_min not available"); return err; } #ifdef ALSAMM_DEBUG if(sys_verbose) post("Getting channels:min=%d, max= %d for request=%d",minchs,maxchs,channels); #endif if(channels < 0)channels=maxchs; if(channels > maxchs)channels = maxchs; if(channels < minchs)channels = minchs; if(channels != *chs) post("requested channels=%d but used=%d",*chs,channels); *chs = channels; #ifdef ALSAMM_DEBUG if(sys_verbose) post("trying to use channels: %d",channels); #endif } /* set the count of channels */ err = snd_pcm_hw_params_set_channels(handle, params, *chs); if (err < 0) { check_error(err,"Channels count not available"); return err; } /* testing for channels */ if((err = snd_pcm_hw_params_get_channels(params,(unsigned int *)chs)) < 0) check_error(err,"Get channels not available"); #ifdef ALSAMM_DEBUG else if(sys_verbose) post("When setting channels count and got %d",*chs); #endif /* if buffersize is set use this instead buffertime */ if(alsamm_buffersize > 0){ #ifdef ALSAMM_DEBUG if(sys_verbose) post("hw_params: ask for max buffersize of %d samples", (unsigned int) alsamm_buffersize ); #endif alsamm_buffer_size = alsamm_buffersize; err = snd_pcm_hw_params_set_buffer_size_near(handle, params, (unsigned long *)&alsamm_buffer_size); if (err < 0) { check_error(err,"Unable to set max buffer size"); return err; } } else{ if(alsamm_buffertime <= 0) /* should never happen, but use 20ms */ alsamm_buffertime = 20000; #ifdef ALSAMM_DEBUG if(sys_verbose) post("hw_params: ask for max buffertime of %d ms", (unsigned int) (alsamm_buffertime*0.001) ); #endif err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &alsamm_buffertime, &dir); if (err < 0) { check_error(err,"Unable to set max buffer time"); return err; } } err = snd_pcm_hw_params_get_buffer_time(params, (unsigned int *)&alsamm_buffertime, &dir); if (err < 0) { check_error(err,"Unable to get buffer time"); return err; } #ifdef ALSAMM_DEBUG if(sys_verbose) post("hw_params: got buffertime to %f ms", (float) (alsamm_buffertime*0.001)); #endif err = snd_pcm_hw_params_get_buffer_size(params, (unsigned long *)&alsamm_buffer_size); if (err < 0) { check_error(err,"Unable to get buffer size"); return err; } #ifdef ALSAMM_DEBUG if(sys_verbose) post("hw_params: got buffersize to %d samples",(int) alsamm_buffer_size); #endif err = snd_pcm_hw_params_get_period_size(params, (unsigned long *)&alsamm_period_size, &dir); if (err > 0) { check_error(err,"Unable to get period size"); return err; } #ifdef ALSAMM_DEBUG if(sys_verbose) post("Got period size of %d", (int) alsamm_period_size); #endif { unsigned int pmin,pmax; err = snd_pcm_hw_params_get_periods_min(params, &pmin, &dir); if (err > 0) { check_error(err,"Unable to get period size"); return err; } err = snd_pcm_hw_params_get_periods_min(params, &pmax, &dir); if (err > 0) { check_error(err,"Unable to get period size"); return err; } /* use maximum of periods */ if( alsamm_periods <= 0) alsamm_periods = pmax; alsamm_periods = (alsamm_periods > pmax)?pmax:alsamm_periods; alsamm_periods = (alsamm_periods < pmin)?pmin:alsamm_periods; err = snd_pcm_hw_params_set_periods(handle, params, alsamm_periods, dir); if (err > 0) { check_error(err,"Unable to set periods"); return err; } err = snd_pcm_hw_params_get_periods(params, &pmin, &dir); if (err > 0) { check_error(err,"Unable to get periods"); return err; } #ifdef ALSAMM_DEBUG if(sys_verbose) post("Got periods of %d, where periodsmin=%d, periodsmax=%d", alsamm_periods,pmin,pmax); #endif } /* write the parameters to device */ err = snd_pcm_hw_params(handle, params); if (err < 0) { check_error(err,"Unable to set hw params"); return err; } #endif /* ALSAAPI9 */ return 0; }
int main( int argc, char *argv[] ) { struct structArgs cmdArgs; unsigned int val, val2; int dir; int errNum; cmdArgs.card = 0; // Default card. cmdArgs.control = 1; // Default control. // ************************************************************************ // ALSA control elements. // ************************************************************************ snd_pcm_t *pcmp; snd_pcm_hw_params_t *params; // snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK; snd_pcm_stream_t stream = SND_PCM_STREAM_CAPTURE; snd_pcm_uframes_t frames; // ************************************************************************ // Get command line parameters. // ************************************************************************ argp_parse( &argp, argc, argv, 0, 0, &cmdArgs ); printf( "Card = %i\n", cmdArgs.card ); printf( "Control = %i\n", cmdArgs.control ); sprintf( cmdArgs.deviceID, "hw:%i,%i", cmdArgs.card, cmdArgs.control ); printf( "Using device %s :", cmdArgs.deviceID ); /* Allocate a hardware parameters object. */ if ( snd_pcm_hw_params_alloca( ¶ms ) < 0 ) { fprintf( stderr, "Unable to allocate.\n" ); return -1; } /* Open PCM device for playback. */ // if ( snd_pcm_open( &pcmp, cmdArgs.deviceID, stream, 0 ) < 0 ) // { // fprintf( stderr, "Unable to open pcm device.\n" ); // return -1; // } /* Fill it in with default values. */ // if ( snd_pcm_hw_params_any( pcmp, params ) < 0 // { // fprintf( stderr, "Unable to set default values.\n" ); // return -1; // } /* Interleaved mode */ // snd_pcm_hw_params_set_access( pcmp, params, // SND_PCM_ACCESS_RW_INTERLEAVED ); /* Signed 16-bit little-endian format */ snd_pcm_hw_params_set_format( pcmp, params, SND_PCM_FORMAT_S16_LE ); /* Two channels (stereo) */ snd_pcm_hw_params_set_channels( pcmp, params, 2 ); /* 44100 bits/second sampling rate (CD quality) */ val = 44100; snd_pcm_hw_params_set_rate_near( pcmp, params, &val, &dir ); /* Write the parameters to the driver */ errNum = snd_pcm_hw_params( pcmp, params ); if ( errNum < 0 ) { fprintf(stderr, "unable to set hw parameters: %s\n", snd_strerror( errNum )); exit( 1 ); } /* Display information about the PCM interface */ printf( "PCM handle name = '%s'\n", snd_pcm_name( pcmp )); printf("PCM state = %s\n", snd_pcm_state_name( snd_pcm_state( pcmp ))); snd_pcm_hw_params_get_access( params, ( snd_pcm_access_t * ) &val ); printf( "access type = %s\n", snd_pcm_access_name(( snd_pcm_access_t ) val )); snd_pcm_hw_params_get_format( params, ( snd_pcm_format_t * ) &val ); printf( "format = '%s' (%s)\n", snd_pcm_format_name(( snd_pcm_format_t ) val ), snd_pcm_format_description(( snd_pcm_format_t ) val )); snd_pcm_hw_params_get_subformat( params, ( snd_pcm_subformat_t * ) &val ); printf( "subformat = '%s' (%s)\n", snd_pcm_subformat_name(( snd_pcm_subformat_t ) val ), snd_pcm_subformat_description(( snd_pcm_subformat_t ) val )); snd_pcm_hw_params_get_channels( params, &val ); printf( "channels = %d\n", val ); snd_pcm_hw_params_get_rate( params, &val, &dir ); printf( "rate = %d bps\n", val ); snd_pcm_hw_params_get_period_time( params, &val, &dir ); printf( "period time = %d us\n", val ); snd_pcm_hw_params_get_period_size( params, &frames, &dir ); printf( "period size = %d frames\n", ( int ) frames ); snd_pcm_hw_params_get_buffer_time( params, &val, &dir ); printf( "buffer time = %d us\n", val ); snd_pcm_hw_params_get_buffer_size( params, ( snd_pcm_uframes_t * ) &val ); printf( "buffer size = %d frames\n", val ); snd_pcm_hw_params_get_periods( params, &val, &dir ); printf( "periods per buffer = %d frames\n", val ); snd_pcm_hw_params_get_rate_numden( params, &val, &val2 ); printf( "exact rate = %d/%d bps\n", val, val2 ); val = snd_pcm_hw_params_get_sbits( params ); printf( "significant bits = %d\n", val ); // snd_pcm_hw_params_get_tick_time( params, &val, &dir ); // printf( "tick time = %d us\n", val ); val = snd_pcm_hw_params_is_batch( params ); printf( "is batch = %d\n", val ); val = snd_pcm_hw_params_is_block_transfer( params ); printf( "is block transfer = %d\n", val ); val = snd_pcm_hw_params_is_double( params ); printf( "is double = %d\n", val ); val = snd_pcm_hw_params_is_half_duplex( params ); printf( "is half duplex = %d\n", val ); val = snd_pcm_hw_params_is_joint_duplex( params ); printf( "is joint duplex = %d\n", val ); val = snd_pcm_hw_params_can_overrange( params ); printf( "can overrange = %d\n", val ); val = snd_pcm_hw_params_can_mmap_sample_resolution( params ); printf( "can mmap = %d\n", val ); val = snd_pcm_hw_params_can_pause( params ); printf( "can pause = %d\n", val ); val = snd_pcm_hw_params_can_resume( params ); printf( "can resume = %d\n", val ); val = snd_pcm_hw_params_can_sync_start( params ); printf( "can sync start = %d\n", val ); snd_pcm_close( pcmp ); return 0; }
int main() { int rc; snd_pcm_t* handle; snd_pcm_hw_params_t* params; unsigned int val; unsigned int val2; int dir; snd_pcm_uframes_t frames; if ( (rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0) { std::cerr << "unable to open pcm devices: " << snd_strerror(rc) << std::endl; exit(1); } snd_pcm_hw_params_alloca(¶ms); snd_pcm_hw_params_any(handle, params); snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); snd_pcm_hw_params_set_channels(handle, params, 2); val = 44100; snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); if ( (rc = snd_pcm_hw_params(handle, params)) < 0) { std::cerr << "unable to set hw parameters: " << snd_strerror(rc) << std::endl; exit(1); } std::cout << "PCM handle name = " << snd_pcm_name(handle) << std::endl; std::cout << "PCM state = " << snd_pcm_state_name(snd_pcm_state(handle)) << std::endl; snd_pcm_hw_params_get_access(params, (snd_pcm_access_t *)&val); std::cout << "access type = " << snd_pcm_access_name((snd_pcm_access_t)val) << std::endl; snd_pcm_hw_params_get_format(params, (snd_pcm_format_t*)(&val)); std::cout << "format = '" << snd_pcm_format_name((snd_pcm_format_t)val) << "' (" << snd_pcm_format_description((snd_pcm_format_t)val) << ")" << std::endl; snd_pcm_hw_params_get_subformat(params, (snd_pcm_subformat_t *)&val); std::cout << "subformat = '" << snd_pcm_subformat_name((snd_pcm_subformat_t)val) << "' (" << snd_pcm_subformat_description((snd_pcm_subformat_t)val) << ")" << std::endl; snd_pcm_hw_params_get_channels(params, &val); std::cout << "channels = " << val << std::endl; snd_pcm_hw_params_get_rate(params, &val, &dir); std::cout << "rate = " << val << " bps" << std::endl; snd_pcm_hw_params_get_period_time(params, &val, &dir); std::cout << "period time = " << val << " us" << std::endl; snd_pcm_hw_params_get_period_size(params, &frames, &dir); std::cout << "period size = " << static_cast<int>(frames) << " frames" << std::endl; snd_pcm_hw_params_get_buffer_time(params, &val, &dir); std::cout << "buffer time = " << val << " us" << std::endl; snd_pcm_hw_params_get_buffer_size(params, (snd_pcm_uframes_t *) &val); std::cout << "buffer size = " << val << " frames" << std::endl; snd_pcm_hw_params_get_periods(params, &val, &dir); std::cout << "periods per buffer = " << val << " frames" << std::endl; snd_pcm_hw_params_get_rate_numden(params, &val, &val2); std::cout << "exact rate = " << val/val2 << " bps" << std::endl; val = snd_pcm_hw_params_get_sbits(params); std::cout << "significant bits = " << val << std::endl; snd_pcm_hw_params_get_tick_time(params, &val, &dir); std::cout << "tick time = " << val << " us" << std::endl; val = snd_pcm_hw_params_is_batch(params); std::cout << "is batch = " << val << std::endl; val = snd_pcm_hw_params_is_block_transfer(params); std::cout << "is block transfer = " << val << std::endl; val = snd_pcm_hw_params_is_double(params); std::cout << "is double = " << val << std::endl; val = snd_pcm_hw_params_is_half_duplex(params); std::cout << "is half duplex = " << val << std::endl; val = snd_pcm_hw_params_is_joint_duplex(params); std::cout << "is joint duplex = " << val << std::endl; val = snd_pcm_hw_params_can_overrange(params); std::cout << "can overrange = " << val << std::endl; val = snd_pcm_hw_params_can_mmap_sample_resolution(params); std::cout << "can mmap = " << val << std::endl; val = snd_pcm_hw_params_can_pause(params); std::cout << "can pause = " << val << std::endl; val = snd_pcm_hw_params_can_resume(params); std::cout << "can resume = " << val << std::endl; val = snd_pcm_hw_params_can_sync_start(params); std::cout << "can sync start = " << val << std::endl; snd_pcm_close(handle); return 0; }
int main() { int rc; snd_pcm_t *handle; snd_pcm_hw_params_t *params; unsigned int val, val2; int dir; snd_pcm_uframes_t frames; /* Open PCM device for playback. */ rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0); if (rc < 0) { fprintf(stderr, "unable to open pcm device: %s\n", snd_strerror(rc)); exit(1); } /* Allocate a hardware parameters object. */ snd_pcm_hw_params_alloca(¶ms); /* Fill it in with default values. */ snd_pcm_hw_params_any(handle, params); /* Set the desired hardware parameters. */ /* Interleaved mode */ snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); /* Signed 16-bit little-endian format */ snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); /* Two channels (stereo) */ snd_pcm_hw_params_set_channels(handle, params, 2); /* 44100 bits/second sampling rate (CD quality) */ val = 44100; snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); /* Write the parameters to the driver */ rc = snd_pcm_hw_params(handle, params); if (rc < 0) { fprintf(stderr, "unable to set hw parameters: %s\n", snd_strerror(rc)); exit(1); } /* Display information about the PCM interface */ printf("PCM handle name = '%s'\n", snd_pcm_name(handle)); printf("PCM state = %s\n", snd_pcm_state_name(snd_pcm_state(handle))); snd_pcm_hw_params_get_access(params, (snd_pcm_access_t *) &val); printf("access type = %s\n", snd_pcm_access_name((snd_pcm_access_t)val)); snd_pcm_hw_params_get_format(params, &val); printf("format = '%s' (%s)\n", snd_pcm_format_name((snd_pcm_format_t)val), snd_pcm_format_description( (snd_pcm_format_t)val)); snd_pcm_hw_params_get_subformat(params, (snd_pcm_subformat_t *)&val); printf("subformat = '%s' (%s)\n", snd_pcm_subformat_name((snd_pcm_subformat_t)val), snd_pcm_subformat_description( (snd_pcm_subformat_t)val)); snd_pcm_hw_params_get_channels(params, &val); printf("channels = %d\n", val); snd_pcm_hw_params_get_rate(params, &val, &dir); printf("rate = %d bps\n", val); snd_pcm_hw_params_get_period_time(params, &val, &dir); printf("period time = %d us\n", val); snd_pcm_hw_params_get_period_size(params, &frames, &dir); printf("period size = %d frames\n", (int)frames); snd_pcm_hw_params_get_buffer_time(params, &val, &dir); printf("buffer time = %d us\n", val); snd_pcm_hw_params_get_buffer_size(params, (snd_pcm_uframes_t *) &val); printf("buffer size = %d frames\n", val); snd_pcm_hw_params_get_periods(params, &val, &dir); printf("periods per buffer = %d frames\n", val); snd_pcm_hw_params_get_rate_numden(params, &val, &val2); printf("exact rate = %d/%d bps\n", val, val2); val = snd_pcm_hw_params_get_sbits(params); printf("significant bits = %d\n", val); snd_pcm_hw_params_get_tick_time(params, &val, &dir); printf("tick time = %d us\n", val); val = snd_pcm_hw_params_is_batch(params); printf("is batch = %d\n", val); val = snd_pcm_hw_params_is_block_transfer(params); printf("is block transfer = %d\n", val); val = snd_pcm_hw_params_is_double(params); printf("is double = %d\n", val); val = snd_pcm_hw_params_is_half_duplex(params); printf("is half duplex = %d\n", val); val = snd_pcm_hw_params_is_joint_duplex(params); printf("is joint duplex = %d\n", val); val = snd_pcm_hw_params_can_overrange(params); printf("can overrange = %d\n", val); val = snd_pcm_hw_params_can_mmap_sample_resolution(params); printf("can mmap = %d\n", val); val = snd_pcm_hw_params_can_pause(params); printf("can pause = %d\n", val); val = snd_pcm_hw_params_can_resume(params); printf("can resume = %d\n", val); val = snd_pcm_hw_params_can_sync_start(params); printf("can sync start = %d\n", val); snd_pcm_close(handle); return 0; }
int main() { const snd_pcm_channel_area_t *areas; int size; unsigned char *buffer; char *pcm_name; unsigned int rate = 8000; int chan; int rc; unsigned int val; char check; int pcmreturn; //Set PCM stream and handle snd_pcm_t *pcm_handle; snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK; //Set HARDWARE parameters snd_pcm_hw_params_t *hwparams; //pcm_name = (char *)malloc(10); pcm_name = "plughw:0,0"; //allocate memory for hardware if(snd_pcm_hw_params_malloc(&hwparams)<0) { fprintf(stderr,"No memory allocated for hardware"); return(-1); } if (snd_pcm_open(&pcm_handle, pcm_name, stream, 0) < 0) { fprintf(stderr, "Error opening PCM device %s\n", pcm_name); return(-1); } //INITIALIZE HARDWARE WITH CONFIGURATION OF THE SOUNDCARD if(snd_pcm_hw_params_any(pcm_handle,hwparams)<0) { fprintf(stderr,"The hardware device cannot be configured\n"); } //SET FORMAT TO 16 BIT LITTLE ENDIAN snd_pcm_hw_params_set_format(pcm_handle,hwparams,SND_PCM_FORMAT_S16_LE); /* Two channels (stereo) */ snd_pcm_hw_params_set_channels(pcm_handle,hwparams,2); /* 44100 bits/second sampling rate (CD quality) */ if (snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0) { fprintf(stderr, "Error setting access.\n"); return(-1); } //SETTING RATE ie SAMPLING FREQUENCY snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &rate, 0); //SETTING HARDWARE PARAMETERS if(rc=(snd_pcm_hw_params(pcm_handle,hwparams))<0) { fprintf(stderr,"\nCannot set hardware parameters\n"); return -1; } //snd_pcm_uframes_t periodsize = 8192; snd_pcm_uframes_t frames,offset ;//OF TYPE UNSIGNED LONG snd_pcm_sframes_t commitres; //frames =32; //SETTING SOME MORE PARAMETERS //size = frames*4; //SETTING BUFFER SIZE /*if (snd_pcm_hw_params_set_buffer_size(pcm_handle, hwparams, (periodsize*2)>>2) < 0) { fprintf(stderr, "Error setting buffersize.\n"); return(-1); } */ int first=0;; int err; snd_pcm_sframes_t avail = snd_pcm_avail_update(pcm_handle); printf("\nNumber of frames available is : %d \n",(int)avail); //------------------------------------------------------------------------------------------------------- //<<<<<<<<<<<<<<<<<<<<<<DISPLAYING INFORMATION>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> //Buffer size snd_pcm_hw_params_get_buffer_size(hwparams, (snd_pcm_uframes_t*)&val); printf("\nThe buffer size is %d \n",val); //Buffer time snd_pcm_hw_params_get_buffer_time(hwparams, &val,0); printf("\nBuffer time is : %d \n",val); //Period size snd_pcm_hw_params_get_period_size(hwparams,&frames,0); printf("\nperiod size : %d \n",(int)frames); //////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// //<<<<<<<<<<<<<mmap_begin>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> err=snd_pcm_mmap_begin(pcm_handle,&areas,&offset,&frames); //Periods between buffer snd_pcm_hw_params_get_periods(hwparams,&val,0); printf("\n Periods between buffer is : %d \n",val); //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>. if(err<0) { printf("\nMMAP error\n"); return -1; } else printf("\n%d\n",err); /* commitres = snd_pcm_mmap_commit(pcm_handle,offset,frames); if(commitres<0) { printf("\nFrames not committed to memory\n"); } */ //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<,OPENING FILE>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.... int dest = open("sample3.wav",O_RDONLY); if(dest<0) { perror("\nFile could not be opened\n"); return -1; } //buffer = (unsigned char *)malloc(1000); /* unsigned long buf = offset; if(read(dest,&offset,1)<0) { perror("\nNo destination for read\n"); return -1; } */ /* avail=snd_pcm_avail_update(pcm_handle); printf("\nAvailable frames = %d \n\n",(int)avail); struct timeval tvbefore,tvafter; gettimeofday(&tvbefore,NULL); */ unsigned char *ptr[2]; int i; //unsigned int steps=0; for(i=0;i<2;i++) ptr[i] = (unsigned char*)areas[i].addr + (areas[i].first/8) + offset*(areas[i].step/8); printf("\nOffset of the first sample : %u \n",areas[0].first); printf("\n\nOffset of the memory map is : %u \n",areas[0].step/8); printf("\nAreas start address is : %u \n",areas[0].addr); printf("\nNumber of frames ; %u \n",frames); printf("\n\nPointer before ; %u \n",ptr[0]); long pl; for(pl=0;pl<100000;pl++); if(ptr[1]==NULL) printf("\nNull pointer 1 allocated\n"); if(ptr[0]==NULL) printf("\nNull pointer 0 allocated \n"); int check2=1; snd_pcm_sframes_t size2 =30; while(1) { for(i=0;i<2;i++) { //ptr[i] = (unsigned char*)areas[i].addr + (areas[i].first/8) + offset*(areas[i].step/8); if(read(dest,ptr[i],120)!=0) { if(ptr[i]!=NULL) { if(pcmreturn = snd_pcm_mmap_writei(pcm_handle,ptr[i],size2)<0) { snd_pcm_prepare(pcm_handle); printf("\n<<<<<<<Buffer Underrun>>>>>>>>\n"); break; } // printf("\n%d\n",pcmreturn); ptr[i]+=0; printf("\n%lu\n",ptr[i]); } } else { check2=0; break; } } if(check2==0) break; // l:break; } commitres = snd_pcm_mmap_commit(pcm_handle,offset,frames); if(commitres<0) { printf("\nFrames not committed to memory\n"); } }
int main() { const snd_pcm_channel_area_t *areas; int size; unsigned char *buffer; char *pcm_name; unsigned int rate = 44100; int chan; int rc; unsigned int val; char check; int pcmreturn; //Set PCM stream and handle snd_pcm_t *pcm_handle; snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK; //Set HARDWARE parameters snd_pcm_hw_params_t *hwparams; //pcm_name = (char *)malloc(10); pcm_name = "plughw:0,0"; //allocate memory for hardware if(snd_pcm_hw_params_malloc(&hwparams)<0) { fprintf(stderr,"No memory allocated for hardware"); return(-1); } if (snd_pcm_open(&pcm_handle, pcm_name, stream, 0) < 0) { fprintf(stderr, "Error opening PCM device %s\n", pcm_name); return(-1); } //INITIALIZE HARDWARE WITH CONFIGURATION OF THE SOUNDCARD if(snd_pcm_hw_params_any(pcm_handle,hwparams)<0) { fprintf(stderr,"The hardware device cannot be configured\n"); } //SET FORMAT TO 16 BIT LITTLE ENDIAN snd_pcm_hw_params_set_format(pcm_handle,hwparams,SND_PCM_FORMAT_S16_LE); /* Two channels (stereo) */ snd_pcm_hw_params_set_channels(pcm_handle,hwparams,2); /* 44100 bits/second sampling rate (CD quality) */ if (snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0) { fprintf(stderr, "Error setting access.\n"); return(-1); } //SETTING RATE ie SAMPLING FREQUENCY snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &rate, 0); //SETTING HARDWARE PARAMETERS if(rc=(snd_pcm_hw_params(pcm_handle,hwparams))<0) { fprintf(stderr,"\nCannot set hardware parameters\n"); return -1; } //snd_pcm_uframes_t periodsize = 8192; snd_pcm_uframes_t frames,offset ;//OF TYPE UNSIGNED LONG snd_pcm_sframes_t commitres; frames =32; //SETTING SOME MORE PARAMETERS size = frames*4; //SETTING BUFFER SIZE /*if (snd_pcm_hw_params_set_buffer_size(pcm_handle, hwparams, (periodsize*2)>>2) < 0) { fprintf(stderr, "Error setting buffersize.\n"); return(-1); } */ int first=0;; int err; snd_pcm_sframes_t avail = snd_pcm_avail_update(pcm_handle); printf("\nNumber of frames available is : %d \n",(int)avail); //------------------------------------------------------------------------------------------------------- //<<<<<<<<<<<<<<<<<<<<<<DISPLAYING INFORMATION>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> //Buffer size snd_pcm_hw_params_get_buffer_size(hwparams, (snd_pcm_uframes_t*)&val); printf("\nThe buffer size is %d \n",val); //Buffer time snd_pcm_hw_params_get_buffer_time(hwparams, &val,0); printf("\nBuffer time is : %d \n",val); //Period size snd_pcm_hw_params_get_period_size(hwparams,&frames,0); printf("\nperiod size : %d \n",(int)frames); //Periods between buffers err=snd_pcm_mmap_begin(pcm_handle,&areas,&offset,&frames); //Periods between buffer snd_pcm_hw_params_get_periods(hwparams,&val,0); printf("\n Periods between buffer is : %d \n",val); //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>. if(err<0) { printf("\nMMAP error\n"); return -1; } else printf("\n%d\n",err); commitres = snd_pcm_mmap_commit(pcm_handle,offset,frames); if(commitres<0) { printf("\nFrames not committed to memory\n"); } int dest = open("sample3.wav",O_RDONLY); if(dest<0) { perror("\nFile could not be opened\n"); return -1; } //int *c = offset; buffer = (unsigned char *)malloc(1000); unsigned long buf = offset; if(read(dest,&offset,1)<0) { perror("\nNo destination for read\n"); return -1; } struct timeval tvbefore,tvafter; gettimeofday(&tvbefore,NULL); while(read(dest,buffer,100)!=0); gettimeofday(&tvafter,NULL); printf("\nTime taken by read() is %09ld \n",tvafter.tv_usec-tvbefore.tv_usec); /* while(1) { if(read(dest,&offset,80)!=0) { //fread(buffer,sizeof(buffer),160,f1); { if(pcmreturn = snd_pcm_mmap_writei(pcm_handle,&offset,80)<0) { snd_pcm_prepare(pcm_handle); printf("\n<<<<<<<Buffer Underrun>>>>>>>>\n"); break; } } } else break; } */ }
Player::Player() { // printf("Player::Player()\n"); int rc=0; unsigned int val=0; int dir=0; /* Open PCM device for playback. */ rc = snd_pcm_open(&(this->m_pHandle), "default", SND_PCM_STREAM_PLAYBACK, 0); if (rc < 0) { printf("unable to open pcm device: %s\n", snd_strerror(rc)); exit(1); } /* Allocate a hardware parameters object. */ snd_pcm_hw_params_alloca(&(this->m_pParams)); /* Fill it in with default values. */ rc = snd_pcm_hw_params_any(this->m_pHandle, this->m_pParams); if (rc < 0) { printf("Can not configure this PCM device: %s\n", snd_strerror(rc)); exit(1); } /* Set the desired hardware parameters. */ /* Interleaved mode */ rc = snd_pcm_hw_params_set_access(this->m_pHandle, this->m_pParams, SND_PCM_ACCESS_RW_INTERLEAVED); if (rc < 0) { printf("Failed to set PCM device to interleaved: %s\n", snd_strerror(rc)); exit(1); } /* Signed 16-bit little-endian format */ rc = snd_pcm_hw_params_set_format(this->m_pHandle, this->m_pParams, SND_PCM_FORMAT_S16_LE); if (rc < 0) { printf("Failed to set PCM device to 16-bit signed PCM: %s\n", snd_strerror(rc)); exit(1); } /* Two channels (mono) */ rc = snd_pcm_hw_params_set_channels(this->m_pHandle, this->m_pParams,channels); if (rc < 0) { printf("Failed to set PCM device to mono: %s\n", snd_strerror(rc)); exit(1); } /* 44100 bits/second sampling rate (CD quality) */ val = rate; rc = snd_pcm_hw_params_set_rate_near(this->m_pHandle, this->m_pParams, &val, 0); if (rc < 0) { printf("Failed to set PCM device to sample rate =%d: %s\n", rate,snd_strerror(rc)); exit(1); } if(val != rate){ printf("Rate doesn't match (request %iHz, get %iHz\n",rate,val); exit(1); } rc = snd_pcm_hw_params_set_buffer_time_near(this->m_pHandle, this->m_pParams, &buffer_time, &dir); if (rc < 0) { fprintf(stderr, "Failed to set PCM device to buffer time=%d: %s\n", val,snd_strerror(rc)); exit(1); } rc = snd_pcm_hw_params_set_period_time_near(this->m_pHandle, this->m_pParams, &period_time, &dir); if (rc < 0) { fprintf(stderr, "Failed to set PCM device to period time=%d: %s\n", val,snd_strerror(rc)); exit(1); } //chunk size rc = snd_pcm_hw_params_get_period_size(this->m_pParams, &period_size, &dir); if(rc < 0){ fprintf(stderr, "Failed to get period size for capture: %s\n", snd_strerror(rc)); exit(1); } this->m_frames = period_size; rc = snd_pcm_hw_params_get_buffer_size(this->m_pParams, &buffer_size); if(rc < 0){ fprintf(stderr, "Failed to get buffer size for capture: %s\n", snd_strerror(rc)); exit(1); } #ifdef DEBUG printf("Recorder alsa driver hw params setting\n"); printf("period size =%d frames\n", (int)period_size); printf("buffer size =%d frames\n", (int)buffer_size); snd_pcm_hw_params_get_period_time(this->m_pParams,&val, &dir); printf("period time =%d us\n",val); snd_pcm_hw_params_get_buffer_time(this->m_pParams,&val, &dir); printf("buffer time =%d us\n", val); snd_pcm_hw_params_get_periods(this->m_pParams, &val, &dir); printf("period per buffer =%d frames\n", val); #endif /* Write the parameters to the driver */ rc = snd_pcm_hw_params(this->m_pHandle, this->m_pParams); if (rc < 0) { printf("unable to set hw parameters: %s\n", snd_strerror(rc)); exit(1); } #ifdef ALSA_OPT snd_pcm_sw_params_t *swparams; snd_pcm_sw_params_alloca(&swparams); /* get the current swparams */ rc = snd_pcm_sw_params_current(this->m_pHandle, swparams); if (rc < 0) { printf("Unable to determine current swparams for playback: %s\n", snd_strerror(rc)); exit(1); } /* start the transfer when the buffer is almost full: */ /* (buffer_size / avail_min) * avail_min */ rc = snd_pcm_sw_params_set_start_threshold(this->m_pHandle, swparams, (buffer_size / period_size) * period_size); if (rc < 0) { printf("Unable to set start threshold mode for playback: %s\n", snd_strerror(rc)); exit(1); } rc = snd_pcm_sw_params_set_avail_min(this->m_pHandle, swparams, period_size); if (rc < 0) { printf("Unable to set avail min for playback: %s\n", snd_strerror(rc)); exit(1); } /* write the parameters to the playback device */ rc = snd_pcm_sw_params(this->m_pHandle, swparams); if (rc < 0) { printf("Unable to set sw params for playback: %s\n", snd_strerror(rc)); exit(1); } #endif }
bool QAudioInputPrivate::open( QObject *input ) { // Open the Alsa capture device. bool rc = true; int err; unsigned int freakuency = frequency; if ((err = snd_pcm_open(&handle, m_device.constData(), //"plughw:0,0" SND_PCM_STREAM_CAPTURE, 0/*SND_PCM_ASYNC*/)) < 0) { qWarning( "QAudioInput: snd_pcm_open: error %d", err); rc = false; } else { snd_pcm_hw_params_t *hwparams; // We want non-blocking mode. snd_pcm_nonblock(handle, 1); // Set the desired parameters. snd_pcm_hw_params_alloca(&hwparams); err = snd_pcm_hw_params_any(handle, hwparams); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_hw_params_any: err %d", err); } err = snd_pcm_hw_params_set_access(handle, hwparams, access); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_hw_params_set_access: err %d",err); } err = snd_pcm_hw_params_set_format(handle, hwparams,format); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_hw_params_set_format: err %d",err); } err = snd_pcm_hw_params_set_channels(handle,hwparams,(unsigned int)channels); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_hw_params_set_channels: err %d",err); } err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &freakuency, 0); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_hw_params_set_rate_near: err %d",err); } if(freakuency > 1.05 * frequency || freakuency < 0.95 * frequency) { qWarning("QAudioInput: warning, sample rate %i not supported by the hardware, using %u", frequency, freakuency); } if ( samplesPerBlock != -1 ) { // Set buffer and period sizes based on the supplied block size. sample_size = (snd_pcm_uframes_t)( samplesPerBlock * channels / 8 ); err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &freakuency, 0); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_hw_params_set_rate_near: err %d",err); } if(freakuency > 1.05 * frequency || freakuency < 0.95 * frequency) { qWarning( "QAudioInput: warning, sample rate %i not supported by the hardware, using %u", frequency, freakuency); } err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, 0); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_hw_params_set_buffer_time_near: err %d",err); } period_time = 1000000 * 256 / frequency; err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, 0); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_hw_params_set_period_time_near: err %d",err); } } else { // Use the largest buffer and period sizes we can. err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, 0); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_hw_params_set_buffer_time_near: err %d",err); } period_time = 1000000 * 256 / frequency; err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, 0); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_hw_params_set_period_time_near: err %d",err); } } err = snd_pcm_hw_params(handle, hwparams); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_hw_params: err %d",err); } int dir; unsigned int vval, vval2; snd_pcm_access_t aval; snd_pcm_format_t fval; snd_pcm_subformat_t sval; qLog(QAudioInput) << "PCM handle name = " << snd_pcm_name(handle); qLog(QAudioInput) << "PCM state = " << snd_pcm_state_name(snd_pcm_state(handle)); snd_pcm_hw_params_get_access(hwparams,&aval); vval = (unsigned int)aval; if ( (int)vval != (int)access ) { qLog(QAudioInput) << QString("access type not set, want %1 got %2") .arg(snd_pcm_access_name((snd_pcm_access_t)access)) .arg(snd_pcm_access_name((snd_pcm_access_t)vval)); access = (snd_pcm_access_t)vval; } qLog(QAudioInput) << "access type = " << snd_pcm_access_name((snd_pcm_access_t)vval); snd_pcm_hw_params_get_format(hwparams, &fval); vval = (unsigned int)fval; if ( (int)vval != (int)format ) { qLog(QAudioInput) << QString("format type not set, want %1 got %2") .arg(snd_pcm_format_name((snd_pcm_format_t)format)) .arg(snd_pcm_format_name((snd_pcm_format_t)vval)); format = (snd_pcm_format_t)vval; } qLog(QAudioInput) << QString("format = '%1' (%2)") .arg(snd_pcm_format_name((snd_pcm_format_t)vval)) .arg(snd_pcm_format_description((snd_pcm_format_t)vval)) .toLatin1().constData(); snd_pcm_hw_params_get_subformat(hwparams,&sval); vval = (unsigned int)sval; qLog(QAudioInput) << QString("subformat = '%1' (%2)") .arg(snd_pcm_subformat_name((snd_pcm_subformat_t)vval)) .arg(snd_pcm_subformat_description((snd_pcm_subformat_t)vval)) .toLatin1().constData(); snd_pcm_hw_params_get_channels(hwparams, &vval); if ( (int)vval != (int)channels ) { qLog(QAudioInput) << QString("channels type not set, want %1 got %2").arg(channels).arg(vval); channels = vval; } qLog(QAudioInput) << "channels = " << vval; snd_pcm_hw_params_get_rate(hwparams, &vval, &dir); if ( (int)vval != (int)frequency ) { qLog(QAudioInput) << QString("frequency type not set, want %1 got %2").arg(frequency).arg(vval); frequency = vval; } qLog(QAudioInput) << "rate =" << vval << " bps"; snd_pcm_hw_params_get_period_time(hwparams,&period_time, &dir); qLog(QAudioInput) << "period time =" << period_time << " us"; snd_pcm_hw_params_get_period_size(hwparams,&period_size, &dir); qLog(QAudioInput) << "period size =" << (int)period_size; snd_pcm_hw_params_get_buffer_time(hwparams,&buffer_time, &dir); qLog(QAudioInput) << "buffer time =" << buffer_time; snd_pcm_hw_params_get_buffer_size(hwparams,(snd_pcm_uframes_t *) &buffer_size); qLog(QAudioInput) << "buffer size =" << (int)buffer_size; snd_pcm_hw_params_get_periods(hwparams, &vval, &dir); qLog(QAudioInput) << "periods per buffer =" << vval; snd_pcm_hw_params_get_rate_numden(hwparams, &vval, &vval2); qLog(QAudioInput) << QString("exact rate = %1/%2 bps").arg(vval).arg(vval2).toLatin1().constData(); vval = snd_pcm_hw_params_get_sbits(hwparams); qLog(QAudioInput) << "significant bits =" << vval; snd_pcm_hw_params_get_tick_time(hwparams,&vval, &dir); qLog(QAudioInput) << "tick time =" << vval; vval = snd_pcm_hw_params_is_batch(hwparams); qLog(QAudioInput) << "is batch =" << vval; vval = snd_pcm_hw_params_is_block_transfer(hwparams); qLog(QAudioInput) << "is block transfer =" << vval; vval = snd_pcm_hw_params_is_double(hwparams); qLog(QAudioInput) << "is double =" << vval; vval = snd_pcm_hw_params_is_half_duplex(hwparams); qLog(QAudioInput) << "is half duplex =" << vval; vval = snd_pcm_hw_params_is_joint_duplex(hwparams); qLog(QAudioInput) << "is joint duplex =" << vval; vval = snd_pcm_hw_params_can_overrange(hwparams); qLog(QAudioInput) << "can overrange =" << vval; vval = snd_pcm_hw_params_can_mmap_sample_resolution(hwparams); qLog(QAudioInput) << "can mmap =" << vval; vval = snd_pcm_hw_params_can_pause(hwparams); qLog(QAudioInput) << "can pause =" << vval; vval = snd_pcm_hw_params_can_resume(hwparams); qLog(QAudioInput) << "can resume =" << vval; vval = snd_pcm_hw_params_can_sync_start(hwparams); qLog(QAudioInput) << "can sync start =" << vval; snd_pcm_sw_params_t *swparams; snd_pcm_sw_params_alloca(&swparams); err = snd_pcm_sw_params_current(handle, swparams); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_sw_params_current: err %d",err); } err = snd_pcm_sw_params_set_start_threshold(handle,swparams,period_size); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_sw_params_set_start_threshold: err %d",err); } err = snd_pcm_sw_params_set_avail_min(handle, swparams,period_size); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_sw_params_set_avail_min: err %d",err); } err = snd_pcm_sw_params_set_xfer_align(handle, swparams, 1); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_sw_params_set_xfer_align: err %d",err); } err = snd_pcm_sw_params(handle, swparams); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_sw_params: err %d",err); } snd_pcm_prepare(handle); snd_pcm_start(handle); int count = snd_pcm_poll_descriptors_count(handle); pollfd *pfds = new pollfd[count]; snd_pcm_poll_descriptors(handle, pfds, count); for (int i = 0; i < count; ++i) { if ((pfds[i].events & POLLIN) != 0) { notifier = new QSocketNotifier(pfds[i].fd, QSocketNotifier::Read); QObject::connect(notifier, SIGNAL(activated(int)), input, SIGNAL(readyRead())); break; } } if (notifier == NULL) { rc = false; } delete pfds; } return rc; }
int main() { long loops; int rc,i = 0; int size; FILE *fp ; snd_pcm_t *handle; snd_pcm_hw_params_t *params; unsigned int val,val2; int dir; snd_pcm_uframes_t frames; char *buffer; if( (fp =fopen("sound.wav","w")) < 0) printf("open sound.wav fial\n"); /* Open PCM device for recording (capture). */ rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_CAPTURE, 0); if (rc < 0) { fprintf(stderr, "unable to open pcm device: %s/n", snd_strerror(rc)); exit(1); } /* Allocate a hardware parameters object. */ snd_pcm_hw_params_alloca(¶ms); /* Fill it in with default values. */ snd_pcm_hw_params_any(handle, params); /* Set the desired hardware parameters. */ /* Interleaved mode */ snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); /* Signed 16-bit little-endian format */ snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); /* Two channels (stereo) */ snd_pcm_hw_params_set_channels(handle, params, 2); /* 44100 bits/second sampling rate (CD quality) */ val = 44100; snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); /* Set period size to 32 frames. */ frames = 32; snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); /* Write the parameters to the driver */ rc = snd_pcm_hw_params(handle, params); if (rc < 0) { fprintf(stderr, "unable to set hw parameters: %s/n", snd_strerror(rc)); exit(1); } /* Use a buffer large enough to hold one period */ snd_pcm_hw_params_get_period_size(params, &frames, &dir); size = frames * 4; /* 2 bytes/sample, 2 channels */ printf("size = %d\n",size); buffer = (char *) malloc(size); /* We want to loop for 5 seconds */ snd_pcm_hw_params_get_period_time(params, &val, &dir); loops = 10000000 / val; while (loops > 0) { loops--; rc = snd_pcm_readi(handle, buffer, frames); printf("%d\n",i++); if (rc == -EPIPE) { /* EPIPE means overrun */ fprintf(stderr, "overrun occurred/n"); snd_pcm_prepare(handle); } else if (rc < 0) { fprintf(stderr, "error from read: %s/n", snd_strerror(rc)); } else if (rc != (int)frames) { fprintf(stderr, "short read, read %d frames/n", rc); } //rc = fwrite( buffer,1, size,fp); rc = write(1,buffer,size); if (rc != size) fprintf(stderr, "short write: wrote %d bytes/n", rc); else printf("fwrite buffer success\n"); } /******************打印参数*********************/ snd_pcm_hw_params_get_channels(params, &val); printf("channels = %d\n", val); snd_pcm_hw_params_get_rate(params, &val, &dir); printf("rate = %d bps\n", val); snd_pcm_hw_params_get_period_time(params, &val, &dir); printf("period time = %d us\n", val); snd_pcm_hw_params_get_period_size(params, &frames, &dir); printf("period size = %d frames\n", (int)frames); snd_pcm_hw_params_get_buffer_time(params, &val, &dir); printf("buffer time = %d us\n", val); snd_pcm_hw_params_get_buffer_size(params, (snd_pcm_uframes_t *) &val); printf("buffer size = %d frames\n", val); snd_pcm_hw_params_get_periods(params, &val, &dir); printf("periods per buffer = %d frames\n", val); snd_pcm_hw_params_get_rate_numden(params, &val, &val2); printf("exact rate = %d/%d bps\n", val, val2); val = snd_pcm_hw_params_get_sbits(params); printf("significant bits = %d\n", val); //snd_pcm_hw_params_get_tick_time(params, &val, &dir); printf("tick time = %d us\n", val); val = snd_pcm_hw_params_is_batch(params); printf("is batch = %d\n", val); val = snd_pcm_hw_params_is_block_transfer(params); printf("is block transfer = %d\n", val); val = snd_pcm_hw_params_is_double(params); printf("is double = %d\n", val); val = snd_pcm_hw_params_is_half_duplex(params); printf("is half duplex = %d\n", val); val = snd_pcm_hw_params_is_joint_duplex(params); printf("is joint duplex = %d\n", val); val = snd_pcm_hw_params_can_overrange(params); printf("can overrange = %d\n", val); val = snd_pcm_hw_params_can_mmap_sample_resolution(params); printf("can mmap = %d\n", val); val = snd_pcm_hw_params_can_pause(params); printf("can pause = %d\n", val); val = snd_pcm_hw_params_can_resume(params); printf("can resume = %d\n", val); val = snd_pcm_hw_params_can_sync_start(params); printf("can sync start = %d\n", val); /*******************************************************************/ snd_pcm_drain(handle); snd_pcm_close(handle); fclose(fp); free(buffer); return 0; }
int main() { int result; snd_pcm_t *handle = NULL; snd_pcm_hw_params_t *params = NULL; snd_pcm_uframes_t frames; snd_pcm_access_t access; snd_pcm_format_t format; unsigned int rate = 44100; unsigned int val, val2; int dir = 0; const char *device = getenv ("ALSA_DEFAULT"); if (device == NULL) { device = "default"; } result = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0); if (result < 0) showErrorAndExit(result, "Error: Unable to open PCM device: %s\n"); result = snd_pcm_hw_params_malloc(¶ms); if (result < 0) showErrorAndExit(result, "Error: No memory for hardware parameters: %s\n"); result = snd_pcm_hw_params_any(handle, params); if (result < 0) showErrorAndExit(result, "Error: Cannot read HW params: %s\n"); result = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); if (result < 0) showErrorAndExit(result, "Could not set access method: %s\n"); result = snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); if (result < 0) showErrorAndExit(result, "Error: Could not set output format: %s\n"); result = snd_pcm_hw_params_set_channels(handle, params, 1); if (result < 0) showErrorAndExit(result, "Error: Cannot set to 1 channel: %s\n"); result = snd_pcm_hw_params_set_rate_near(handle, params, &rate, &dir); if (result < 0) showErrorAndExit(result, "Error: Could not set rate: %s\n"); result = snd_pcm_hw_params(handle, params); if (result < 0) showErrorAndExit(result, "Error: Could not write HW params: %s\n"); printf("Card Parameters\n"); printf("%30s: %s\n", "Alsa Library Version", snd_asoundlib_version()); result = snd_pcm_hw_params_get_access(params, &access); if (result < 0) { showErrorAndExit(result, "Error: Could not retrieve access mode: %s\n"); } else { printf("%30s: %s\n", "Access Method", snd_pcm_access_name(access)); } result = snd_pcm_hw_params_get_format(params, &format); if (result < 0) { showErrorAndExit(result, "Error: Unable to retrieve format type: %d\n"); } else { printf("%30s: %s\n", "Format", snd_pcm_format_name(format)); } result = snd_pcm_hw_params_get_channels(params, &val); if (result < 0) { showErrorAndExit(result, "Error: Unable to retrieve channel count: %s\n"); } else { printf("%30s: %d\n", "Channels", val); } result = snd_pcm_hw_params_get_rate(params, &val, &dir); if (result < 0) { showErrorAndExit(result, "Error: Unable to retrieve rate: %s\n"); } else { printf("%30s: %d bps\n", "Rate", val); } result = snd_pcm_hw_params_get_period_time(params, &val, &dir); if (result < 0) { showErrorAndExit(result, "Error: Unable to retrieve period time: %s\n"); } else { printf("%30s: %d us\n", "Period Time", val); } result = snd_pcm_hw_params_get_period_size(params, &frames, &dir); if (result < 0) { showErrorAndExit(result, "Error: Unable to retrieve period size: %s\n"); } else { printf("%30s: %d frames\n", "Period Size", (int) frames); } result = snd_pcm_hw_params_get_buffer_time(params, &val, &dir); if (result < 0) { showErrorAndExit(result, "Error: Unable to retrieve buffer time: %s\n"); } else { printf("%30s: %d us\n", "Buffer Time", val); } result = snd_pcm_hw_params_get_buffer_size(params, &frames); if (result < 0) { showErrorAndExit(result, "Error: Unable to retrieve buffer size: %s\n"); } else { printf("%30s: %d frames\n", "Buffer Size", (int) frames); } result = snd_pcm_hw_params_get_periods(params, &val, &dir); if (result < 0) { showErrorAndExit(result, "Error: Unable to get buffer periods: %s\n"); } else { printf("%30s: %d frames\n", "Periods per Buffer", val); } result = snd_pcm_hw_params_get_rate_numden(params, &val, &val2); if (result < 0) { showErrorAndExit(result, "Error: Unable to get rate numerator/denominator: %s\n"); } else { printf("%30s: %d/%d bps\n", "Exact Rate", val, val2); } val = snd_pcm_hw_params_get_sbits(params); printf("%30s: %d\n", "Significant Bits", val); result = snd_pcm_hw_params_get_tick_time(params, &val, &dir); if (result < 0) { showErrorAndExit(result, "Error: Could not retrieve tick time: %s\n"); } else { printf("%30s: %d\n", "Tick Time", val); } printf("Card Capabilities\n"); val = snd_pcm_hw_params_is_batch(params); printf("%30s: %s\n", "Batch Transfer", (val ? "Yes" : "No")); val = snd_pcm_hw_params_is_block_transfer(params); printf("%30s: %s\n", "Block Transfer", (val ? "Yes" : "No")); val = snd_pcm_hw_params_is_double(params); printf("%30s: %s\n", "Double Buffering", (val ? "Yes" : "No")); val = snd_pcm_hw_params_is_half_duplex(params); printf("%30s: %s\n", "Half Duplex Only", (val ? "Yes" : "No")); val = snd_pcm_hw_params_is_joint_duplex(params); printf("%30s: %s\n", "Joint Duplex Capable", (val ? "Yes" : "No")); val = snd_pcm_hw_params_can_overrange(params); printf("%30s: %s\n", "Support Overrange Detection", (val ? "Yes" : "No")); val = snd_pcm_hw_params_can_mmap_sample_resolution(params); printf("%30s: %s\n", "Support Sample-res Mmap", (val ? "Yes" : "No")); val = snd_pcm_hw_params_can_pause(params); printf("%30s: %s\n", "Can Pause", (val ? "Yes" : "No")); val = snd_pcm_hw_params_can_resume(params); printf("%30s: %s\n", "Can Resume", (val ? "Yes" : "No")); val = snd_pcm_hw_params_can_sync_start(params); printf("%30s: %s\n", "Support Sync Start", (val ? "Yes" : "No")); result = snd_pcm_close(handle); if (result < 0) showErrorAndExit(result, "Error: Could not close PCM device: %s\n"); return 0; }
/** * Set up the snd_pcm_t object which was opened by the caller. Set up * the configured settings and the audio format. */ static bool alsa_setup(struct alsa_data *ad, struct audio_format *audio_format, GError **error) { snd_pcm_hw_params_t *hwparams; snd_pcm_sw_params_t *swparams; unsigned int sample_rate = audio_format->sample_rate; unsigned int channels = audio_format->channels; snd_pcm_uframes_t alsa_buffer_size; snd_pcm_uframes_t alsa_period_size; int err; const char *cmd = NULL; int retry = MPD_ALSA_RETRY_NR; unsigned int period_time, period_time_ro; unsigned int buffer_time; period_time_ro = period_time = ad->period_time; configure_hw: /* configure HW params */ snd_pcm_hw_params_alloca(&hwparams); cmd = "snd_pcm_hw_params_any"; err = snd_pcm_hw_params_any(ad->pcm, hwparams); if (err < 0) goto error; if (ad->use_mmap) { err = snd_pcm_hw_params_set_access(ad->pcm, hwparams, SND_PCM_ACCESS_MMAP_INTERLEAVED); if (err < 0) { g_warning("Cannot set mmap'ed mode on ALSA device \"%s\": %s\n", alsa_device(ad), snd_strerror(-err)); g_warning("Falling back to direct write mode\n"); ad->use_mmap = false; } else ad->writei = snd_pcm_mmap_writei; } if (!ad->use_mmap) { cmd = "snd_pcm_hw_params_set_access"; err = snd_pcm_hw_params_set_access(ad->pcm, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) goto error; ad->writei = snd_pcm_writei; } err = alsa_output_setup_format(ad->pcm, hwparams, audio_format); if (err < 0) { g_set_error(error, alsa_output_quark(), err, "ALSA device \"%s\" does not support format %s: %s", alsa_device(ad), sample_format_to_string(audio_format->format), snd_strerror(-err)); return false; } err = snd_pcm_hw_params_set_channels_near(ad->pcm, hwparams, &channels); if (err < 0) { g_set_error(error, alsa_output_quark(), err, "ALSA device \"%s\" does not support %i channels: %s", alsa_device(ad), (int)audio_format->channels, snd_strerror(-err)); return false; } audio_format->channels = (int8_t)channels; err = snd_pcm_hw_params_set_rate_near(ad->pcm, hwparams, &sample_rate, NULL); if (err < 0 || sample_rate == 0) { g_set_error(error, alsa_output_quark(), err, "ALSA device \"%s\" does not support %u Hz audio", alsa_device(ad), audio_format->sample_rate); return false; } audio_format->sample_rate = sample_rate; snd_pcm_uframes_t buffer_size_min, buffer_size_max; snd_pcm_hw_params_get_buffer_size_min(hwparams, &buffer_size_min); snd_pcm_hw_params_get_buffer_size_max(hwparams, &buffer_size_max); unsigned buffer_time_min, buffer_time_max; snd_pcm_hw_params_get_buffer_time_min(hwparams, &buffer_time_min, 0); snd_pcm_hw_params_get_buffer_time_max(hwparams, &buffer_time_max, 0); g_debug("buffer: size=%u..%u time=%u..%u", (unsigned)buffer_size_min, (unsigned)buffer_size_max, buffer_time_min, buffer_time_max); snd_pcm_uframes_t period_size_min, period_size_max; snd_pcm_hw_params_get_period_size_min(hwparams, &period_size_min, 0); snd_pcm_hw_params_get_period_size_max(hwparams, &period_size_max, 0); unsigned period_time_min, period_time_max; snd_pcm_hw_params_get_period_time_min(hwparams, &period_time_min, 0); snd_pcm_hw_params_get_period_time_max(hwparams, &period_time_max, 0); g_debug("period: size=%u..%u time=%u..%u", (unsigned)period_size_min, (unsigned)period_size_max, period_time_min, period_time_max); if (ad->buffer_time > 0) { buffer_time = ad->buffer_time; cmd = "snd_pcm_hw_params_set_buffer_time_near"; err = snd_pcm_hw_params_set_buffer_time_near(ad->pcm, hwparams, &buffer_time, NULL); if (err < 0) goto error; } else { err = snd_pcm_hw_params_get_buffer_time(hwparams, &buffer_time, NULL); if (err < 0) buffer_time = 0; } if (period_time_ro == 0 && buffer_time >= 10000) { period_time_ro = period_time = buffer_time / 4; g_debug("default period_time = buffer_time/4 = %u/4 = %u", buffer_time, period_time); } if (period_time_ro > 0) { period_time = period_time_ro; cmd = "snd_pcm_hw_params_set_period_time_near"; err = snd_pcm_hw_params_set_period_time_near(ad->pcm, hwparams, &period_time, NULL); if (err < 0) goto error; } cmd = "snd_pcm_hw_params"; err = snd_pcm_hw_params(ad->pcm, hwparams); if (err == -EPIPE && --retry > 0 && period_time_ro > 0) { period_time_ro = period_time_ro >> 1; goto configure_hw; } else if (err < 0)
bool ALSAPCMPlayer::SetParameters(snd_pcm_t &alsa_handle, unsigned sample_rate, bool big_endian_source, unsigned latency, unsigned &channels) { /* adoption of alsa-libs's snd_pcm_set_params() function, which is not * available on SALSA, with a few detail enhancements. */ snd_pcm_hw_params_t *hw_params; snd_pcm_hw_params_alloca(&hw_params); int alsa_error = snd_pcm_hw_params_any(&alsa_handle, hw_params); if (alsa_error < 0) { LogFormat("snd_pcm_hw_params_any(0x%p, 0x%p) failed: %d - %s", &alsa_handle, hw_params, alsa_error, snd_strerror(alsa_error)); return false; } /* Try to enable resampling, but do not give up if it fails. Probably we are * lucky and our ALSA device supports our sample rate natively. */ snd_pcm_hw_params_set_rate_resample(&alsa_handle, hw_params, 1); alsa_error = snd_pcm_hw_params_set_access(&alsa_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); if (0 != alsa_error) { LogFormat("snd_pcm_hw_params_set_access(0x%p, 0x%p, " "SND_PCM_ACCESS_RW_INTERLEAVED) failed: %d - %s", &alsa_handle, hw_params, alsa_error, snd_strerror(alsa_error)); return false; } alsa_error = snd_pcm_hw_params_set_format(&alsa_handle, hw_params, big_endian_source ? SND_PCM_FORMAT_S16_BE : SND_PCM_FORMAT_S16_LE); if (0 != alsa_error) { LogFormat("snd_pcm_hw_params_set_format(0x%p, 0x%p, " "%s) failed: %d - %s", &alsa_handle, hw_params, big_endian_source ? "SND_PCM_FORMAT_S16_BE" : "SND_PCM_FORMAT_S16_LE", alsa_error, snd_strerror(alsa_error)); return false; } assert(1 == channels); alsa_error = snd_pcm_hw_params_set_channels_near(&alsa_handle, hw_params, &channels); if (0 != alsa_error) { LogFormat("snd_pcm_hw_params_set_channels_near(0x%p, 0x%p, 0x%p) " "failed: %d - %s", &alsa_handle, hw_params, &channels, alsa_error, snd_strerror(alsa_error)); return false; } alsa_error = snd_pcm_hw_params_set_rate(&alsa_handle, hw_params, sample_rate, 0); if (0 != alsa_error) { LogFormat("snd_pcm_hw_params_set_rate(0x%p, 0x%p, %u, 0) " "failed: %d - %s", &alsa_handle, hw_params, sample_rate, alsa_error, snd_strerror(alsa_error)); return false; } snd_pcm_uframes_t buffer_size, period_size; alsa_error = snd_pcm_hw_params_set_buffer_time_near(&alsa_handle, hw_params, &latency, nullptr); if (0 != alsa_error) { unsigned period_time = latency / 4; alsa_error = snd_pcm_hw_params_set_period_time_near(&alsa_handle, hw_params, &period_time, nullptr); if (0 != alsa_error) { LogFormat("snd_pcm_hw_params_set_period_time_near(0x%p, 0x%p, 0x%p, " "nullptr) failed: %d - %s", &alsa_handle, hw_params, &period_time, alsa_error, snd_strerror(alsa_error)); return false; } alsa_error = snd_pcm_hw_params_get_period_size(hw_params, &period_size, nullptr); if (0 != alsa_error) { LogFormat("snd_pcm_hw_params_get_period_size(0x%p, 0x%p, nullptr) " "failed: %d - %s", hw_params, &period_size, alsa_error, snd_strerror(alsa_error)); return false; } buffer_size = period_size * 4; alsa_error = snd_pcm_hw_params_set_buffer_size_near(&alsa_handle, hw_params, &buffer_size); if (0 != alsa_error) { LogFormat("snd_pcm_hw_params_set_buffer_size_near(0x%p, 0x%p, 0x%p) " "failed: %d - %s", &alsa_handle, hw_params, &buffer_size, alsa_error, snd_strerror(alsa_error)); return false; } alsa_error = snd_pcm_hw_params_get_buffer_size(hw_params, &buffer_size); if (0 != alsa_error) { LogFormat("snd_pcm_hw_params_get_buffer_size(0x%p, 0x%p) " "failed: %d - %s", hw_params, &buffer_size, alsa_error, snd_strerror(alsa_error)); return false; } } else { alsa_error = snd_pcm_hw_params_get_buffer_size(hw_params, &buffer_size); if (0 != alsa_error) { LogFormat("snd_pcm_hw_params_get_buffer_size(0x%p, 0x%p) " "failed: %d - %s", hw_params, &buffer_size, alsa_error, snd_strerror(alsa_error)); return false; } alsa_error = snd_pcm_hw_params_get_buffer_time(hw_params, &latency, nullptr); if (0 != alsa_error) { LogFormat("snd_pcm_hw_params_get_buffer_time(0x%p, 0x%p, nullptr) " "failed: %d - %s", hw_params, &latency, alsa_error, snd_strerror(alsa_error)); return false; } unsigned period_time = latency / 4; alsa_error = snd_pcm_hw_params_set_period_time_near(&alsa_handle, hw_params, &period_time, nullptr); if (0 != alsa_error) { LogFormat("snd_pcm_hw_params_set_period_time_near(0x%p, 0x%p, 0x%p, " "nullptr) failed: %d - %s", &alsa_handle, hw_params, &period_time, alsa_error, snd_strerror(alsa_error)); return false; } alsa_error = snd_pcm_hw_params_get_period_size(hw_params, &period_size, nullptr); if (0 != alsa_error) { LogFormat("snd_pcm_hw_params_get_period_size(0x%p, 0x%p, nullptr) " "failed: %d - %s", hw_params, &period_size, alsa_error, snd_strerror(alsa_error)); return false; } } alsa_error = snd_pcm_hw_params(&alsa_handle, hw_params); if (0 != alsa_error) { LogFormat("snd_pcm_hw_params(0x%p, 0x%p) failed: %d - %s", &alsa_handle, hw_params, alsa_error, snd_strerror(alsa_error)); return false; } snd_pcm_sw_params_t *sw_params; snd_pcm_sw_params_alloca(&sw_params); alsa_error = snd_pcm_sw_params_current(&alsa_handle, sw_params); if (0 != alsa_error) { LogFormat("snd_pcm_sw_params_current(0x%p, 0x%p) failed: %d - %s", &alsa_handle, sw_params, alsa_error, snd_strerror(alsa_error)); return false; } snd_pcm_uframes_t start_threshold = (buffer_size / period_size) * period_size; alsa_error = snd_pcm_sw_params_set_start_threshold(&alsa_handle, sw_params, start_threshold); if (0 != alsa_error) { LogFormat("snd_pcm_sw_params_set_start_threshold(0x%p, 0x%p, %u) " "failed: %d - %s", &alsa_handle, sw_params, static_cast<unsigned>(start_threshold), alsa_error, snd_strerror(alsa_error)); return false; } alsa_error = snd_pcm_sw_params_set_avail_min(&alsa_handle, sw_params, period_size); if (0 != alsa_error) { LogFormat("snd_pcm_sw_params_set_avail_min(0x%p, 0x%p, %u) failed: %d - %s", &alsa_handle, sw_params, static_cast<unsigned>(period_size), alsa_error, snd_strerror(alsa_error)); return false; } alsa_error = snd_pcm_sw_params(&alsa_handle, sw_params); if (0 != alsa_error) { LogFormat("snd_pcm_sw_params(0x%p, 0x%p) failed: %d - %s", &alsa_handle, sw_params, alsa_error, snd_strerror(alsa_error)); return false; } return true; }
status_t setHardwareParams(alsa_handle_t *handle) { snd_pcm_hw_params_t *hardwareParams; status_t err; snd_pcm_uframes_t bufferSize = handle->bufferSize; unsigned int requestedRate = handle->sampleRate; unsigned int latency = handle->latency; // snd_pcm_format_description() and snd_pcm_format_name() do not perform // proper bounds checking. bool validFormat = (static_cast<int> (handle->format) > SND_PCM_FORMAT_UNKNOWN) && (static_cast<int> (handle->format) <= SND_PCM_FORMAT_LAST); const char *formatDesc = validFormat ? snd_pcm_format_description( handle->format) : "Invalid Format"; const char *formatName = validFormat ? snd_pcm_format_name(handle->format) : "UNKNOWN"; if (snd_pcm_hw_params_malloc(&hardwareParams) < 0) { LOG_ALWAYS_FATAL("Failed to allocate ALSA hardware parameters!"); return NO_INIT; } err = snd_pcm_hw_params_any(handle->handle, hardwareParams); if (err < 0) { ALOGE("Unable to configure hardware: %s", snd_strerror(err)); goto done; } // Set the interleaved read and write format. err = snd_pcm_hw_params_set_access(handle->handle, hardwareParams, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { ALOGE("Unable to configure PCM read/write format: %s", snd_strerror(err)); goto done; } err = snd_pcm_hw_params_set_format(handle->handle, hardwareParams, handle->format); if (err < 0) { ALOGE("Unable to configure PCM format %s (%s): %s", formatName, formatDesc, snd_strerror(err)); goto done; } ALOGW("Set %s PCM format to %s (%s)", streamName(handle), formatName, formatDesc); err = snd_pcm_hw_params_set_channels(handle->handle, hardwareParams, handle->channels); if (err < 0) { ALOGE("Unable to set channel count to %i: %s", handle->channels, snd_strerror(err)); goto done; } ALOGW("Using %i %s for %s.", handle->channels, handle->channels == 1 ? "channel" : "channels", streamName(handle)); ALOGW("requestedRate=%d\n", requestedRate); err = snd_pcm_hw_params_set_rate_near(handle->handle, hardwareParams, &requestedRate, 0); ALOGW("returned Rate=%d, handle->rate=%d\n", requestedRate, handle->sampleRate); if (err < 0) ALOGE("Unable to set %s sample rate to %u: %s", streamName(handle), handle->sampleRate, snd_strerror(err)); else if (requestedRate != handle->sampleRate) // Some devices have a fixed sample rate, and can not be changed. // This may cause resampling problems; i.e. PCM playback will be too // slow or fast. ALOGW("Requested rate (%u HZ) does not match actual rate (%u HZ)", handle->sampleRate, requestedRate); else ALOGI("Set %s sample rate to %u HZ", streamName(handle), requestedRate); #ifdef DISABLE_HARWARE_RESAMPLING // Disable hardware re-sampling. err = snd_pcm_hw_params_set_rate_resample(handle->handle, hardwareParams, static_cast<int>(resample)); if (err < 0) { ALOGE("Unable to %s hardware resampling: %s", resample ? "enable" : "disable", snd_strerror(err)); goto done; } #endif // Make sure we have at least the size we originally wanted err = snd_pcm_hw_params_set_buffer_size_near(handle->handle, hardwareParams, &bufferSize); if (err < 0) { ALOGE("Unable to set buffer size to %d: %s", (int)bufferSize, snd_strerror(err)); goto done; } // Setup buffers for latency err = snd_pcm_hw_params_set_buffer_time_near(handle->handle, hardwareParams, &latency, NULL); if (err < 0) { /* That didn't work, set the period instead */ unsigned int periodTime = latency / 4; err = snd_pcm_hw_params_set_period_time_near(handle->handle, hardwareParams, &periodTime, NULL); if (err < 0) { ALOGE("Unable to set the period time for latency: %s", snd_strerror(err)); goto done; } snd_pcm_uframes_t periodSize; err = snd_pcm_hw_params_get_period_size(hardwareParams, &periodSize, NULL); if (err < 0) { ALOGE("Unable to get the period size for latency: %s", snd_strerror(err)); goto done; } bufferSize = periodSize * 4; if (bufferSize < handle->bufferSize) bufferSize = handle->bufferSize; err = snd_pcm_hw_params_set_buffer_size_near(handle->handle, hardwareParams, &bufferSize); if (err < 0) { ALOGE("Unable to set the buffer size for latency: %s", snd_strerror(err)); goto done; } } else { // OK, we got buffer time near what we expect. See what that did for bufferSize. err = snd_pcm_hw_params_get_buffer_size(hardwareParams, &bufferSize); if (err < 0) { ALOGE("Unable to get the buffer size for latency: %s", snd_strerror(err)); goto done; } // Does set_buffer_time_near change the passed value? It should. err = snd_pcm_hw_params_get_buffer_time(hardwareParams, &latency, NULL); if (err < 0) { ALOGE("Unable to get the buffer time for latency: %s", snd_strerror(err)); goto done; } unsigned int periodTime = latency / 4; err = snd_pcm_hw_params_set_period_time_near(handle->handle, hardwareParams, &periodTime, NULL); if (err < 0) { ALOGE("Unable to set the period time for latency: %s", snd_strerror(err)); goto done; } } ALOGI("Buffer size: %d", (int)bufferSize); ALOGI("Latency: %d", (int)latency); handle->bufferSize = bufferSize; handle->latency = latency; // Commit the hardware parameters back to the device. err = snd_pcm_hw_params(handle->handle, hardwareParams); if (err < 0) ALOGE("Unable to set hardware parameters: %s", snd_strerror(err)); done: snd_pcm_hw_params_free(hardwareParams); return err; }
static size_t alsa_configure (void) { //<init: size_t chunk_bytes, bits_per_sample, bits_per_frame = 0; snd_pcm_uframes_t chunk_size, buffer_size = 0; snd_pcm_hw_params_t *params; unsigned int rate = DEFAULT_SPEED; int err; snd_pcm_hw_params_alloca (¶ms); //> //<defaults: err = snd_pcm_hw_params_any (AHandle, params); if (err < 0) { fprintf (stderr, "Broken configuration for this PCM: no configurations available"); exit (EXIT_FAILURE); } //> //<Format: err = snd_pcm_hw_params_set_format (AHandle, params, DEFAULT_FORMAT); if (err < 0) { fprintf (stderr, "Sample format non available"); exit (EXIT_FAILURE); } //> //<Channels: err = snd_pcm_hw_params_set_channels (AHandle, params, 1); if (err < 0) { fprintf (stderr, "Channels count non available"); exit (EXIT_FAILURE); } //> //<Rate: err = snd_pcm_hw_params_set_rate_near (AHandle, params, &rate, 0); assert (err >= 0); //> //<Access Mode: err = snd_pcm_hw_params_set_access (AHandle, params, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { fprintf (stderr, "Access type not available"); exit (EXIT_FAILURE); } //> //< Set things explicitly if DEBUG #ifdef DEBUG //<Compute buffer_time: unsigned int period_time = 0; unsigned int buffer_time = 0; snd_pcm_uframes_t period_frames = 0; snd_pcm_uframes_t buffer_frames = 0; // affected by defined buffer_size (e.g. via asoundrc) if (buffer_time == 0 && buffer_frames == 0) { err = snd_pcm_hw_params_get_buffer_time (params, &buffer_time, 0); assert (err >= 0); if (buffer_time > 500000) //usecs buffer_time = 500000; } //> //<Compute period_time: if (period_time == 0 && period_frames == 0) { if (buffer_time > 0) period_time = buffer_time / 4; else period_frames = buffer_frames / 4; } if (period_time > 0) err = snd_pcm_hw_params_set_period_time_near (AHandle, params, &period_time, 0); else err = snd_pcm_hw_params_set_period_size_near (AHandle, params, &period_frames, 0); assert (err >= 0); if (buffer_time > 0) { err = snd_pcm_hw_params_set_buffer_time_near (AHandle, params, &buffer_time, 0); } else { err = snd_pcm_hw_params_set_buffer_size_near (AHandle, params, &buffer_frames); } assert (err >= 0); //> #endif //> //<Commit hw params: err = snd_pcm_hw_params (AHandle, params); if (err < 0) { fprintf (stderr, "Unable to install hw params:"); exit (EXIT_FAILURE); } //> //<finalize chunk_size and buffer_size: snd_pcm_hw_params_get_period_size (params, &chunk_size, 0); snd_pcm_hw_params_get_buffer_size (params, &buffer_size); if (chunk_size == buffer_size) { fprintf (stderr, "Can't use period equal to buffer size (%lu == %lu)", chunk_size, buffer_size); exit (EXIT_FAILURE); } //> //< If DEBUG: SW Params Configure transfer: #ifdef DEBUG size_t n; snd_pcm_uframes_t xfer_align; snd_pcm_uframes_t start_threshold, stop_threshold; int start_delay = 5; int stop_delay = 0; snd_pcm_sw_params_t *swParams; snd_pcm_sw_params_alloca (&swParams); snd_pcm_sw_params_current (AHandle, swParams); err = snd_pcm_sw_params_get_xfer_align (swParams, &xfer_align); if (err < 0) { fprintf (stderr, "Unable to obtain xfer align\n"); exit (EXIT_FAILURE); } // round up to closest transfer boundary n = (buffer_size / xfer_align) * xfer_align; if (start_delay <= 0) { start_threshold = (snd_pcm_uframes_t) (n + (double) rate * start_delay / 1000000); } else start_threshold = (snd_pcm_uframes_t) ((double) rate * start_delay / 1000000); if (start_threshold < 1) start_threshold = 1; if (start_threshold > n) start_threshold = n; err = snd_pcm_sw_params_set_start_threshold (AHandle, swParams, start_threshold); assert (err >= 0); if (stop_delay <= 0) stop_threshold = (snd_pcm_uframes_t) (buffer_size + (double) rate * stop_delay / 1000000); else stop_threshold = (snd_pcm_uframes_t) ((double) rate * stop_delay / 1000000); err = snd_pcm_sw_params_set_stop_threshold (AHandle, swParams, stop_threshold); assert (err >= 0); err = snd_pcm_sw_params_set_xfer_align (AHandle, swParams, xfer_align); assert (err >= 0); if (snd_pcm_sw_params (AHandle, swParams) < 0) { fprintf (stderr, "unable to install sw params:"); exit (EXIT_FAILURE); } #endif //> bits_per_sample = snd_pcm_format_physical_width (DEFAULT_FORMAT); bits_per_frame = bits_per_sample * 1; //mono chunk_bytes = chunk_size * bits_per_frame / 8; return chunk_bytes; }
bool QAudioOutputPrivate::open() { if(opened) return true; #ifdef DEBUG_AUDIO QTime now(QTime::currentTime()); qDebug()<<now.second()<<"s "<<now.msec()<<"ms :open()"; #endif timeStamp.restart(); elapsedTimeOffset = 0; int dir; int err=-1; int count=0; unsigned int freakuency=settings.frequency(); QString dev = QLatin1String(m_device.constData()); QList<QByteArray> devices = QAudioDeviceInfoInternal::availableDevices(QAudio::AudioOutput); if(dev.compare(QLatin1String("default")) == 0) { #if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) dev = QLatin1String(devices.first().constData()); #else dev = QLatin1String("hw:0,0"); #endif } else { #if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) dev = QLatin1String(m_device); #else int idx = 0; char *name; QString shortName = QLatin1String(m_device.mid(m_device.indexOf('=',0)+1).constData()); while(snd_card_get_name(idx,&name) == 0) { if(qstrncmp(shortName.toLocal8Bit().constData(),name,shortName.length()) == 0) break; idx++; } dev = QString(QLatin1String("hw:%1,0")).arg(idx); #endif } // Step 1: try and open the device while((count < 5) && (err < 0)) { err=snd_pcm_open(&handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_PLAYBACK,0); if(err < 0) count++; } if (( err < 0)||(handle == 0)) { errorState = QAudio::OpenError; deviceState = QAudio::StoppedState; return false; } snd_pcm_nonblock( handle, 0 ); // Step 2: Set the desired HW parameters. snd_pcm_hw_params_alloca( &hwparams ); bool fatal = false; QString errMessage; unsigned int chunks = 8; err = snd_pcm_hw_params_any( handle, hwparams ); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_any: err = %1").arg(err); } if ( !fatal ) { err = snd_pcm_hw_params_set_rate_resample( handle, hwparams, 1 ); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_rate_resample: err = %1").arg(err); } } if ( !fatal ) { err = snd_pcm_hw_params_set_access( handle, hwparams, access ); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_access: err = %1").arg(err); } } if ( !fatal ) { err = setFormat(); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_format: err = %1").arg(err); } } if ( !fatal ) { err = snd_pcm_hw_params_set_channels( handle, hwparams, (unsigned int)settings.channels() ); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_channels: err = %1").arg(err); } } if ( !fatal ) { err = snd_pcm_hw_params_set_rate_near( handle, hwparams, &freakuency, 0 ); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_rate_near: err = %1").arg(err); } } if ( !fatal ) { err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, &dir); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_buffer_time_near: err = %1").arg(err); } } if ( !fatal ) { err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, &dir); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_period_time_near: err = %1").arg(err); } } if ( !fatal ) { err = snd_pcm_hw_params_set_periods_near(handle, hwparams, &chunks, &dir); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_periods_near: err = %1").arg(err); } } if ( !fatal ) { err = snd_pcm_hw_params(handle, hwparams); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params: err = %1").arg(err); } } if( err < 0) { qWarning()<<errMessage; errorState = QAudio::OpenError; deviceState = QAudio::StoppedState; return false; } snd_pcm_hw_params_get_buffer_size(hwparams,&buffer_frames); buffer_size = snd_pcm_frames_to_bytes(handle,buffer_frames); snd_pcm_hw_params_get_period_size(hwparams,&period_frames, &dir); period_size = snd_pcm_frames_to_bytes(handle,period_frames); snd_pcm_hw_params_get_buffer_time(hwparams,&buffer_time, &dir); snd_pcm_hw_params_get_period_time(hwparams,&period_time, &dir); // Step 3: Set the desired SW parameters. snd_pcm_sw_params_t *swparams; snd_pcm_sw_params_alloca(&swparams); snd_pcm_sw_params_current(handle, swparams); snd_pcm_sw_params_set_start_threshold(handle,swparams,period_frames); snd_pcm_sw_params_set_stop_threshold(handle,swparams,buffer_frames); snd_pcm_sw_params_set_avail_min(handle, swparams,period_frames); snd_pcm_sw_params(handle, swparams); // Step 4: Prepare audio if(audioBuffer == 0) audioBuffer = new char[snd_pcm_frames_to_bytes(handle,buffer_frames)]; snd_pcm_prepare( handle ); snd_pcm_start(handle); // Step 5: Setup callback and timer fallback snd_async_add_pcm_handler(&ahandler, handle, async_callback, this); bytesAvailable = bytesFree(); // Step 6: Start audio processing timer->start(period_time/1000); clockStamp.restart(); timeStamp.restart(); elapsedTimeOffset = 0; errorState = QAudio::NoError; totalTimeValue = 0; opened = true; return true; }
int main(int argc, char **argv){ int i; int aver,val,val2; int16_t buf[BUFSIZE]; double d_buffer[BUFSIZE]; double pitch = 0.0; struct timespec before,after; struct pitch_tracker_params *settings; snd_pcm_uframes_t period_size = PERIOD_SIZE; //ALSA PCM configuration snd_pcm_t *handle; snd_pcm_hw_params_t *params; int dir,rc; snd_pcm_uframes_t frames; /* Open PCM device for capture */ rc = snd_pcm_open( &handle, "default" , SND_PCM_STREAM_CAPTURE , 0); if(rc < 0 ){ fprintf(stderr,"unable to open pcm device: %s\n",snd_strerror(rc)); exit(1); } /* Allocate a hardware parameters object. */ snd_pcm_hw_params_alloca(¶ms); /* Fill it in with default values. */ snd_pcm_hw_params_any(handle, params); /* Set the desired hardware parameters. */ /* Interleaved mode */ snd_pcm_hw_params_set_access(handle, params,SND_PCM_ACCESS_RW_INTERLEAVED); /* unsigned 16-bit format */ snd_pcm_hw_params_set_format(handle, params,SND_PCM_FORMAT_S16); snd_pcm_hw_params_set_channels(handle, params, 1); /* 44100 bits/second sampling rate */ val = 44100; snd_pcm_hw_params_set_rate_near(handle,params, &val, &dir); /* set size time*/ snd_pcm_hw_params_set_period_size_near(handle, params, &period_size , &dir); /* write configuration */ rc = snd_pcm_hw_params(handle,params); /*Display info*/ printf("PCM handle name = '%s'\n", snd_pcm_name(handle)); printf("PCM state = %s\n", snd_pcm_state_name(snd_pcm_state(handle))); snd_pcm_hw_params_get_access(params, (snd_pcm_access_t *) &val); printf("access type = %s\n", snd_pcm_access_name((snd_pcm_access_t)val)); snd_pcm_hw_params_get_format(params, &val); printf("format = '%s' (%s)\n", snd_pcm_format_name((snd_pcm_format_t)val), snd_pcm_format_description( (snd_pcm_format_t)val)); snd_pcm_hw_params_get_subformat(params, (snd_pcm_subformat_t *)&val); printf("subformat = '%s' (%s)\n", snd_pcm_subformat_name((snd_pcm_subformat_t)val), snd_pcm_subformat_description( (snd_pcm_subformat_t)val)); snd_pcm_hw_params_get_channels(params, &val); printf("channels = %d\n", val); snd_pcm_hw_params_get_rate(params, &val, &dir); printf("rate = %d bps\n", val); snd_pcm_hw_params_get_period_time(params, &val, &dir); printf("period time = %d us\n", val); snd_pcm_hw_params_get_period_size(params, &frames, &dir); printf("period size = %d frames\n", (int)frames); snd_pcm_hw_params_get_buffer_time(params, &val, &dir); printf("buffer time = %d us\n", val); snd_pcm_hw_params_get_buffer_size(params, (snd_pcm_uframes_t *) &val); printf("buffer size = %d frames\n", val); snd_pcm_hw_params_get_periods(params, &val, &dir); printf("periods per buffer = %d frames\n", val); snd_pcm_hw_params_get_rate_numden(params, &val, &val2); printf("exact rate = %d/%d bps\n", val, val2); val = snd_pcm_hw_params_get_sbits(params); printf("significant bits = %d\n", val); val = snd_pcm_hw_params_is_batch(params); printf("is batch = %d\n", val); val = snd_pcm_hw_params_is_block_transfer(params); printf("is block transfer = %d\n", val); val = snd_pcm_hw_params_is_double(params); printf("is double = %d\n", val); val = snd_pcm_hw_params_is_half_duplex(params); printf("is half duplex = %d\n", val); val = snd_pcm_hw_params_is_joint_duplex(params); printf("is joint duplex = %d\n", val); val = snd_pcm_hw_params_can_overrange(params); printf("can overrange = %d\n", val); val = snd_pcm_hw_params_can_mmap_sample_resolution(params); printf("can mmap = %d\n", val); val = snd_pcm_hw_params_can_pause(params); printf("can pause = %d\n", val); val = snd_pcm_hw_params_can_resume(params); printf("can resume = %d\n", val); val = snd_pcm_hw_params_can_sync_start(params); printf("can sync start = %d\n", val); settings = open_pitch_tracker(); while(1){ rc = snd_pcm_readi(handle, buf, frames); if (rc == -EPIPE) { /* EPIPE means overrun */ fprintf(stderr, "overrun occurred\n"); snd_pcm_prepare(handle); } else if (rc < 0) { fprintf(stderr, "error from read: %s\n", snd_strerror(rc)); } else if (rc != (int)frames) { fprintf(stderr, "short read, read %d frames\n", rc); } for( i = 0 ; i< BUFSIZE ; i++){ d_buffer[i] = (double) buf[i]; } pitch = compute_pitch(d_buffer, BUFSIZE, S16, settings ,ACCURACY); if( pitch != 0.0 ) printf("frequency -> %f\n",pitch); memset(buf,0,BUFSIZE); } close_pitch_tracker(&settings); snd_pcm_drain(handle); snd_pcm_close(handle); return 0; }