bool PokeLaunchApplication::sound() { #if JUCE_LINUX int err; int freq = 44100, channels = 2; snd_pcm_hw_params_t *hw_params; snd_pcm_sw_params_t *sw_params; snd_pcm_hw_params_malloc( &hw_params ); snd_pcm_sw_params_malloc( &sw_params ); err = snd_pcm_open( &g_alsa_playback_handle, "default", SND_PCM_STREAM_PLAYBACK, 0 ); if( err < 0 ) { DBG( "ALSA ERROR: Can't open audio device: " << snd_strerror( err ) ); return false; } DBG("Opened Audio Device"); err = snd_pcm_hw_params_any( g_alsa_playback_handle, hw_params ); if( err < 0 ) { DBG( "ALSA ERROR: Can't initialize hardware parameter structure: " << snd_strerror( err ) ); return false; } err = snd_pcm_hw_params_set_access( g_alsa_playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED ); if( err < 0 ) { DBG( "ALSA ERROR: Can't set access type: " << snd_strerror( err ) ); return false; } //const UTF8_CHAR *sample_format = ""; err = snd_pcm_hw_params_set_format( g_alsa_playback_handle, hw_params, SND_PCM_FORMAT_S16_LE ); if( err < 0 ) { DBG( "ALSA ERROR: Can't set sample format :" << snd_strerror( err ) ); return false; } err = snd_pcm_hw_params_set_rate_near( g_alsa_playback_handle, hw_params, (unsigned int*)&freq, 0 ); if( err < 0 ) { DBG( "ALSA ERROR: Can't set sample rate: " << snd_strerror( err ) ); return false; } DBG( "ALSA Sample rate: "<< freq ); err = snd_pcm_hw_params_set_channels( g_alsa_playback_handle, hw_params, channels ); if( err < 0 ) { DBG( "ALSA ERROR: Can't set channel count: " << snd_strerror( err ) ); return false; } snd_pcm_uframes_t frames; frames = DEFAULT_BUFFER_SIZE; err = snd_pcm_hw_params_set_buffer_size_near( g_alsa_playback_handle, hw_params, &frames ); if( err < 0 ) { DBG( "ALSA ERROR: Can't set buffer size: " << snd_strerror( err ) ); return false; } snd_pcm_hw_params_get_buffer_size( hw_params, &frames ); DBG( "ALSA Buffer size: 4096 samples" ); err = snd_pcm_hw_params( g_alsa_playback_handle, hw_params ); if( err < 0 ) { DBG( "ALSA ERROR: Can't set parameters: " << snd_strerror( err ) ); return false; } snd_pcm_hw_params_free( hw_params ); snd_pcm_sw_params_free( sw_params ); err = snd_pcm_prepare( g_alsa_playback_handle ); if( err < 0 ) { DBG( "ALSA ERROR: Can't prepare audio interface for use: " << snd_strerror( err ) ); return false; } /* Stop PCM device and drop pending frames */ snd_pcm_drain(g_alsa_playback_handle); #endif return true; }
int main() { long loops; int rc; int size; snd_pcm_t *handle; snd_pcm_hw_params_t *params; unsigned int val; int dir; snd_pcm_uframes_t frames; char *buffer; /* 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 */ buffer = (char *) malloc(size); /* We want to loop for 5 seconds */ snd_pcm_hw_params_get_period_time(params, &val, &dir); loops = 5000000 / val; while (loops > 0) { loops--; rc = snd_pcm_readi(handle, buffer, 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); } rc = write(1, buffer, size); if (rc != size) fprintf(stderr, "short write: wrote %d bytes\n", rc); } snd_pcm_drain(handle); snd_pcm_close(handle); free(buffer); return 0; }
static int pcm_open(struct alsa_pcm *alsa, const char *device_name, snd_pcm_stream_t stream, int rate, int buffer_time) { int r, dir; unsigned int p; size_t bytes; snd_pcm_hw_params_t *hw_params; r = snd_pcm_open(&alsa->pcm, device_name, stream, SND_PCM_NONBLOCK); if (r < 0) { alsa_error("open", r); return -1; } snd_pcm_hw_params_alloca(&hw_params); r = snd_pcm_hw_params_any(alsa->pcm, hw_params); if (r < 0) { alsa_error("hw_params_any", r); return -1; } r = snd_pcm_hw_params_set_access(alsa->pcm, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); if (r < 0) { alsa_error("hw_params_set_access", r); return -1; } r = snd_pcm_hw_params_set_format(alsa->pcm, hw_params, SND_PCM_FORMAT_S16); if (r < 0) { alsa_error("hw_params_set_format", r); fprintf(stderr, "16-bit signed format is not available. " "You may need to use a 'plughw' device.\n"); return -1; } r = snd_pcm_hw_params_set_rate(alsa->pcm, hw_params, rate, 0); if (r < 0) { alsa_error("hw_params_set_rate", r); fprintf(stderr, "%dHz sample rate not available. You may need to use " "a 'plughw' device.\n", rate); return -1; } alsa->rate = rate; r = snd_pcm_hw_params_set_channels(alsa->pcm, hw_params, DEVICE_CHANNELS); if (r < 0) { alsa_error("hw_params_set_channels", r); fprintf(stderr, "%d channel audio not available on this device.\n", DEVICE_CHANNELS); return -1; } p = buffer_time * 1000; /* microseconds */ dir = -1; r = snd_pcm_hw_params_set_buffer_time_max(alsa->pcm, hw_params, &p, &dir); if (r < 0) { alsa_error("hw_params_set_buffer_time_max", r); fprintf(stderr, "Buffer of %dms may be too small for this hardware.\n", buffer_time); return -1; } p = 2; /* double buffering */ dir = 1; r = snd_pcm_hw_params_set_periods_min(alsa->pcm, hw_params, &p, &dir); if (r < 0) { alsa_error("hw_params_set_periods_min", r); fprintf(stderr, "Buffer of %dms may be too small for this hardware.\n", buffer_time); return -1; } r = snd_pcm_hw_params(alsa->pcm, hw_params); if (r < 0) { alsa_error("hw_params", r); return -1; } r = snd_pcm_hw_params_get_period_size(hw_params, &alsa->period, &dir); if (r < 0) { alsa_error("get_period_size", r); return -1; } bytes = alsa->period * DEVICE_CHANNELS * sizeof(signed short); alsa->buf = malloc(bytes); if (!alsa->buf) { perror("malloc"); return -1; } /* snd_pcm_readi() returns uninitialised memory on first call, * possibly caused by premature POLLIN. Keep valgrind happy. */ memset(alsa->buf, 0, bytes); return 0; }
static int pcm_open(pcm_handle_t* pcm, const pcm_desc_t* desc) { const snd_pcm_format_t fmt = SND_PCM_FORMAT_S16_LE; snd_pcm_stream_t stm; int err; if (desc->flags & PCM_FLAG_IN) stm = SND_PCM_STREAM_CAPTURE; else stm = SND_PCM_STREAM_PLAYBACK; err = snd_pcm_open (&pcm->pcm, desc->name, stm, SND_PCM_NONBLOCK); if (err) PERROR_GOTO(snd_strerror(err), on_error_0); err = snd_pcm_hw_params_malloc(&pcm->hw_params); if (err) PERROR_GOTO(snd_strerror(err), on_error_1); err = snd_pcm_hw_params_any(pcm->pcm, pcm->hw_params); if (err) PERROR_GOTO(snd_strerror(err), on_error_2); err = snd_pcm_hw_params_set_access (pcm->pcm, pcm->hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); if (err) PERROR_GOTO(snd_strerror(err), on_error_2); err = snd_pcm_hw_params_set_format(pcm->pcm, pcm->hw_params, fmt); if (err) PERROR_GOTO(snd_strerror(err), on_error_2); err = snd_pcm_hw_params_set_rate (pcm->pcm, pcm->hw_params, desc->fsampl, 0); if (err) PERROR_GOTO(snd_strerror(err), on_error_2); pcm->nchan = desc->nchan; pcm->wchan = (size_t)snd_pcm_format_physical_width(fmt) / 8; pcm->scale = pcm->nchan * pcm->wchan; err = snd_pcm_hw_params_set_channels (pcm->pcm, pcm->hw_params, desc->nchan); if (err) PERROR_GOTO(snd_strerror(err), on_error_2); err = snd_pcm_hw_params(pcm->pcm, pcm->hw_params); if (err) PERROR_GOTO(snd_strerror(err), on_error_2); err = snd_pcm_sw_params_malloc(&pcm->sw_params); if (err) PERROR_GOTO(snd_strerror(err), on_error_2); err = snd_pcm_sw_params_current(pcm->pcm, pcm->sw_params); if (err) PERROR_GOTO(snd_strerror(err), on_error_3); #if 1 err = snd_pcm_sw_params_set_avail_min (pcm->pcm, pcm->sw_params, 1024); if (err) PERROR_GOTO(snd_strerror(err), on_error_3); #endif #if 1 err = snd_pcm_sw_params_set_start_threshold (pcm->pcm, pcm->sw_params, 0U); if (err) PERROR_GOTO(snd_strerror(err), on_error_3); #endif err = snd_pcm_sw_params(pcm->pcm, pcm->sw_params); if (err) PERROR_GOTO(snd_strerror(err), on_error_3); err = snd_pcm_prepare(pcm->pcm); if (err) PERROR_GOTO(snd_strerror(err), on_error_3); pcm->rpos = 0; pcm->wpos = 0; pcm->nsampl = (size_t)desc->fsampl * 10; pcm->buf = malloc(pcm->nsampl * pcm->scale); if (pcm->buf == NULL) goto on_error_3; return 0; on_error_3: snd_pcm_sw_params_free(pcm->sw_params); on_error_2: snd_pcm_hw_params_free(pcm->hw_params); on_error_1: snd_pcm_close(pcm->pcm); on_error_0: return -1; }
void SetupSound(void) { snd_pcm_hw_params_t *hwparams; snd_pcm_sw_params_t *swparams; snd_pcm_status_t *status; int pspeed; int pchannels; int format; int buffer_time; int period_time; int err; if(iDisStereo) pchannels=1; else pchannels=2; pspeed=48000; format=SND_PCM_FORMAT_S16_LE; buffer_time=500000; period_time=buffer_time/4; if((err=snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK))<0) { printf("Audio open error: %s\n", snd_strerror(err)); return; } if((err=snd_pcm_nonblock(handle, 0))<0) { printf("Can't set blocking moded: %s\n", snd_strerror(err)); return; } snd_pcm_hw_params_alloca(&hwparams); snd_pcm_sw_params_alloca(&swparams); if((err=snd_pcm_hw_params_any(handle, hwparams))<0) { printf("Broken configuration for this PCM: %s\n", snd_strerror(err)); return; } if((err=snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED))<0) { printf("Access type not available: %s\n", snd_strerror(err)); return; } if((err=snd_pcm_hw_params_set_format(handle, hwparams, format))<0) { printf("Sample format not available: %s\n", snd_strerror(err)); return; } if((err=snd_pcm_hw_params_set_channels(handle, hwparams, pchannels))<0) { printf("Channels count not available: %s\n", snd_strerror(err)); return; } if((err=snd_pcm_hw_params_set_rate_near(handle, hwparams, &pspeed, 0))<0) { printf("Rate not available: %s\n", snd_strerror(err)); return; } if((err=snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, 0))<0) { printf("Buffer time error: %s\n", snd_strerror(err)); return; } if((err=snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, 0))<0) { printf("Period time error: %s\n", snd_strerror(err)); return; } if((err=snd_pcm_hw_params(handle, hwparams))<0) { printf("Unable to install hw params: %s\n", snd_strerror(err)); return; } snd_pcm_status_alloca(&status); if((err=snd_pcm_status(handle, status))<0) { printf("Unable to get status: %s\n", snd_strerror(err)); return; } buffer_size=snd_pcm_status_get_avail(status); }
static int set_params_raw(alsa_param_t *alsa_params) { snd_pcm_hw_params_t *hwparams; snd_pcm_sw_params_t *swparams; // snd_pcm_uframes_t buffer_size; // snd_pcm_uframes_t boundary; // unsigned int period_time = 0; // unsigned int buffer_time = 0; snd_pcm_uframes_t bufsize; int err; unsigned int rate; snd_pcm_uframes_t start_threshold, stop_threshold; snd_pcm_hw_params_alloca(&hwparams); snd_pcm_sw_params_alloca(&swparams); err = snd_pcm_hw_params_any(alsa_params->handle, hwparams); if (err < 0) { adec_print("Broken configuration for this PCM: no configurations available"); return err; } err = snd_pcm_hw_params_set_access(alsa_params->handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { adec_print("Access type not available"); return err; } err = snd_pcm_hw_params_set_format(alsa_params->handle, hwparams, alsa_params->format); if (err < 0) { adec_print("Sample format non available"); return err; } err = snd_pcm_hw_params_set_channels(alsa_params->handle, hwparams, alsa_params->channelcount); if (err < 0) { adec_print("Channels count non available"); return err; } rate = alsa_params->rate; err = snd_pcm_hw_params_set_rate_near(alsa_params->handle, hwparams, &alsa_params->rate, 0); assert(err >= 0); #if 0 err = snd_pcm_hw_params_get_buffer_time_max(hwparams, &buffer_time, 0); assert(err >= 0); if (buffer_time > 500000) { buffer_time = 500000; } period_time = buffer_time / 4; err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, 0); assert(err >= 0); err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, 0); assert(err >= 0); #endif alsa_params->bits_per_sample = snd_pcm_format_physical_width(alsa_params->format); //bits_per_frame = bits_per_sample * hwparams.realchanl; alsa_params->bits_per_frame = alsa_params->bits_per_sample * alsa_params->channelcount; bufsize = PERIOD_NUM*PERIOD_SIZE*4; err = snd_pcm_hw_params_set_buffer_size_near(alsa_params->handle, hwparams,&bufsize); if (err < 0) { adec_print("Unable to set buffer size \n"); return err; } err = snd_pcm_hw_params_set_period_size_near(alsa_params->handle, hwparams, &chunk_size, NULL); if (err < 0) { adec_print("Unable to set period size \n"); return err; } #if 0 err = snd_pcm_hw_params_set_periods_near(alsa_params->handle, hwparams, &fragcount, NULL); if (err < 0) { adec_print("Unable to set periods \n"); return err; } #endif err = snd_pcm_hw_params(alsa_params->handle, hwparams); if (err < 0) { adec_print("Unable to install hw params:"); return err; } err = snd_pcm_hw_params_get_buffer_size(hwparams, &bufsize); if (err < 0) { adec_print("Unable to get buffersize \n"); return err; } adec_print("[%s::%d]--[alsa raw buffer frame size:%d]\n", __FUNCTION__, __LINE__,bufsize); alsa_params->buffer_size = bufsize * alsa_params->bits_per_frame / 8; #if 1 err = snd_pcm_sw_params_current(alsa_params->handle, swparams); if (err < 0) { adec_print("??Unable to get sw-parameters\n"); return err; } //err = snd_pcm_sw_params_get_boundary(swparams, &boundary); //if (err < 0){ // adec_print("Unable to get boundary\n"); // return err; //} //err = snd_pcm_sw_params_set_start_threshold(handle, swparams, bufsize); //if (err < 0) { // adec_print("Unable to set start threshold \n"); // return err; //} //err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, buffer_size); //if (err < 0) { // adec_print("Unable to set stop threshold \n"); // return err; //} // err = snd_pcm_sw_params_set_silence_size(handle, swparams, buffer_size); // if (err < 0) { // adec_print("Unable to set silence size \n"); // return err; // } err = snd_pcm_sw_params(alsa_params->handle, swparams); if (err < 0) { adec_print("Unable to get sw-parameters\n"); return err; } //snd_pcm_sw_params_free(swparams); #endif //chunk_bytes = chunk_size * bits_per_frame / 8; return 0; }
bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const { // Set nearest to closest settings that do work. // See if what is in settings will work (return value). int err = 0; snd_pcm_t* handle; snd_pcm_hw_params_t *params; QString dev = device; 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 = device; #else int idx = 0; char *name; QString shortName = device.mid(device.indexOf(QLatin1String("="),0)+1); while(snd_card_get_name(idx,&name) == 0) { if(shortName.compare(QLatin1String(name)) == 0) break; idx++; } dev = QString(QLatin1String("hw:%1,0")).arg(idx); #endif } if(mode == QAudio::AudioOutput) { err=snd_pcm_open( &handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_PLAYBACK,0); } else { err=snd_pcm_open( &handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_CAPTURE,0); } if(err < 0) { handle = 0; return false; } bool testChannel = false; bool testCodec = false; bool testFreq = false; bool testType = false; bool testSize = false; int dir = 0; snd_pcm_nonblock( handle, 0 ); snd_pcm_hw_params_alloca( ¶ms ); snd_pcm_hw_params_any( handle, params ); // set the values! snd_pcm_hw_params_set_channels(handle,params,format.channels()); snd_pcm_hw_params_set_rate(handle,params,format.frequency(),dir); switch(format.sampleSize()) { case 8: if(format.sampleType() == QAudioFormat::SignedInt) snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S8); else if(format.sampleType() == QAudioFormat::UnSignedInt) snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U8); break; case 16: if(format.sampleType() == QAudioFormat::SignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_BE); } else if(format.sampleType() == QAudioFormat::UnSignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_BE); } break; case 32: if(format.sampleType() == QAudioFormat::SignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_BE); } else if(format.sampleType() == QAudioFormat::UnSignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_BE); } } // For now, just accept only audio/pcm codec if(!format.codec().startsWith(QLatin1String("audio/pcm"))) { err=-1; } else testCodec = true; if(err>=0 && format.channels() != -1) { err = snd_pcm_hw_params_test_channels(handle,params,format.channels()); if(err>=0) err = snd_pcm_hw_params_set_channels(handle,params,format.channels()); if(err>=0) testChannel = true; } if(err>=0 && format.frequency() != -1) { err = snd_pcm_hw_params_test_rate(handle,params,format.frequency(),0); if(err>=0) err = snd_pcm_hw_params_set_rate(handle,params,format.frequency(),dir); if(err>=0) testFreq = true; } if((err>=0 && format.sampleSize() != -1) && (format.sampleType() != QAudioFormat::Unknown)) { switch(format.sampleSize()) { case 8: if(format.sampleType() == QAudioFormat::SignedInt) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S8); else if(format.sampleType() == QAudioFormat::UnSignedInt) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U8); break; case 16: if(format.sampleType() == QAudioFormat::SignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_BE); } else if(format.sampleType() == QAudioFormat::UnSignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_BE); } break; case 32: if(format.sampleType() == QAudioFormat::SignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_BE); } else if(format.sampleType() == QAudioFormat::UnSignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_BE); } } if(err>=0) { testSize = true; testType = true; } } if(err>=0) err = snd_pcm_hw_params(handle, params); if(err == 0) { // settings work // close() if(handle) snd_pcm_close(handle); return true; } if(handle) snd_pcm_close(handle); return false; }
/** * @brief Setup the ALSA handle to the audio device */ void AlsaPlayback::setupHandle() { if(alsa_handle) { snd_pcm_close(alsa_handle); alsa_handle = NULL; } if(snd_pcm_open(&alsa_handle, "default", SND_PCM_STREAM_PLAYBACK, 0) < 0) { TRACE("Unable to open playback device!!\n"); alsa_handle = NULL; } else { int rc = -1; snd_pcm_hw_params_t *params = NULL; /* Allocate a hardware parameters object. */ snd_pcm_hw_params_malloc(¶ms); if(NULL != params) { int dir = 0; /* Fill it in with default values. */ snd_pcm_hw_params_any(alsa_handle, params); /* Set the desired hardware parameters. */ /* Interleaved mode */ snd_pcm_hw_params_set_access(alsa_handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); /* Signed 16-bit little-endian format */ snd_pcm_hw_params_set_format(alsa_handle, params, SND_PCM_FORMAT_S16_LE); /* One channel (mono) */ snd_pcm_hw_params_set_channels(alsa_handle, params, 1); /* set sampling rate */ snd_pcm_hw_params_set_rate_near(alsa_handle, params, &AlsaPlayback::_sample_rate, &dir); /* Set period size to 128 frames (samples) */ frames = AlsaPlayback::FRAME_PERIOD; snd_pcm_hw_params_set_period_size_near(alsa_handle, params, &frames, &dir); snd_pcm_uframes_t buf_size = MINIMUM_SAMPLE_SET_SIZE; snd_pcm_hw_params_set_buffer_size_near(alsa_handle, params, &buf_size); /* Write the parameters to the driver */ rc = snd_pcm_hw_params(alsa_handle, params); if(rc >= 0) { TRACE("AlsaPlayback init completed successfully..\n"); } else { snd_pcm_close(alsa_handle); alsa_handle = NULL; TRACE("AlsaPlayback init failed\n"); } snd_pcm_hw_params_free(params); params = NULL; } else { TRACE("playAudio - snd_pcm_hw_params_alloc() failed\n"); } } }
void create_recorder(int samp_rate,char* dev_name,int nchan,void **capture_handle_f) { int err; snd_pcm_t *capture_handle; snd_pcm_hw_params_t *hw_params; printf("From C: *capture_handle_f=%p\n",*capture_handle_f); if ((err = snd_pcm_open ((snd_pcm_t**)capture_handle_f, dev_name, SND_PCM_STREAM_CAPTURE, 0)) < 0) { fprintf (stderr, "cannot open audio device %s (%s)\n", dev_name, snd_strerror (err)); fprintf(stderr, "Hint: Use \"arecord -l\" to list recording devices.\n"); exit (1); } capture_handle = (snd_pcm_t*)(*capture_handle_f); printf("made handle %p (&=%p) to %s at %d\n",capture_handle,&capture_handle,dev_name,samp_rate); if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) { fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_any (capture_handle, hw_params)) < 0) { fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_access (capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { fprintf (stderr, "cannot set access type (%s)\n", snd_strerror(err)); exit (1); } if ((err = snd_pcm_hw_params_set_format (capture_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) { fprintf (stderr, "cannot set sample format (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_rate_resample(capture_handle,hw_params, 0)) < 0) { fprintf(stderr, "failed attempting to prevent ALSA resampling. (%s)", snd_strerror(err)); exit (1); } int dir = 0; unsigned int val = samp_rate; if ((err = snd_pcm_hw_params_set_rate_near (capture_handle, hw_params, &val, &dir)) < 0) { fprintf (stderr, "cannot set sample rate (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_channels (capture_handle, hw_params, nchan)) < 0) { fprintf (stderr, "cannot set channel count (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params (capture_handle, hw_params)) < 0) { fprintf (stderr, "cannot set parameters (%s)\n", snd_strerror (err)); exit (1); } snd_pcm_hw_params_free (hw_params); if ((err = snd_pcm_prepare (capture_handle)) < 0) { fprintf (stderr, "cannot prepare audio interface for use (%s)\n", snd_strerror (err)); exit (1); } /* int nbuf = 8000; short *buf = (short*)malloc(sizeof(short)*nbuf); int i; for (i=0; i<2; ++i) { if ((err = snd_pcm_readi(capture_handle, buf, nbuf)) != nbuf) { fprintf (stderr, "read from audio interface failed (%s)\n", snd_strerror(err)); exit (1); } else { printf("read from C using %p into %p.\n",capture_handle,buf); } } */ }
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 argc, char *argv[]) { ros::init(argc, argv, "cmd_control"); ros::NodeHandle n; ros::Publisher motor_pub = n.advertise<std_msgs::Char>("motor_chatter", 1000); std::string port; ros::param::param<std::string>("~port", port, "/dev/ttyACM0"); int baud; ros::param::param<int>("~baud", baud, 57600); int byte_per_sample = bits_per_sample >> 3; long loops; int rc; int size; snd_pcm_t *handle; snd_pcm_hw_params_t *params; unsigned int val; int dir; snd_pcm_uframes_t frames; char *buffer; char *speechbuf; /* 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, channels); /* 44100 bits/second sampling rate (CD quality) */ //val = 44100; val = sample_rate; snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); /* Set period size to 32 frames. */ frames = frames_per_period; 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 * channels * byte_per_sample; /* 2 bytes/sample, 1 channels */ speechbuf = (char *) malloc(size); //printf("buffer size %d\n", size); /* We want to loop for 5 seconds */ snd_pcm_hw_params_get_period_time(params, &val, &dir); int client_sockfd; struct sockaddr_in remote_addr; //服务器端网络地址结构体 memset(&remote_addr,0,sizeof(remote_addr)); //数据初始化--清零 remote_addr.sin_family=AF_INET; //设置为IP通信 remote_addr.sin_addr.s_addr=inet_addr("10.0.1.0");//服务器IP地址 remote_addr.sin_port=htons(port); //服务器端口号 /*创建客户端套接字--IPv4协议,面向连接通信,TCP协议*/ if((client_sockfd=socket(PF_INET,SOCK_STREAM,0))<0) { perror("socket failed\n"); return 1; } /*将套接字绑定到服务器的网络地址上*/ if(connect(client_sockfd,(struct sockaddr *)&remote_addr,sizeof(struct sockaddr))<0) { perror("connect failed\n"); return 1; } printf("connected to server\n"); int len = 10 * FRAME_LEN; //printf("pcm size is %d", pcm_size); int totallen = 0; totallen = 0; int sendlen =0; int pcm_count = 0; int num = 0; pthread_t thread_recv; int err; void *tret; if((err = pthread_create(&thread_recv, NULL, &recv_cmd_func, &client_sockfd)) != 0) { printf("thread recv erro : %s \n", strerror(err)); return -1; } sleep(1); //printf("thread creat is\n" ); //fflush(stdout); while(1) { rc = snd_pcm_readi(handle, speechbuf, 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); break; } sendlen = send(client_sockfd, speechbuf, len, 0); if(sendlen < 0) printf("send failed \n"); } if((err = pthread_join(thread_recv, &tret)) != 0) { printf("can not join thread_recv %s!\n", strerror(err)); exit(-1); } getchar(); close(client_sockfd); snd_pcm_drain(handle); snd_pcm_close(handle); free(speechbuf); return 0; }
/** * Create and initialize Alsa audio output device with given parameters. * * @param Parameters - optional parameters * @throws AudioOutputException if output device cannot be opened */ AudioOutputDeviceAlsa::AudioOutputDeviceAlsa(std::map<String,DeviceCreationParameter*> Parameters) : AudioOutputDevice(Parameters), Thread(true, true, 1, 0) { pcm_handle = NULL; stream = SND_PCM_STREAM_PLAYBACK; this->uiAlsaChannels = ((DeviceCreationParameterInt*)Parameters["CHANNELS"])->ValueAsInt(); this->uiSamplerate = ((DeviceCreationParameterInt*)Parameters["SAMPLERATE"])->ValueAsInt(); this->FragmentSize = ((DeviceCreationParameterInt*)Parameters["FRAGMENTSIZE"])->ValueAsInt(); uint Fragments = ((DeviceCreationParameterInt*)Parameters["FRAGMENTS"])->ValueAsInt(); String Card = ((DeviceCreationParameterString*)Parameters["CARD"])->ValueAsString(); dmsg(2,("Checking if hw parameters supported...\n")); if (HardwareParametersSupported(Card, uiAlsaChannels, uiSamplerate, Fragments, FragmentSize)) { pcm_name = "hw:" + Card; } else { fprintf(stderr, "Warning: your soundcard doesn't support chosen hardware parameters; "); fprintf(stderr, "trying to compensate support lack with plughw..."); fflush(stdout); pcm_name = "plughw:" + Card; } dmsg(2,("HW check completed.\n")); int err; snd_pcm_hw_params_alloca(&hwparams); // Allocate the snd_pcm_hw_params_t structure on the stack. /* Open PCM. The last parameter of this function is the mode. */ /* If this is set to 0, the standard mode is used. Possible */ /* other values are SND_PCM_NONBLOCK and SND_PCM_ASYNC. */ /* If SND_PCM_NONBLOCK is used, read / write access to the */ /* PCM device will return immediately. If SND_PCM_ASYNC is */ /* specified, SIGIO will be emitted whenever a period has */ /* been completely processed by the soundcard. */ if ((err = snd_pcm_open(&pcm_handle, pcm_name.c_str(), stream, 0)) < 0) { throw AudioOutputException(String("Error opening PCM device ") + pcm_name + ": " + snd_strerror(err)); } if ((err = snd_pcm_hw_params_any(pcm_handle, hwparams)) < 0) { throw AudioOutputException(String("Error, cannot initialize hardware parameter structure: ") + snd_strerror(err)); } /* Set access type. This can be either */ /* SND_PCM_ACCESS_RW_INTERLEAVED or */ /* SND_PCM_ACCESS_RW_NONINTERLEAVED. */ if ((err = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { throw AudioOutputException(String("Error snd_pcm_hw_params_set_access: ") + snd_strerror(err)); } /* Set sample format */ #if WORDS_BIGENDIAN if ((err = snd_pcm_hw_params_set_format(pcm_handle, hwparams, SND_PCM_FORMAT_S16_BE)) < 0) #else // little endian if ((err = snd_pcm_hw_params_set_format(pcm_handle, hwparams, SND_PCM_FORMAT_S16_LE)) < 0) #endif { throw AudioOutputException(String("Error setting sample format: ") + snd_strerror(err)); } int dir = 0; /* Set sample rate. If the exact rate is not supported */ /* by the hardware, use nearest possible rate. */ #if ALSA_MAJOR > 0 if((err = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &uiSamplerate, &dir)) < 0) #else if((err = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, uiSamplerate, &dir)) < 0) #endif { throw AudioOutputException(String("Error setting sample rate: ") + snd_strerror(err)); } if ((err = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, uiAlsaChannels)) < 0) { throw AudioOutputException(String("Error setting number of channels: ") + snd_strerror(err)); } /* Set number of periods. Periods used to be called fragments. */ if ((err = snd_pcm_hw_params_set_periods(pcm_handle, hwparams, Fragments, dir)) < 0) { throw AudioOutputException(String("Error setting number of ") + ToString(Fragments) + " periods: " + snd_strerror(err)); } /* Set buffer size (in frames). The resulting latency is given by */ /* latency = periodsize * periods / (rate * bytes_per_frame) */ if ((err = snd_pcm_hw_params_set_buffer_size(pcm_handle, hwparams, (FragmentSize * Fragments))) < 0) { throw AudioOutputException(String("Error setting buffersize: ") + snd_strerror(err)); } /* Apply HW parameter settings to */ /* PCM device and prepare device */ if ((err = snd_pcm_hw_params(pcm_handle, hwparams)) < 0) { throw AudioOutputException(String("Error setting HW params: ") + snd_strerror(err)); } if (snd_pcm_sw_params_malloc(&swparams) != 0) { throw AudioOutputException(String("Error in snd_pcm_sw_params_malloc: ") + snd_strerror(err)); } if (snd_pcm_sw_params_current(pcm_handle, swparams) != 0) { throw AudioOutputException(String("Error in snd_pcm_sw_params_current: ") + snd_strerror(err)); } if (snd_pcm_sw_params_set_stop_threshold(pcm_handle, swparams, 0xffffffff) != 0) { throw AudioOutputException(String("Error in snd_pcm_sw_params_set_stop_threshold: ") + snd_strerror(err)); } if (snd_pcm_sw_params(pcm_handle, swparams) != 0) { throw AudioOutputException(String("Error in snd_pcm_sw_params: ") + snd_strerror(err)); } if ((err = snd_pcm_prepare(pcm_handle)) < 0) { throw AudioOutputException(String("Error snd_pcm_prepare: ") + snd_strerror(err)); } // allocate Alsa output buffer pAlsaOutputBuffer = new int16_t[uiAlsaChannels * FragmentSize]; // create audio channels for this audio device to which the sampler engines can write to for (int i = 0; i < uiAlsaChannels; i++) this->Channels.push_back(new AudioChannel(i, FragmentSize)); if (((DeviceCreationParameterBool*)Parameters["ACTIVE"])->ValueAsBool()) { Play(); } }
int AudioAlsa::setHWParams( const ch_cnt_t _channels, snd_pcm_access_t _access ) { int err, dir; // choose all parameters if( ( err = snd_pcm_hw_params_any( m_handle, m_hwParams ) ) < 0 ) { printf( "Broken configuration for playback: no configurations " "available: %s\n", snd_strerror( err ) ); return err; } // set the interleaved read/write format if( ( err = snd_pcm_hw_params_set_access( m_handle, m_hwParams, _access ) ) < 0 ) { printf( "Access type not available for playback: %s\n", snd_strerror( err ) ); return err; } // set the sample format if( ( snd_pcm_hw_params_set_format( m_handle, m_hwParams, SND_PCM_FORMAT_S16_LE ) ) < 0 ) { if( ( snd_pcm_hw_params_set_format( m_handle, m_hwParams, SND_PCM_FORMAT_S16_BE ) ) < 0 ) { printf( "Neither little- nor big-endian available for " "playback: %s\n", snd_strerror( err ) ); return err; } m_convertEndian = isLittleEndian(); } else { m_convertEndian = !isLittleEndian(); } // set the count of channels if( ( err = snd_pcm_hw_params_set_channels( m_handle, m_hwParams, _channels ) ) < 0 ) { printf( "Channel count (%i) not available for playbacks: %s\n" "(Does your soundcard not support surround?)\n", _channels, snd_strerror( err ) ); return err; } // set the sample rate if( ( err = snd_pcm_hw_params_set_rate( m_handle, m_hwParams, sampleRate(), 0 ) ) < 0 ) { if( ( err = snd_pcm_hw_params_set_rate( m_handle, m_hwParams, mixer()->baseSampleRate(), 0 ) ) < 0 ) { printf( "Could not set sample rate: %s\n", snd_strerror( err ) ); return err; } } m_periodSize = mixer()->framesPerPeriod(); m_bufferSize = m_periodSize * 8; dir = 0; err = snd_pcm_hw_params_set_period_size_near( m_handle, m_hwParams, &m_periodSize, &dir ); if( err < 0 ) { printf( "Unable to set period size %lu for playback: %s\n", m_periodSize, snd_strerror( err ) ); return err; } dir = 0; err = snd_pcm_hw_params_get_period_size( m_hwParams, &m_periodSize, &dir ); if( err < 0 ) { printf( "Unable to get period size for playback: %s\n", snd_strerror( err ) ); } dir = 0; err = snd_pcm_hw_params_set_buffer_size_near( m_handle, m_hwParams, &m_bufferSize ); if( err < 0 ) { printf( "Unable to set buffer size %lu for playback: %s\n", m_bufferSize, snd_strerror( err ) ); return ( err ); } err = snd_pcm_hw_params_get_buffer_size( m_hwParams, &m_bufferSize ); if( 2 * m_periodSize > m_bufferSize ) { printf( "buffer to small, could not use\n" ); return ( err ); } // write the parameters to device err = snd_pcm_hw_params( m_handle, m_hwParams ); if( err < 0 ) { printf( "Unable to set hw params for playback: %s\n", snd_strerror( err ) ); return ( err ); } return ( 0 ); // all ok }
void pcm_init() { int n, m, err; snd_pcm_hw_params_t *hw_params; if (!sound) { pcm.hz = 11025; pcm.len = 4096; pcm.buf = malloc(pcm.len); pcm.pos = 0; playback_handle = NULL; return; } if (!dsp_device) dsp_device = strdup(DSP_DEVICE); if ((err = snd_pcm_open (&playback_handle, dsp_device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { fprintf (stderr, "cannot open audio device %s (%s)\n", dsp_device, snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) { fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_any (playback_handle, hw_params)) < 0) { fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_access (playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { fprintf (stderr, "cannot set access type (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_format (playback_handle, hw_params, SND_PCM_FORMAT_U8)) < 0) { fprintf (stderr, "cannot set sample format (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_rate_near (playback_handle, hw_params, samplerate, 0)) < 0) { fprintf (stderr, "cannot set sample rate (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_channels (playback_handle, hw_params, stereo ? 2 : 1)) < 0) { fprintf (stderr, "cannot set channel count (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params (playback_handle, hw_params)) < 0) { fprintf (stderr, "cannot set parameters (%s)\n", snd_strerror (err)); exit (1); } snd_pcm_hw_params_free (hw_params); if ((err = snd_pcm_prepare (playback_handle)) < 0) { fprintf (stderr, "cannot prepare audio interface for use (%s)\n", snd_strerror (err)); exit (1); } pcm.stereo = stereo; pcm.hz = samplerate; pcm.len = 4096; pcm.buf = malloc(pcm.len); }
static int alsa_set_params(snd_pcm_t *pcm_handle, int rw, int bits, int stereo, int rate) { snd_pcm_hw_params_t *hwparams=NULL; snd_pcm_sw_params_t *swparams=NULL; int dir; uint exact_uvalue; unsigned long exact_ulvalue; int channels; int periods=ALSA_PERIODS; int periodsize=ALSA_PERIOD_SIZE; int err; int format; /* Allocate the snd_pcm_hw_params_t structure on the stack. */ snd_pcm_hw_params_alloca(&hwparams); /* Init hwparams with full configuration space */ if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) { ms_warning("alsa_set_params: Cannot configure this PCM device.\n"); return -1; } if (snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) { ms_warning("alsa_set_params: Error setting access.\n"); return -1; } /* Set sample format */ format=SND_PCM_FORMAT_S16; if (snd_pcm_hw_params_set_format(pcm_handle, hwparams, format) < 0) { ms_warning("alsa_set_params: Error setting format.\n"); return -1; } /* Set number of channels */ if (stereo) channels=2; else channels=1; if (snd_pcm_hw_params_set_channels(pcm_handle, hwparams, channels) < 0) { ms_warning("alsa_set_params: Error setting channels.\n"); return -1; } /* Set sample rate. If the exact rate is not supported */ /* by the hardware, use nearest possible rate. */ exact_uvalue=rate; dir=0; if ((err=snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &exact_uvalue, &dir))<0){ ms_warning("alsa_set_params: Error setting rate to %i:%s",rate,snd_strerror(err)); return -1; } if (dir != 0) { ms_warning("alsa_set_params: The rate %d Hz is not supported by your hardware.\n " "==> Using %d Hz instead.\n", rate, exact_uvalue); } /* choose greater period size when rate is high */ periodsize=periodsize*(rate/8000); /* Set buffer size (in frames). The resulting latency is given by */ /* latency = periodsize * periods / (rate * bytes_per_frame) */ /* set period size */ exact_ulvalue=periodsize; dir=0; if (snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams, &exact_ulvalue, &dir) < 0) { ms_warning("alsa_set_params: Error setting period size.\n"); return -1; } if (dir != 0) { ms_warning("alsa_set_params: The period size %d is not supported by your hardware.\n " "==> Using %d instead.\n", periodsize, (int)exact_ulvalue); } periodsize=exact_ulvalue; /* Set number of periods. Periods used to be called fragments. */ exact_uvalue=periods; dir=0; if (snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &exact_uvalue, &dir) < 0) { ms_warning("alsa_set_params: Error setting periods.\n"); return -1; } if (dir != 0) { ms_warning("alsa_set_params: The number of periods %d is not supported by your hardware.\n " "==> Using %d instead.\n", periods, exact_uvalue); } /* Apply HW parameter settings to */ /* PCM device and prepare device */ if ((err=snd_pcm_hw_params(pcm_handle, hwparams)) < 0) { ms_warning("alsa_set_params: Error setting HW params:%s",snd_strerror(err)); return -1; } /*prepare sw params */ if (rw){ snd_pcm_sw_params_alloca(&swparams); snd_pcm_sw_params_current(pcm_handle, swparams); if ((err=snd_pcm_sw_params_set_start_threshold(pcm_handle, swparams,periodsize*4 ))<0){ ms_warning("alsa_set_params: Error setting start threshold:%s",snd_strerror(err)); } if ((err=snd_pcm_sw_params_set_stop_threshold(pcm_handle, swparams,periodsize*periods ))<0){ ms_warning("alsa_set_params: Error setting start threshold:%s",snd_strerror(err)); } if ((err=snd_pcm_sw_params(pcm_handle, swparams))<0){ ms_warning("alsa_set_params: Error setting SW params:%s",snd_strerror(err)); return -1; } } return 0; }
int init_alsa(unsigned int channels, unsigned sample_rate, snd_pcm_format_t format) { int ret; snd_pcm_hw_params_t *hw_params; playback_handle = NULL; ret = snd_pcm_open(&playback_handle, "default", SND_PCM_STREAM_PLAYBACK, 0); if (ret < 0) { fprintf(stderr, "can NOT open soundcard\n"); goto fail; } ret = snd_pcm_hw_params_malloc(&hw_params); if (ret < 0) { fprintf(stderr, "can NOT allocate hardware paramter structure (%s)\n", snd_strerror(ret)); goto fail; } ret = snd_pcm_hw_params_any(playback_handle, hw_params); if (ret < 0) { fprintf(stderr, "can NOT initialize hardware paramter structure (%s)\n", snd_strerror(ret)); goto fail; } ret = snd_pcm_hw_params_set_access(playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); if (ret < 0) { fprintf(stderr, "can NOT set access type (%s)\n", snd_strerror(ret)); goto fail; } ret = snd_pcm_hw_params_set_format(playback_handle, hw_params, format); if (ret < 0) { fprintf(stderr, "can NOT set sample format (%s)\n", snd_strerror(ret)); goto fail; } ret = snd_pcm_hw_params_set_rate_near(playback_handle, hw_params, &sample_rate, 0); if (ret < 0) { fprintf(stderr, "can NOT set sample rate (%s)\n", snd_strerror(ret)); goto fail; } ret = snd_pcm_hw_params_set_channels(playback_handle, hw_params, channels); if (ret < 0) { fprintf(stderr, "can NOT set channels (%s)\n", snd_strerror(ret)); goto fail; } snd_pcm_hw_params_get_buffer_size_max(hw_params, &buffer_size); buffer_size = buffer_size < ALSA_BUFFER_SIZE_MAX ? buffer_size : ALSA_BUFFER_SIZE_MAX; ret = snd_pcm_hw_params_set_buffer_size_near(playback_handle, hw_params, &buffer_size); if (ret < 0) { fprintf(stderr, "can NOT set alsa buffer size (%s)\n", snd_strerror(ret)); goto fail; } snd_pcm_hw_params_get_period_size_min(hw_params, &period_size, NULL); if (!period_size) period_size = buffer_size / 4; ret = snd_pcm_hw_params_set_period_size_near(playback_handle, hw_params, &period_size, NULL); if (ret < 0) { fprintf(stderr, "can NOT set alsa period size (%s)\n", snd_strerror(ret)); goto fail; } ret = snd_pcm_hw_params(playback_handle, hw_params); if (ret < 0) { fprintf(stderr, "can NOT set parameters (%s)\n", snd_strerror(ret)); goto fail; } snd_pcm_hw_params_free(hw_params); audio_channels = channels; audio_sample_rate = sample_rate; audio_format = format; ret = 0; return ret; fail: if (playback_handle) { snd_pcm_close(playback_handle); playback_handle = NULL; } return ret; }
static void *alsa_init(const char *device, unsigned rate, unsigned latency) { alsa_t *alsa = (alsa_t*)calloc(1, sizeof(alsa_t)); if (!alsa) return NULL; snd_pcm_hw_params_t *params = NULL; snd_pcm_sw_params_t *sw_params = NULL; unsigned latency_usec = latency * 1000; unsigned channels = 2; unsigned periods = 4; snd_pcm_format_t format; const char *alsa_dev = "default"; if (device) alsa_dev = device; snd_pcm_uframes_t buffer_size; TRY_ALSA(snd_pcm_open(&alsa->pcm, alsa_dev, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)); TRY_ALSA(snd_pcm_hw_params_malloc(¶ms)); alsa->has_float = find_float_format(alsa->pcm, params); format = alsa->has_float ? SND_PCM_FORMAT_FLOAT : SND_PCM_FORMAT_S16; TRY_ALSA(snd_pcm_hw_params_any(alsa->pcm, params)); TRY_ALSA(snd_pcm_hw_params_set_access(alsa->pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED)); TRY_ALSA(snd_pcm_hw_params_set_format(alsa->pcm, params, format)); TRY_ALSA(snd_pcm_hw_params_set_channels(alsa->pcm, params, channels)); TRY_ALSA(snd_pcm_hw_params_set_rate(alsa->pcm, params, rate, 0)); TRY_ALSA(snd_pcm_hw_params_set_buffer_time_near(alsa->pcm, params, &latency_usec, NULL)); TRY_ALSA(snd_pcm_hw_params_set_periods_near(alsa->pcm, params, &periods, NULL)); TRY_ALSA(snd_pcm_hw_params(alsa->pcm, params)); snd_pcm_hw_params_get_period_size(params, &buffer_size, NULL); RARCH_LOG("ALSA: Period size: %d frames\n", (int)buffer_size); snd_pcm_hw_params_get_buffer_size(params, &buffer_size); RARCH_LOG("ALSA: Buffer size: %d frames\n", (int)buffer_size); alsa->buffer_size = snd_pcm_frames_to_bytes(alsa->pcm, buffer_size); alsa->can_pause = snd_pcm_hw_params_can_pause(params); RARCH_LOG("ALSA: Can pause: %s.\n", alsa->can_pause ? "yes" : "no"); TRY_ALSA(snd_pcm_sw_params_malloc(&sw_params)); TRY_ALSA(snd_pcm_sw_params_current(alsa->pcm, sw_params)); TRY_ALSA(snd_pcm_sw_params_set_start_threshold(alsa->pcm, sw_params, buffer_size / 2)); TRY_ALSA(snd_pcm_sw_params(alsa->pcm, sw_params)); snd_pcm_hw_params_free(params); snd_pcm_sw_params_free(sw_params); return alsa; error: RARCH_ERR("ALSA: Failed to initialize...\n"); if (params) snd_pcm_hw_params_free(params); if (sw_params) snd_pcm_sw_params_free(sw_params); if (alsa) { if (alsa->pcm) snd_pcm_close(alsa->pcm); free(alsa); } return NULL; }
bool AlsaSound::AlsaInit() { unsigned int sample_rate = m_mixer->GetSampleRate(); int err; int dir; snd_pcm_sw_params_t *swparams; snd_pcm_hw_params_t *hwparams; snd_pcm_uframes_t buffer_size,buffer_size_max; unsigned int periods; err = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0); if (err < 0) { ERROR_LOG(AUDIO, "Audio open error: %s\n", snd_strerror(err)); return false; } snd_pcm_hw_params_alloca(&hwparams); err = snd_pcm_hw_params_any(handle, hwparams); if (err < 0) { ERROR_LOG(AUDIO, "Broken configuration for this PCM: %s\n", snd_strerror(err)); return false; } err = snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { ERROR_LOG(AUDIO, "Access type not available: %s\n", snd_strerror(err)); return false; } err = snd_pcm_hw_params_set_format(handle, hwparams, SND_PCM_FORMAT_S16_LE); if (err < 0) { ERROR_LOG(AUDIO, "Sample format not available: %s\n", snd_strerror(err)); return false; } dir = 0; err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &sample_rate, &dir); if (err < 0) { ERROR_LOG(AUDIO, "Rate not available: %s\n", snd_strerror(err)); return false; } err = snd_pcm_hw_params_set_channels(handle, hwparams, 2); if (err < 0) { ERROR_LOG(AUDIO, "Channels count not available: %s\n", snd_strerror(err)); return false; } periods = BUFFER_SIZE_MAX / FRAME_COUNT_MIN; err = snd_pcm_hw_params_set_periods_max(handle, hwparams, &periods, &dir); if (err < 0) { ERROR_LOG(AUDIO, "Cannot set Minimum periods: %s\n", snd_strerror(err)); return false; } buffer_size_max = BUFFER_SIZE_MAX; err = snd_pcm_hw_params_set_buffer_size_max(handle, hwparams, &buffer_size_max); if (err < 0) { ERROR_LOG(AUDIO, "Cannot set minimum buffer size: %s\n", snd_strerror(err)); return false; } err = snd_pcm_hw_params(handle, hwparams); if (err < 0) { ERROR_LOG(AUDIO, "Unable to install hw params: %s\n", snd_strerror(err)); return false; } err = snd_pcm_hw_params_get_buffer_size(hwparams, &buffer_size); if (err < 0) { ERROR_LOG(AUDIO, "Cannot get buffer size: %s\n", snd_strerror(err)); return false; } err = snd_pcm_hw_params_get_periods_max(hwparams, &periods, &dir); if (err < 0) { ERROR_LOG(AUDIO, "Cannot get periods: %s\n", snd_strerror(err)); return false; } //periods is the number of fragments alsa can wait for during one //buffer_size frames_to_deliver = buffer_size / periods; //limit the minimum size. pulseaudio advertises a minimum of 32 samples. if (frames_to_deliver < FRAME_COUNT_MIN) frames_to_deliver = FRAME_COUNT_MIN; //it is probably a bad idea to try to send more than one buffer of data if ((unsigned int)frames_to_deliver > buffer_size) frames_to_deliver = buffer_size; NOTICE_LOG(AUDIO, "ALSA gave us a %ld sample \"hardware\" buffer with %d periods. Will send %d samples per fragments.\n", buffer_size, periods, frames_to_deliver); snd_pcm_sw_params_alloca(&swparams); err = snd_pcm_sw_params_current(handle, swparams); if (err < 0) { ERROR_LOG(AUDIO, "cannot init sw params: %s\n", snd_strerror(err)); return false; } err = snd_pcm_sw_params_set_start_threshold(handle, swparams, 0U); if (err < 0) { ERROR_LOG(AUDIO, "cannot set start thresh: %s\n", snd_strerror(err)); return false; } err = snd_pcm_sw_params(handle, swparams); if (err < 0) { ERROR_LOG(AUDIO, "cannot set sw params: %s\n", snd_strerror(err)); return false; } err = snd_pcm_prepare(handle); if (err < 0) { ERROR_LOG(AUDIO, "Unable to prepare: %s\n", snd_strerror(err)); return false; } NOTICE_LOG(AUDIO, "ALSA successfully initialized.\n"); return true; }
av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode, unsigned int *sample_rate, int channels, enum CodecID *codec_id) { AlsaData *s = ctx->priv_data; const char *audio_device; int res, flags = 0; snd_pcm_format_t format; snd_pcm_t *h; snd_pcm_hw_params_t *hw_params; snd_pcm_uframes_t buffer_size, period_size; int64_t layout = ctx->streams[0]->codec->channel_layout; if (ctx->filename[0] == 0) audio_device = "default"; else audio_device = ctx->filename; if (*codec_id == CODEC_ID_NONE) *codec_id = DEFAULT_CODEC_ID; format = codec_id_to_pcm_format(*codec_id); if (format == SND_PCM_FORMAT_UNKNOWN) { av_log(ctx, AV_LOG_ERROR, "sample format 0x%04x is not supported\n", *codec_id); return AVERROR(ENOSYS); } s->frame_size = av_get_bits_per_sample(*codec_id) / 8 * channels; if (ctx->flags & AVFMT_FLAG_NONBLOCK) { flags = SND_PCM_NONBLOCK; } res = snd_pcm_open(&h, audio_device, mode, flags); if (res < 0) { av_log(ctx, AV_LOG_ERROR, "cannot open audio device %s (%s)\n", audio_device, snd_strerror(res)); return AVERROR(EIO); } res = snd_pcm_hw_params_malloc(&hw_params); if (res < 0) { av_log(ctx, AV_LOG_ERROR, "cannot allocate hardware parameter structure (%s)\n", snd_strerror(res)); goto fail1; } res = snd_pcm_hw_params_any(h, hw_params); if (res < 0) { av_log(ctx, AV_LOG_ERROR, "cannot initialize hardware parameter structure (%s)\n", snd_strerror(res)); goto fail; } res = snd_pcm_hw_params_set_access(h, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); if (res < 0) { av_log(ctx, AV_LOG_ERROR, "cannot set access type (%s)\n", snd_strerror(res)); goto fail; } res = snd_pcm_hw_params_set_format(h, hw_params, format); if (res < 0) { av_log(ctx, AV_LOG_ERROR, "cannot set sample format 0x%04x %d (%s)\n", *codec_id, format, snd_strerror(res)); goto fail; } res = snd_pcm_hw_params_set_rate_near(h, hw_params, sample_rate, 0); if (res < 0) { av_log(ctx, AV_LOG_ERROR, "cannot set sample rate (%s)\n", snd_strerror(res)); goto fail; } res = snd_pcm_hw_params_set_channels(h, hw_params, channels); if (res < 0) { av_log(ctx, AV_LOG_ERROR, "cannot set channel count to %d (%s)\n", channels, snd_strerror(res)); goto fail; } snd_pcm_hw_params_get_buffer_size_max(hw_params, &buffer_size); /* TODO: maybe use ctx->max_picture_buffer somehow */ res = snd_pcm_hw_params_set_buffer_size_near(h, hw_params, &buffer_size); if (res < 0) { av_log(ctx, AV_LOG_ERROR, "cannot set ALSA buffer size (%s)\n", snd_strerror(res)); goto fail; } snd_pcm_hw_params_get_period_size_min(hw_params, &period_size, NULL); res = snd_pcm_hw_params_set_period_size_near(h, hw_params, &period_size, NULL); if (res < 0) { av_log(ctx, AV_LOG_ERROR, "cannot set ALSA period size (%s)\n", snd_strerror(res)); goto fail; } s->period_size = period_size; res = snd_pcm_hw_params(h, hw_params); if (res < 0) { av_log(ctx, AV_LOG_ERROR, "cannot set parameters (%s)\n", snd_strerror(res)); goto fail; } snd_pcm_hw_params_free(hw_params); if (channels > 2 && layout) { if (find_reorder_func(s, *codec_id, layout, mode == SND_PCM_STREAM_PLAYBACK) < 0) { char name[128]; av_get_channel_layout_string(name, sizeof(name), channels, layout); av_log(ctx, AV_LOG_WARNING, "ALSA channel layout unknown or unimplemented for %s %s.\n", name, mode == SND_PCM_STREAM_PLAYBACK ? "playback" : "capture"); } if (s->reorder_func) { s->reorder_buf_size = buffer_size; s->reorder_buf = av_malloc(s->reorder_buf_size * s->frame_size); if (!s->reorder_buf) goto fail1; } } s->h = h; return 0; fail: snd_pcm_hw_params_free(hw_params); fail1: snd_pcm_close(h); return AVERROR(EIO); }
static int set_hwparams (GstAlsaSrc * alsa) { guint rrate; gint err; snd_pcm_hw_params_t *params; snd_pcm_hw_params_malloc (¶ms); /* choose all parameters */ CHECK (snd_pcm_hw_params_any (alsa->handle, params), no_config); /* set the interleaved read/write format */ CHECK (snd_pcm_hw_params_set_access (alsa->handle, params, alsa->access), wrong_access); /* set the sample format */ CHECK (snd_pcm_hw_params_set_format (alsa->handle, params, alsa->format), no_sample_format); /* set the count of channels */ CHECK (snd_pcm_hw_params_set_channels (alsa->handle, params, alsa->channels), no_channels); /* set the stream rate */ rrate = alsa->rate; CHECK (snd_pcm_hw_params_set_rate_near (alsa->handle, params, &rrate, NULL), no_rate); if (rrate != alsa->rate) goto rate_match; #ifndef GST_DISABLE_GST_DEBUG /* get and dump some limits */ { guint min, max; snd_pcm_hw_params_get_buffer_time_min (params, &min, NULL); snd_pcm_hw_params_get_buffer_time_max (params, &max, NULL); GST_DEBUG_OBJECT (alsa, "buffer time %u, min %u, max %u", alsa->buffer_time, min, max); snd_pcm_hw_params_get_period_time_min (params, &min, NULL); snd_pcm_hw_params_get_period_time_max (params, &max, NULL); GST_DEBUG_OBJECT (alsa, "period time %u, min %u, max %u", alsa->period_time, min, max); snd_pcm_hw_params_get_periods_min (params, &min, NULL); snd_pcm_hw_params_get_periods_max (params, &max, NULL); GST_DEBUG_OBJECT (alsa, "periods min %u, max %u", min, max); } #endif if (alsa->buffer_time != -1) { /* set the buffer time */ CHECK (snd_pcm_hw_params_set_buffer_time_near (alsa->handle, params, &alsa->buffer_time, NULL), buffer_time); GST_DEBUG_OBJECT (alsa, "buffer time %u", alsa->buffer_time); } if (alsa->period_time != -1) { /* set the period time */ CHECK (snd_pcm_hw_params_set_period_time_near (alsa->handle, params, &alsa->period_time, NULL), period_time); GST_DEBUG_OBJECT (alsa, "period time %u", alsa->period_time); } /* write the parameters to device */ CHECK (snd_pcm_hw_params (alsa->handle, params), set_hw_params); CHECK (snd_pcm_hw_params_get_buffer_size (params, &alsa->buffer_size), buffer_size); CHECK (snd_pcm_hw_params_get_period_size (params, &alsa->period_size, NULL), period_size); snd_pcm_hw_params_free (params); return 0; /* ERRORS */ no_config: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Broken configuration for recording: no configurations available: %s", snd_strerror (err))); snd_pcm_hw_params_free (params); return err; } wrong_access: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Access type not available for recording: %s", snd_strerror (err))); snd_pcm_hw_params_free (params); return err; } no_sample_format: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Sample format not available for recording: %s", snd_strerror (err))); snd_pcm_hw_params_free (params); return err; } no_channels: { gchar *msg = NULL; if ((alsa->channels) == 1) msg = g_strdup (_("Could not open device for recording in mono mode.")); if ((alsa->channels) == 2) msg = g_strdup (_("Could not open device for recording in stereo mode.")); if ((alsa->channels) > 2) msg = g_strdup_printf (_ ("Could not open device for recording in %d-channel mode"), alsa->channels); GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, ("%s", msg), ("%s", snd_strerror (err))); g_free (msg); snd_pcm_hw_params_free (params); return err; } no_rate: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Rate %iHz not available for recording: %s", alsa->rate, snd_strerror (err))); snd_pcm_hw_params_free (params); return err; } rate_match: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Rate doesn't match (requested %iHz, get %iHz)", alsa->rate, err)); snd_pcm_hw_params_free (params); return -EINVAL; } buffer_time: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Unable to set buffer time %i for recording: %s", alsa->buffer_time, snd_strerror (err))); snd_pcm_hw_params_free (params); return err; } buffer_size: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Unable to get buffer size for recording: %s", snd_strerror (err))); snd_pcm_hw_params_free (params); return err; } period_time: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Unable to set period time %i for recording: %s", alsa->period_time, snd_strerror (err))); snd_pcm_hw_params_free (params); return err; } period_size: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Unable to get period size for recording: %s", snd_strerror (err))); snd_pcm_hw_params_free (params); return err; } set_hw_params: { GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL), ("Unable to set hw params for recording: %s", snd_strerror (err))); snd_pcm_hw_params_free (params); return err; } }
/*---------------------------------------------------------------- TIesrFA_ALSA_open Try to open an ALSA audio PCM channel. ----------------------------------------------------------------*/ TIesrFA_ALSA_Error_t TIesrFA_ALSA_open( TIesrFA_t * const aTIesrFAInstance ) { int rtnStatus; int openSuccess = 0; snd_pcm_uframes_t numSamples; snd_pcm_hw_params_t *hw_params = 0; snd_pcm_sw_params_t *sw_params = 0; TIesrFA_ALSA_t * const ALSAData = (TIesrFA_ALSA_t * const) aTIesrFAInstance->impl_data; /* Try to open a handle to the ALSA pcm in blocking mode. */ rtnStatus = snd_pcm_open( &ALSAData->alsa_handle, aTIesrFAInstance->channel_name, SND_PCM_STREAM_CAPTURE, 0 ); if( rtnStatus < 0 ) goto openExit; /* Set up the information for recording from the audio channelport. This will include data specified by the user, such as data in aTIesrFAInstance->encoding, etc. If setup fails, then the audio channel should be shut down and failure reported. */ /* Setup hardware parameters of the ALSA pcm */ rtnStatus = snd_pcm_hw_params_malloc( &hw_params ); if( rtnStatus < 0 ) goto openExit; rtnStatus = snd_pcm_hw_params_any( ALSAData->alsa_handle, hw_params ); if( rtnStatus < 0 ) goto openExit; /* There will only be a single channel */ rtnStatus = snd_pcm_hw_params_set_channels( ALSAData->alsa_handle, hw_params, 1 ); if( rtnStatus < 0 ) goto openExit; /* Even though only one channel, must specify type of read. */ rtnStatus = snd_pcm_hw_params_set_access( ALSAData->alsa_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED ); if( rtnStatus < 0 ) goto openExit; /* Format type - only 16 bit linear for now */ rtnStatus = snd_pcm_hw_params_set_format( ALSAData->alsa_handle, hw_params, SND_PCM_FORMAT_S16 ); if( rtnStatus < 0 ) goto openExit; /* Set sample rate, it must be exactly supported */ rtnStatus = snd_pcm_hw_params_set_rate( ALSAData->alsa_handle, hw_params, aTIesrFAInstance->sample_rate, 0 ); if( rtnStatus < 0 ) goto openExit; /* Size of ALSA PCM ring buffer is set to approximately the desired number of multiples of read_samples in the buffer */ numSamples = aTIesrFAInstance->num_audio_buffer_frames * ALSAData->read_samples; rtnStatus = snd_pcm_hw_params_set_buffer_size_near( ALSAData->alsa_handle, hw_params, &numSamples ); if( rtnStatus < 0 ) goto openExit; /* Set the hardware parameters in the PCM*/ rtnStatus = snd_pcm_hw_params( ALSAData->alsa_handle, hw_params ); if( rtnStatus < 0 ) goto openExit; /* Set software parameters to interrupt at the end of an audio buffer number of samples and to start-up manually */ rtnStatus = snd_pcm_sw_params_malloc( &sw_params ); if( rtnStatus < 0 ) goto openExit; rtnStatus = snd_pcm_sw_params_current( ALSAData->alsa_handle, sw_params ); if( rtnStatus < 0 ) goto openExit; /* Number of samples needed in PCM buffer prior to interrupt */ rtnStatus = snd_pcm_sw_params_set_avail_min( ALSAData->alsa_handle, sw_params, ALSAData->read_samples ); if( rtnStatus < 0 ) goto openExit; /* Set start threshold so startup is done manually */ rtnStatus = snd_pcm_sw_params_set_start_threshold( ALSAData->alsa_handle, sw_params, ULONG_MAX ); if( rtnStatus < 0 ) goto openExit; /* Channel opened successfully */ openSuccess = 1; openExit: if( hw_params != NULL ) snd_pcm_hw_params_free( hw_params ); if( sw_params != NULL ) snd_pcm_sw_params_free( sw_params ); if( openSuccess ) return TIesrFA_ALSAErrNone; return TIesrFA_ALSAErrFail; }
const VisPluginInfo *get_plugin_info (void) { static VisInputPlugin input = { .upload = inp_alsa_upload }; static VisPluginInfo info = { .type = VISUAL_PLUGIN_TYPE_INPUT, .plugname = "alsa", .name = "alsa", .author = "Vitaly V. Bursov <*****@*****.**>", .version = "0.1", .about = N_("ALSA capture plugin"), .help = N_("Use this plugin to capture PCM data from the ALSA record device"), .license = VISUAL_PLUGIN_LICENSE_LGPL, .init = inp_alsa_init, .cleanup = inp_alsa_cleanup, .plugin = &input }; return &info; } int inp_alsa_init (VisPluginData *plugin) { snd_pcm_hw_params_t *hwparams = NULL; alsaPrivate *priv; unsigned int rate = inp_alsa_var_samplerate; unsigned int exact_rate; unsigned int tmp; int dir = 0; int err; #if ENABLE_NLS bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR); #endif priv = visual_mem_new0 (alsaPrivate, 1); visual_plugin_set_private (plugin, priv); if ((err = snd_pcm_open(&priv->chandle, inp_alsa_var_cdevice, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0) { visual_log(VISUAL_LOG_ERROR, "Record open error: %s", snd_strerror(err)); return FALSE; } snd_pcm_hw_params_malloc(&hwparams); visual_return_val_if_fail(hwparams != NULL, FALSE); if (snd_pcm_hw_params_any(priv->chandle, hwparams) < 0) { visual_log(VISUAL_LOG_ERROR, "Cannot configure this PCM device"); snd_pcm_hw_params_free(hwparams); return FALSE; } if (snd_pcm_hw_params_set_access(priv->chandle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) { visual_log(VISUAL_LOG_ERROR, "Error setting access"); snd_pcm_hw_params_free(hwparams); return FALSE; } #if VISUAL_LITTLE_ENDIAN == 1 if (snd_pcm_hw_params_set_format(priv->chandle, hwparams, SND_PCM_FORMAT_S16_LE) < 0) { #else if (snd_pcm_hw_params_set_format(priv->chandle, hwparams, SND_PCM_FORMAT_S16_BE) < 0) { #endif visual_log(VISUAL_LOG_ERROR, "Error setting format"); snd_pcm_hw_params_free(hwparams); return FALSE; } exact_rate = rate; if (snd_pcm_hw_params_set_rate_near(priv->chandle, hwparams, &exact_rate, &dir) < 0) { visual_log(VISUAL_LOG_ERROR, "Error setting rate"); snd_pcm_hw_params_free(hwparams); return FALSE; } if (exact_rate != rate) { visual_log(VISUAL_LOG_INFO, "The rate %d Hz is not supported by your " \ "hardware.\n" \ "==> Using %d Hz instead", rate, exact_rate); } if (snd_pcm_hw_params_set_channels(priv->chandle, hwparams, inp_alsa_var_channels) < 0) { visual_log(VISUAL_LOG_ERROR, "Error setting channels"); snd_pcm_hw_params_free(hwparams); return FALSE; } /* Setup a large buffer */ tmp = 1000000; if (snd_pcm_hw_params_set_period_time_near(priv->chandle, hwparams, &tmp, &dir) < 0){ visual_log(VISUAL_LOG_ERROR, "Error setting period time"); snd_pcm_hw_params_free(hwparams); return FALSE; } tmp = 1000000*4; if (snd_pcm_hw_params_set_buffer_time_near(priv->chandle, hwparams, &tmp, &dir) < 0){ visual_log(VISUAL_LOG_ERROR, "Error setting buffer time"); snd_pcm_hw_params_free(hwparams); return FALSE; } if (snd_pcm_hw_params(priv->chandle, hwparams) < 0) { visual_log(VISUAL_LOG_ERROR, "Error setting HW params"); snd_pcm_hw_params_free(hwparams); return FALSE; } if (snd_pcm_prepare(priv->chandle) < 0) { visual_log(VISUAL_LOG_ERROR, "Failed to prepare interface"); snd_pcm_hw_params_free(hwparams); return FALSE; } snd_pcm_hw_params_free(hwparams); priv->loaded = TRUE; return TRUE; } void inp_alsa_cleanup (VisPluginData *plugin) { alsaPrivate *priv = visual_plugin_get_private (plugin); if (priv->loaded) { snd_pcm_close(priv->chandle); } visual_mem_free (priv); }
/* Initialise audio devices. */ int digi_init() { int err, tmp; char *device = "plughw:0,0"; snd_pcm_hw_params_t *params; pthread_attr_t attr; pthread_mutexattr_t mutexattr; //added on 980905 by adb to init sound kill system memset(SampleHandles, 255, sizeof(SampleHandles)); //end edit by adb /* Open the ALSA sound device */ if ((err = snd_pcm_open(&snd_devhandle, device, SND_PCM_STREAM_PLAYBACK)) < 0) { con_printf(CON_CRITICAL, "open failed: %s\n", snd_strerror( err )); return -1; } snd_pcm_hw_params_alloca(¶ms); err = snd_pcm_hw_params_any(snd_devhandle, params); if (err < 0) { con_printf(CON_CRITICAL,"ALSA: Error %s\n", snd_strerror(err)); return -1; } err = snd_pcm_hw_params_set_access(snd_devhandle, params, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { con_printf(CON_CRITICAL,"ALSA: Error %s\n", snd_strerror(err)); return -1; } err = snd_pcm_hw_params_set_format(snd_devhandle, params, SND_PCM_FORMAT_U8); if (err < 0) { con_printf(CON_CRITICAL,"ALSA: Error %s\n", snd_strerror(err)); return -1; } err = snd_pcm_hw_params_set_channels(snd_devhandle, params, 2); if (err < 0) { con_printf(CON_CRITICAL,"ALSA: Error %s\n", snd_strerror(err)); return -1; } tmp = 11025; err = snd_pcm_hw_params_set_rate_near(snd_devhandle, params, &tmp, NULL); if (err < 0) { con_printf(CON_CRITICAL,"ALSA: Error %s\n", snd_strerror(err)); return -1; } snd_pcm_hw_params_set_periods(snd_devhandle, params, 3, 0); snd_pcm_hw_params_set_buffer_size(snd_devhandle,params, (SOUND_BUFFER_SIZE*3)/2); err = snd_pcm_hw_params(snd_devhandle, params); if (err < 0) { con_printf(CON_CRITICAL,"ALSA: Error %s\n", snd_strerror(err)); return -1; } /* Start the mixer thread */ /* We really should check the results of these */ pthread_mutexattr_init(&mutexattr); pthread_mutex_init(&mutex,&mutexattr); pthread_mutexattr_destroy(&mutexattr); if (pthread_attr_init(&attr) != 0) { con_printf(CON_CRITICAL, "failed to init attr\n"); snd_pcm_close( snd_devhandle ); return -1; } pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_create(&thread_id,&attr,mixer_thread,NULL); pthread_attr_destroy(&attr); digi_initialised = 1; return 0; }
int alsa_play_hw(alsa_play_t alsa_play, glc_audio_format_message_t *fmt_msg) { snd_pcm_hw_params_t *hw_params = NULL; snd_pcm_access_t access; unsigned int period_time; unsigned int buffer_time; int dir = 0, ret = 0; if (unlikely(fmt_msg->id != alsa_play->id)) return 0; alsa_play->flags = fmt_msg->flags; alsa_play->format = fmt_msg->format; alsa_play->rate = fmt_msg->rate; alsa_play->channels = fmt_msg->channels; if (alsa_play->pcm) /* re-open */ snd_pcm_close(alsa_play->pcm); if (alsa_play->flags & GLC_AUDIO_INTERLEAVED) access = SND_PCM_ACCESS_RW_INTERLEAVED; else access = SND_PCM_ACCESS_RW_NONINTERLEAVED; if (unlikely((ret = snd_pcm_open(&alsa_play->pcm, alsa_play->device, SND_PCM_STREAM_PLAYBACK, 0)) < 0)) goto err; snd_pcm_hw_params_alloca(&hw_params); if (unlikely((ret = snd_pcm_hw_params_any(alsa_play->pcm, hw_params)) < 0)) goto err; if (unlikely((ret = snd_pcm_hw_params_set_access(alsa_play->pcm, hw_params, access)) < 0)) goto err; if (unlikely((ret = snd_pcm_hw_params_set_format(alsa_play->pcm, hw_params, glc_fmt_to_pcm_fmt(alsa_play->format))) < 0)) goto err; if (unlikely((ret = snd_pcm_hw_params_set_channels(alsa_play->pcm, hw_params, alsa_play->channels)) < 0)) goto err; if (unlikely((ret = snd_pcm_hw_params_set_rate(alsa_play->pcm, hw_params, alsa_play->rate, 0)) < 0)) goto err; if (unlikely((ret = snd_pcm_hw_params_get_buffer_time_max(hw_params, &buffer_time, 0)))) goto err; if (buffer_time > 1000000) { glc_log(alsa_play->glc, GLC_INFO, "alsa_play", "buffer time max is %u usec. We will limit it to 1 sec", buffer_time); buffer_time = 1000000; } period_time = buffer_time / 4; alsa_play->silence_threshold = period_time*2000; if (unlikely((ret = snd_pcm_hw_params_set_period_time_near(alsa_play->pcm, hw_params, &period_time, 0)) < 0)) goto err; if (unlikely((ret = snd_pcm_hw_params_set_buffer_time_near(alsa_play->pcm, hw_params, &buffer_time, 0)) < 0)) goto err; if (unlikely((ret = snd_pcm_hw_params(alsa_play->pcm, hw_params)) < 0)) goto err; alsa_play->bufs = (void **) malloc(sizeof(void *) * alsa_play->channels); glc_log(alsa_play->glc, GLC_INFO, "alsa_play", "opened pcm %s for playback. buffer_time: %u", alsa_play->device, buffer_time); return 0; err: glc_log(alsa_play->glc, GLC_ERROR, "alsa_play", "can't initialize pcm %s: %s (%d)", alsa_play->device, snd_strerror(ret), ret); return -ret; }
bool AlsaSource::SetupHW () { bool result = false; bool rw_available = false; bool mmap_available = false; #if DEBUG bool debug = debug_flags & RUNTIME_DEBUG_AUDIO; #else bool debug = false; #endif snd_pcm_hw_params_t *params = NULL; snd_output_t *output = NULL; guint32 buffer_time = 100000; // request 0.1 seconds of buffer time. int err = 0; int dir = 0; unsigned int rate = GetSampleRate (); unsigned int actual_rate = rate; guint32 channels = GetChannels (); if (debug) { err = snd_output_stdio_attach (&output, stdout, 0); if (err < 0) LOG_AUDIO ("AlsaSource::SetupHW (): Could not create alsa output: %s\n", snd_strerror (err)); } err = snd_pcm_hw_params_malloc (¶ms); if (err < 0) { LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup failed (malloc): %s\n", snd_strerror (err)); return false; } // choose all parameters err = snd_pcm_hw_params_any (pcm, params); if (err < 0) { LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup failed (no configurations available): %s\n", snd_strerror (err)); goto cleanup; } if (debug && output != NULL) { LOG_AUDIO ("AlsaSource::SetupHW (): hw configurations:\n"); snd_pcm_hw_params_dump (params, output); } // enable software resampling err = snd_pcm_hw_params_set_rate_resample (pcm, params, 1); if (err < 0) { LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup failed (could not enable resampling): %s\n", snd_strerror (err)); goto cleanup; } // test for available transfer modes if (!(moonlight_flags & RUNTIME_INIT_AUDIO_ALSA_MMAP)) { err = snd_pcm_hw_params_test_access (pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup: RW access mode not supported (%s).\n", snd_strerror (err)); } else { rw_available = true; } } if (!(moonlight_flags & RUNTIME_INIT_AUDIO_ALSA_RW)) { err = snd_pcm_hw_params_test_access (pcm, params, SND_PCM_ACCESS_MMAP_INTERLEAVED); if (err < 0) { LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup: MMAP access mode not supported (%s).\n", snd_strerror (err)); } else { mmap_available = true; } } if (mmap_available) { mmap = true; } else if (rw_available) { mmap = false; } else { LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup failed, no available access mode\n"); goto cleanup; } LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup: using %s access mode.\n", mmap ? "MMAP" : "RW"); // set transfer mode (mmap or rw in our case) err = snd_pcm_hw_params_set_access (pcm, params, mmap ? SND_PCM_ACCESS_MMAP_INTERLEAVED : SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup failed (access type not available for playback): %s\n", snd_strerror (err)); goto cleanup; } // set audio format switch (GetInputBytesPerSample ()) { case 1: // 8 bit audio err = snd_pcm_hw_params_set_format (pcm, params, SND_PCM_FORMAT_S16); SetOutputBytesPerSample (2); break; case 2: // 16 bit audio err = snd_pcm_hw_params_set_format (pcm, params, SND_PCM_FORMAT_S16); SetOutputBytesPerSample (2); break; case 3: // 24 bit audio // write as 32 bit audio, this is a lot easier to write to than 24 bit. err = snd_pcm_hw_params_set_format (pcm, params, SND_PCM_FORMAT_S32); SetOutputBytesPerSample (4); break; default: LOG_AUDIO ("AlsaSource::SetupHW (): Invalid input bytes per sample, expected 1, 2 or 3, got %i\n", GetInputBytesPerSample ()); goto cleanup; } if (err < 0) { LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup failed (sample format not available for playback): %s\n", snd_strerror (err)); goto cleanup; } // set channel count err = snd_pcm_hw_params_set_channels (pcm, params, channels); if (err < 0) { LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup failed (channels count %i not available for playback): %s\n", channels, snd_strerror (err)); goto cleanup; } // set sample rate err = snd_pcm_hw_params_set_rate_near (pcm, params, &actual_rate, 0); if (err < 0) { LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup failed (sample rate %i Hz not available for playback): %s\n", rate, snd_strerror (err)); goto cleanup; } else if (actual_rate != rate) { LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup failed (sample rate %i Hz not available for playback, only got %i Hz).\n", rate, actual_rate); goto cleanup; } // set the buffer time err = snd_pcm_hw_params_set_buffer_time_near (pcm, params, &buffer_time, &dir); if (err < 0) { LOG_AUDIO ("AudioNode::SetupHW (): Audio HW setup failed (unable to set buffer time %i for playback: %s\n", buffer_time, snd_strerror (err)); goto cleanup; } // write the parameters to device err = snd_pcm_hw_params (pcm, params); if (err < 0) { LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup failed (unable to set hw params for playback: %s)\n", snd_strerror (err)); if (debug && output != NULL) { LOG_AUDIO ("AlsaSource::SetupHW (): current hw configurations:\n"); snd_pcm_hw_params_dump (params, output); } goto cleanup; } if (debug) { LOG_AUDIO ("AlsaSource::SetupHW (): hardware pause support: %s\n", snd_pcm_hw_params_can_pause (params) == 0 ? "no" : "yes"); LOG_AUDIO ("AlsaSource::SetupHW (): succeeded\n"); if (output != NULL) snd_pcm_hw_params_dump (params, output); } result = true; cleanup: snd_pcm_hw_params_free (params); return result; }
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, "PCM: Broken configuration: 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; }
main (int argc, char *argv[]) { int i; int err; short buf[128]; snd_pcm_t *capture_handle; snd_pcm_hw_params_t *hw_params; if ((err = snd_pcm_open (&capture_handle, argv[1], SND_PCM_STREAM_CAPTURE, 0)) < 0) { fprintf (stderr, "cannot open audio device %s (%s)\n", argv[1], snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) { fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_any (capture_handle, hw_params)) < 0) { fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_access (capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { fprintf (stderr, "cannot set access type (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_format (capture_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) { fprintf (stderr, "cannot set sample format (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_rate_near (capture_handle, hw_params, 44100, 0)) < 0) { fprintf (stderr, "cannot set sample rate (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_channels (capture_handle, hw_params, 2)) < 0) { fprintf (stderr, "cannot set channel count (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params (capture_handle, hw_params)) < 0) { fprintf (stderr, "cannot set parameters (%s)\n", snd_strerror (err)); exit (1); } snd_pcm_hw_params_free (hw_params); if ((err = snd_pcm_prepare (capture_handle)) < 0) { fprintf (stderr, "cannot prepare audio interface for use (%s)\n", snd_strerror (err)); exit (1); } for (i = 0; i < 10; ++i) { if ((err = snd_pcm_readi (capture_handle, buf, 128)) != 128) { fprintf (stderr, "read from audio interface failed (%s)\n", snd_strerror (err)); exit (1); } } snd_pcm_close (capture_handle); exit (0); }
static snd_pcm_t *alsa_open(char *dev, int rate, int channels) { snd_pcm_hw_params_t *hwp; snd_pcm_sw_params_t *swp; snd_pcm_t *h; int r; int dir; snd_pcm_uframes_t period_size_min; snd_pcm_uframes_t period_size_max; snd_pcm_uframes_t buffer_size_min; snd_pcm_uframes_t buffer_size_max; snd_pcm_uframes_t period_size; snd_pcm_uframes_t buffer_size; if ((r = snd_pcm_open(&h, dev, SND_PCM_STREAM_PLAYBACK, 0) < 0)) return NULL; hwp = alloca(snd_pcm_hw_params_sizeof()); memset(hwp, 0, snd_pcm_hw_params_sizeof()); snd_pcm_hw_params_any(h, hwp); snd_pcm_hw_params_set_access(h, hwp, SND_PCM_ACCESS_RW_INTERLEAVED); snd_pcm_hw_params_set_format(h, hwp, SND_PCM_FORMAT_S16_LE); snd_pcm_hw_params_set_rate(h, hwp, rate, 0); snd_pcm_hw_params_set_channels(h, hwp, channels); /* Configurue period */ dir = 0; snd_pcm_hw_params_get_period_size_min(hwp, &period_size_min, &dir); dir = 0; snd_pcm_hw_params_get_period_size_max(hwp, &period_size_max, &dir); period_size = 1024; dir = 0; r = snd_pcm_hw_params_set_period_size_near(h, hwp, &period_size, &dir); if (r < 0) { fprintf(stderr, "audio: Unable to set period size %lu (%s)\n", period_size, snd_strerror(r)); snd_pcm_close(h); return NULL; } dir = 0; r = snd_pcm_hw_params_get_period_size(hwp, &period_size, &dir); if (r < 0) { fprintf(stderr, "audio: Unable to get period size (%s)\n", snd_strerror(r)); snd_pcm_close(h); return NULL; } /* Configurue buffer size */ snd_pcm_hw_params_get_buffer_size_min(hwp, &buffer_size_min); snd_pcm_hw_params_get_buffer_size_max(hwp, &buffer_size_max); buffer_size = period_size * 4; dir = 0; r = snd_pcm_hw_params_set_buffer_size_near(h, hwp, &buffer_size); if (r < 0) { fprintf(stderr, "audio: Unable to set buffer size %lu (%s)\n", buffer_size, snd_strerror(r)); snd_pcm_close(h); return NULL; } r = snd_pcm_hw_params_get_buffer_size(hwp, &buffer_size); if (r < 0) { fprintf(stderr, "audio: Unable to get buffer size (%s)\n", snd_strerror(r)); snd_pcm_close(h); return NULL; } /* write the hw params */ r = snd_pcm_hw_params(h, hwp); if (r < 0) { fprintf(stderr, "audio: Unable to configure hardware parameters (%s)\n", snd_strerror(r)); snd_pcm_close(h); return NULL; } /* * Software parameters */ swp = alloca(snd_pcm_sw_params_sizeof()); memset(hwp, 0, snd_pcm_sw_params_sizeof()); snd_pcm_sw_params_current(h, swp); r = snd_pcm_sw_params_set_avail_min(h, swp, period_size); if (r < 0) { fprintf(stderr, "audio: Unable to configure wakeup threshold (%s)\n", snd_strerror(r)); snd_pcm_close(h); return NULL; } snd_pcm_sw_params_set_start_threshold(h, swp, 0); if (r < 0) { fprintf(stderr, "audio: Unable to configure start threshold (%s)\n", snd_strerror(r)); snd_pcm_close(h); return NULL; } r = snd_pcm_sw_params(h, swp); if (r < 0) { fprintf(stderr, "audio: Cannot set soft parameters (%s)\n", snd_strerror(r)); snd_pcm_close(h); return NULL; } r = snd_pcm_prepare(h); if (r < 0) { fprintf(stderr, "audio: Cannot prepare audio for playback (%s)\n", snd_strerror(r)); snd_pcm_close(h); return NULL; } return h; }
void* play_thread(void *argv) { char *__file_name = argv; struct WAVE *_wave; #ifdef SOLO _wave = (struct WAVE*)malloc(sizeof(struct WAVE)); memset(&_wave, 0, sizeof(struct _wave)); if(!wave_read_file(argv, &_wave )){ goto ERR; } #else if(!list_count){ fprintf(stderr,"[PLAY]: Not such wav sound file.\nPlease call \'play_read_filelist(DIR_PATH)\'\n"); exit(1); } for(_wave=head;;_wave=_wave->next){ if(!strcmp(_wave->file_name, __file_name))break; if(head->prev == _wave){ fprintf(stderr,"[PLAY]: Invalid file_name...\n"); return NULL; } } #endif if(DISP) fprintf(stderr,"[PLAY]: Player will be playing \"%s\".\n",__file_name); snd_pcm_t *handle; // handle for sound_device snd_pcm_hw_params_t *params; // params for sound_device int result_func = 0; // result for function return unsigned int sampling_rate = _wave->rate; // sampling rate int dir; // sub unit direction snd_pcm_uframes_t frames = 32; // size of frame unsigned int buffer_size; // buffer_size for frame int16_t *frameBuffer=NULL; // buffer for frame unsigned int approximate_period; // period[us] {// open the pcm device // open pcm device result_func = snd_pcm_open( &handle, "default", SND_PCM_STREAM_PLAYBACK, 0); if ( result_func < 0 ) { fprintf(stderr, "[PLAY]: unable to open pcm device :%s\n", snd_strerror(result_func)); goto ERR; } } {// set parameter to device // allocate device params snd_pcm_hw_params_alloca(¶ms); // get default param snd_pcm_hw_params_any(handle, params); // set parameter Interleaved mode snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); // set format parameter : monoral 1ch 16bit LittleEndian snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); // set output_device parameter stereo 2ch snd_pcm_hw_params_set_channels(handle, params, _wave->channel); // approximates to a specified sampling rate // pcm PCM handle // params Configuration space // val approximate target rate / returned approximate set rate // dir Sub unit direction snd_pcm_hw_params_set_rate_near( handle, params, &sampling_rate, &dir); // set parameter size of frame snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); // set parameter to hardware_device result_func = snd_pcm_hw_params(handle, params); // err check if (result_func < 0) { fprintf(stderr, "[PLAY]: unable to set hw parameters: %s\n", snd_strerror(result_func)); goto ERR; } // get bufferSize / frame snd_pcm_hw_params_get_period_size(params, &frames, &dir); // calculate buffer_size buffer_size = frames * 2; /*????????? 48000,monoral ver */ // allocate buffer frameBuffer = (int16_t *)malloc(buffer_size); memset(frameBuffer, 0, sizeof(*frameBuffer)); // get playback period // params Configuration space // val Returned approximate period duration in us // dir Sub unit direction snd_pcm_hw_params_get_period_time(params, &approximate_period, &dir); } { // playback process // playback time unsigned int ptime = approximate_period * 2 * 10; // playback while ( ptime-- ) { result_func = fread( frameBuffer, sizeof(unsigned char), buffer_size, _wave->fp); // data is ended if ( result_func == 0 ) { //fprintf(stdout, "[PLAY]: end of input devce\n"); break; } // buffer_size is not correct if ( result_func != buffer_size ) { /* fprintf(stderr, "short read: read %d bytes\n", result_func); */ break; } // playback result_func = snd_pcm_writei( handle, frameBuffer, frames); } } // for unplayed frame,wait sound finish snd_pcm_drain(handle); if(DISP) fprintf(stderr,"[PLAY]: Finished playing %s.\n",__file_name); ERR : { // release if ( frameBuffer != NULL ){ free(frameBuffer); } if ( handle != NULL ) { snd_pcm_close(handle); } } return NULL; }
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; }