result alsa_init(Soloud *aSoloud, unsigned int aFlags, unsigned int aSamplerate, unsigned int aBuffer, unsigned int aChannels) { ALSAData *data = new ALSAData; memset(data, 0, sizeof(ALSAData)); aSoloud->mBackendData = data; aSoloud->mBackendCleanupFunc = alsaCleanup; data->samples = aBuffer; data->channels = 2; data->soloud = aSoloud; int rc; snd_pcm_t *handle; rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0); if (rc < 0) { return UNKNOWN_ERROR; } data->alsaDeviceHandle = handle; snd_pcm_hw_params_t *params; snd_pcm_hw_params_alloca(¶ms); snd_pcm_hw_params_any(handle, params); snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); snd_pcm_hw_params_set_channels(handle, params, 2); snd_pcm_hw_params_set_buffer_size(handle, params, aBuffer); unsigned int val = aSamplerate; int dir = 0; rc = snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); if (rc < 0) { return UNKNOWN_ERROR; } rc = snd_pcm_hw_params(handle, params); if (rc < 0) { return UNKNOWN_ERROR; } snd_pcm_hw_params_get_rate(params, &val, &dir); aSamplerate = val; snd_pcm_hw_params_get_channels(params, &val); data->channels = val; data->buffer = new float[data->samples*data->channels]; data->sampleBuffer = new short[data->samples*data->channels]; aSoloud->postinit(aSamplerate, data->samples * data->channels, aFlags, 2); data->threadHandle = Thread::createThread(alsaThread, data); if (0 == data->threadHandle) { return UNKNOWN_ERROR; } aSoloud->mBackendString = "ALSA"; return 0; }
static int ste_iop_hwparams(snd_pcm_ioplug_t *io, snd_pcm_hw_params_t *params) { int err = 0; int direction; ste_iop_t *ste_iop = io->private_data; /* Get and print HW params */ /* PCM format */ err = snd_pcm_hw_params_get_format(params, &ste_iop->hwparams.pcm_format); if (err < 0) { fprintf(stderr, "ST-Ericsson ALSA ADM I/O Plugin: Failed to get HW param PCM format: %s\n", snd_strerror(err)); return err; } /* PCM access mode */ err = snd_pcm_hw_params_get_access(params, &ste_iop->hwparams.pcm_access); if (err < 0) { fprintf(stderr, "ST-Ericsson ALSA ADM I/O Plugin: Failed to get HW param PCM Access mode: %s\n", snd_strerror(err)); return err; } /* PCM number of channels */ err = snd_pcm_hw_params_get_channels(params, &ste_iop->hwparams.pcm_channels); if (err < 0) { fprintf(stderr, "ST-Ericsson ALSA ADM I/O Plugin: Failed to get HW param PCM number of channels: %s\n", snd_strerror(err)); return err; } /* Sample Rate */ err = snd_pcm_hw_params_get_rate(params, &ste_iop->hwparams.pcm_rate, &direction); if (err < 0) { fprintf(stderr, "ST-Ericsson ALSA ADM I/O Plugin: Failed to get HW param PCM Sample Rate: %s\n", snd_strerror(err)); return err; } ste_iop->bufsz = ste_iop->hwparams.pcm_rate * 32 / 1000 * 2 * ste_iop->hwparams.pcm_channels; /* Period time */ err = snd_pcm_hw_params_get_period_time(params, &ste_iop->hwparams.pcm_period_time, &direction); if (err < 0) { fprintf(stderr, "ST-Ericsson ALSA ADM I/O Plugin: Failed to get HW param PCM period time: %s\n", snd_strerror(err)); return err; } return 0; }
AudioSourceNix::AudioSourceNix(int c, int r) : AudioSource(c, r) { int err; unsigned int ap_rate = rate; unsigned int ap_chan = channels; err = snd_pcm_open(&device, ADDR, SND_PCM_STREAM_CAPTURE, 0); if (err < 0) { g2g = PR_FALSE; return; } err = snd_pcm_hw_params_malloc(¶ms); if (err < 0) { g2g = PR_FALSE; return; } err = snd_pcm_hw_params_any(device, params); if (err < 0) { g2g = PR_FALSE; return; } err = snd_pcm_hw_params_set_access( device, params, SND_PCM_ACCESS_RW_INTERLEAVED ); if (err < 0) { g2g = PR_FALSE; return; } err = snd_pcm_hw_params_set_format( device, params, SND_PCM_FORMAT_S16_LE ); if (err < 0) { g2g = PR_FALSE; return; } /* For rate and channels if we don't get * what we want, that's too bad */ err = snd_pcm_hw_params_set_rate_near( device, params, &ap_rate, 0 ); if (err < 0) { err = snd_pcm_hw_params_get_rate( params, &ap_rate, 0 ); if (err < 0) { g2g = PR_FALSE; return; } } err = snd_pcm_hw_params_set_channels( device, params, ap_chan ); if (err < 0) { err = snd_pcm_hw_params_get_channels( params, &ap_chan ); if (err < 0) { g2g = PR_FALSE; return; } } g2g = PR_TRUE; rec = PR_FALSE; rate = ap_rate; channels = ap_chan; snd_pcm_close(device); }
static int alsa_get_preferred_sample_rate(cubeb * ctx, uint32_t * rate) { (void)ctx; int r, dir; snd_pcm_t * pcm; snd_pcm_hw_params_t * hw_params; snd_pcm_hw_params_alloca(&hw_params); /* get a pcm, disabling resampling, so we get a rate the * hardware/dmix/pulse/etc. supports. */ r = snd_pcm_open(&pcm, CUBEB_ALSA_PCM_NAME, SND_PCM_STREAM_PLAYBACK, SND_PCM_NO_AUTO_RESAMPLE); if (r < 0) { return CUBEB_ERROR; } r = snd_pcm_hw_params_any(pcm, hw_params); if (r < 0) { snd_pcm_close(pcm); return CUBEB_ERROR; } r = snd_pcm_hw_params_get_rate(hw_params, rate, &dir); if (r >= 0) { /* There is a default rate: use it. */ snd_pcm_close(pcm); return CUBEB_OK; } /* Use a common rate, alsa may adjust it based on hw/etc. capabilities. */ *rate = 44100; r = snd_pcm_hw_params_set_rate_near(pcm, hw_params, rate, NULL); if (r < 0) { snd_pcm_close(pcm); return CUBEB_ERROR; } snd_pcm_close(pcm); return CUBEB_OK; }
void alsa_print_info(snd_pcm_t * handle, snd_pcm_hw_params_t * hwp) { printf("device [%s] opened with\n", snd_pcm_name(handle)); printf("\tstate=%s\n", snd_pcm_state_name(snd_pcm_state(handle))); unsigned int val, val2; snd_pcm_hw_params_get_access(hwp, (snd_pcm_access_t *) &val); printf("\taccess_type=%s\n", snd_pcm_access_name((snd_pcm_access_t)val)); snd_pcm_hw_params_get_format(hwp, (snd_pcm_format_t *) &val); printf("\tformat=%s\n", snd_pcm_format_name((snd_pcm_format_t) val) ); snd_pcm_hw_params_get_channels(hwp, &val); printf("\tchannels=%d\n", val); snd_pcm_hw_params_get_rate(hwp, &val, (int *) &val2); printf("\trate=%d fps\n", val); snd_pcm_hw_params_get_period_time(hwp, &val, (int *) &val2); printf("\tperiod_time=%d us\n", val); snd_pcm_uframes_t frames; snd_pcm_hw_params_get_period_size(hwp, &frames, (int *) &val2); printf("\tperiod_size=%d frames\n", (int)frames); snd_pcm_hw_params_get_buffer_size(hwp, (snd_pcm_uframes_t *) &val); printf("\tbuffer_size=%d frames\n", val); snd_pcm_hw_params_get_periods(hwp, &val, (int *) &val2); printf("\tperiods_per_buffer=%d periods\n", val); }
int record(int size,char *serverString) { unsigned int pcm, tmp, dir; int rate, channels, seconds; snd_pcm_t *pcm_handle; snd_pcm_hw_params_t *params; snd_pcm_uframes_t frames; char *buff,*buf; int buff_size, loops; int fp; /*if (argc < 4) { printf("Usage: %s <sample_rate> <channels> <seconds>\n", argv[0]); return -1; }*/ rate = 8000;//atoi(argv[1]); channels = 1;//atoi(argv[2]); seconds = 10;//atoi(argv[3]); /* Open the PCM device in playback mode */ if (pcm = snd_pcm_open(&pcm_handle, "default" , SND_PCM_STREAM_PLAYBACK, 0) < 0) printf("ERROR: Can't open \"%s\" PCM device. %s\n", "default", snd_strerror(pcm)); /* Allocate parameters object and fill it with default values*/ snd_pcm_hw_params_alloca(¶ms); snd_pcm_hw_params_any(pcm_handle, params); /* Set parameters */ if (pcm = snd_pcm_hw_params_set_access(pcm_handle, params,SND_PCM_ACCESS_RW_INTERLEAVED) < 0) printf("ERROR: Can't set interleaved mode. %s\n", snd_strerror(pcm)); if (pcm = snd_pcm_hw_params_set_format(pcm_handle, params,SND_PCM_FORMAT_U8) < 0) printf("ERROR: Can't set format. %s\n", snd_strerror(pcm)); if (pcm = snd_pcm_hw_params_set_channels(pcm_handle, params, channels) < 0) printf("ERROR: Can't set channels number. %s\n", snd_strerror(pcm)); if (pcm = snd_pcm_hw_params_set_rate_near(pcm_handle, params, &rate, 0) < 0) printf("ERROR: Can't set rate. %s\n", snd_strerror(pcm)); /* Write parameters */ if (pcm = snd_pcm_hw_params(pcm_handle, params) < 0) printf("ERROR: Can't set harware parameters. %s\n", snd_strerror(pcm)); /* Resume information */ printf("PCM name: '%s'\n", snd_pcm_name(pcm_handle)); printf("PCM state: %s\n", snd_pcm_state_name(snd_pcm_state(pcm_handle))); snd_pcm_hw_params_get_channels(params, &tmp); printf("channels: %i ", tmp); if (tmp == 1) printf("(mono)\n"); else if (tmp == 2) printf("(stereo)\n"); snd_pcm_hw_params_get_rate(params, &tmp, 0); printf("rate: %d bps\n", tmp); printf("seconds: %d\n", seconds); /* Allocate buffer to hold single period */ snd_pcm_hw_params_get_period_size(params, &frames, 0); buff_size = frames * channels * 2 /* 2 -> sample size */; buff = (char *) malloc(buff_size*3); size = frames * channels * 2 /* 2 -> sample size */; buf = (char *) realloc((void*)serverString,(size*3)); snd_pcm_hw_params_get_period_time(params, &tmp, NULL); //fp=open("222.wav",O_RDONLY); for (loops = (seconds * 1000000) / tmp; loops > 0; loops--) { /* if (pcm = read(fp, buff, buff_size) == 0) { printf("Early end of file.\n"); //return 0; } */ if (pcm = snd_pcm_writei(pcm_handle, buf, frames) == -EPIPE) { printf("XRUN.\n"); snd_pcm_prepare(pcm_handle); } else if(pcm < 0) { printf("ERROR. Can't write to PCM device. %s\n", snd_strerror(pcm)); } } snd_pcm_drain(pcm_handle); snd_pcm_close(pcm_handle); free(buff); return 0; }
int open_alsa_read(struct pcm **p, char *name) { snd_pcm_t *pcm; if (snd_pcm_open(&pcm, name, SND_PCM_STREAM_CAPTURE, 0) < 0) { fprintf(stderr, "Error opening PCM device %s\n", name); return 0; } snd_pcm_hw_params_t *params; snd_pcm_hw_params_alloca(¶ms); if (snd_pcm_hw_params_any(pcm, params) < 0) { fprintf(stderr, "Can not configure this PCM device.\n"); snd_pcm_close(pcm); return 0; } if (snd_pcm_hw_params_set_access(pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) { fprintf(stderr, "Error setting access.\n"); snd_pcm_close(pcm); return 0; } if (snd_pcm_hw_params_set_format(pcm, params, SND_PCM_FORMAT_S16_LE) < 0) { fprintf(stderr, "Error setting S16_LE format.\n"); snd_pcm_close(pcm); return 0; } if (snd_pcm_hw_params_set_rate_resample(pcm, params, 0) < 0) { fprintf(stderr, "Error disabling resampling.\n"); snd_pcm_close(pcm); return 0; } unsigned rate_min = 8000; int dir_min = 0; if (snd_pcm_hw_params_set_rate_min(pcm, params, &rate_min, &dir_min) < 0 || rate_min < 8000) { fprintf(stderr, "Error setting min rate.\n"); snd_pcm_close(pcm); return 0; } if (snd_pcm_hw_params(pcm, params) < 0) { fprintf(stderr, "Error setting HW params.\n"); snd_pcm_close(pcm); return 0; } unsigned int rate = 0; if (snd_pcm_hw_params_get_rate(params, &rate, 0) < 0) { fprintf(stderr, "Error getting rate.\n"); snd_pcm_close(pcm); return 0; } unsigned int channels = 0; if (snd_pcm_hw_params_get_channels(params, &channels) < 0) { fprintf(stderr, "Error getting channels.\n"); snd_pcm_close(pcm); return 0; } struct alsa *alsa = (struct alsa *)malloc(sizeof(struct alsa)); alsa->base.close = close_alsa; alsa->base.info = info_alsa; alsa->base.rate = rate_alsa; alsa->base.channels = channels_alsa; alsa->base.rw = read_alsa; alsa->base.data = (void *)alsa; alsa->pcm = pcm; alsa->r = rate; alsa->c = channels; alsa->frames = 0; *p = &(alsa->base); return 1; }
bool QAudioInputPrivate::open( QObject *input ) { // Open the Alsa capture device. bool rc = true; int err; unsigned int freakuency = frequency; if ((err = snd_pcm_open(&handle, m_device.constData(), //"plughw:0,0" SND_PCM_STREAM_CAPTURE, 0/*SND_PCM_ASYNC*/)) < 0) { qWarning( "QAudioInput: snd_pcm_open: error %d", err); rc = false; } else { snd_pcm_hw_params_t *hwparams; // We want non-blocking mode. snd_pcm_nonblock(handle, 1); // Set the desired parameters. snd_pcm_hw_params_alloca(&hwparams); err = snd_pcm_hw_params_any(handle, hwparams); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_hw_params_any: err %d", err); } err = snd_pcm_hw_params_set_access(handle, hwparams, access); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_hw_params_set_access: err %d",err); } err = snd_pcm_hw_params_set_format(handle, hwparams,format); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_hw_params_set_format: err %d",err); } err = snd_pcm_hw_params_set_channels(handle,hwparams,(unsigned int)channels); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_hw_params_set_channels: err %d",err); } err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &freakuency, 0); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_hw_params_set_rate_near: err %d",err); } if(freakuency > 1.05 * frequency || freakuency < 0.95 * frequency) { qWarning("QAudioInput: warning, sample rate %i not supported by the hardware, using %u", frequency, freakuency); } if ( samplesPerBlock != -1 ) { // Set buffer and period sizes based on the supplied block size. sample_size = (snd_pcm_uframes_t)( samplesPerBlock * channels / 8 ); err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &freakuency, 0); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_hw_params_set_rate_near: err %d",err); } if(freakuency > 1.05 * frequency || freakuency < 0.95 * frequency) { qWarning( "QAudioInput: warning, sample rate %i not supported by the hardware, using %u", frequency, freakuency); } err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, 0); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_hw_params_set_buffer_time_near: err %d",err); } period_time = 1000000 * 256 / frequency; err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, 0); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_hw_params_set_period_time_near: err %d",err); } } else { // Use the largest buffer and period sizes we can. err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, 0); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_hw_params_set_buffer_time_near: err %d",err); } period_time = 1000000 * 256 / frequency; err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, 0); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_hw_params_set_period_time_near: err %d",err); } } err = snd_pcm_hw_params(handle, hwparams); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_hw_params: err %d",err); } int dir; unsigned int vval, vval2; snd_pcm_access_t aval; snd_pcm_format_t fval; snd_pcm_subformat_t sval; qLog(QAudioInput) << "PCM handle name = " << snd_pcm_name(handle); qLog(QAudioInput) << "PCM state = " << snd_pcm_state_name(snd_pcm_state(handle)); snd_pcm_hw_params_get_access(hwparams,&aval); vval = (unsigned int)aval; if ( (int)vval != (int)access ) { qLog(QAudioInput) << QString("access type not set, want %1 got %2") .arg(snd_pcm_access_name((snd_pcm_access_t)access)) .arg(snd_pcm_access_name((snd_pcm_access_t)vval)); access = (snd_pcm_access_t)vval; } qLog(QAudioInput) << "access type = " << snd_pcm_access_name((snd_pcm_access_t)vval); snd_pcm_hw_params_get_format(hwparams, &fval); vval = (unsigned int)fval; if ( (int)vval != (int)format ) { qLog(QAudioInput) << QString("format type not set, want %1 got %2") .arg(snd_pcm_format_name((snd_pcm_format_t)format)) .arg(snd_pcm_format_name((snd_pcm_format_t)vval)); format = (snd_pcm_format_t)vval; } qLog(QAudioInput) << QString("format = '%1' (%2)") .arg(snd_pcm_format_name((snd_pcm_format_t)vval)) .arg(snd_pcm_format_description((snd_pcm_format_t)vval)) .toLatin1().constData(); snd_pcm_hw_params_get_subformat(hwparams,&sval); vval = (unsigned int)sval; qLog(QAudioInput) << QString("subformat = '%1' (%2)") .arg(snd_pcm_subformat_name((snd_pcm_subformat_t)vval)) .arg(snd_pcm_subformat_description((snd_pcm_subformat_t)vval)) .toLatin1().constData(); snd_pcm_hw_params_get_channels(hwparams, &vval); if ( (int)vval != (int)channels ) { qLog(QAudioInput) << QString("channels type not set, want %1 got %2").arg(channels).arg(vval); channels = vval; } qLog(QAudioInput) << "channels = " << vval; snd_pcm_hw_params_get_rate(hwparams, &vval, &dir); if ( (int)vval != (int)frequency ) { qLog(QAudioInput) << QString("frequency type not set, want %1 got %2").arg(frequency).arg(vval); frequency = vval; } qLog(QAudioInput) << "rate =" << vval << " bps"; snd_pcm_hw_params_get_period_time(hwparams,&period_time, &dir); qLog(QAudioInput) << "period time =" << period_time << " us"; snd_pcm_hw_params_get_period_size(hwparams,&period_size, &dir); qLog(QAudioInput) << "period size =" << (int)period_size; snd_pcm_hw_params_get_buffer_time(hwparams,&buffer_time, &dir); qLog(QAudioInput) << "buffer time =" << buffer_time; snd_pcm_hw_params_get_buffer_size(hwparams,(snd_pcm_uframes_t *) &buffer_size); qLog(QAudioInput) << "buffer size =" << (int)buffer_size; snd_pcm_hw_params_get_periods(hwparams, &vval, &dir); qLog(QAudioInput) << "periods per buffer =" << vval; snd_pcm_hw_params_get_rate_numden(hwparams, &vval, &vval2); qLog(QAudioInput) << QString("exact rate = %1/%2 bps").arg(vval).arg(vval2).toLatin1().constData(); vval = snd_pcm_hw_params_get_sbits(hwparams); qLog(QAudioInput) << "significant bits =" << vval; snd_pcm_hw_params_get_tick_time(hwparams,&vval, &dir); qLog(QAudioInput) << "tick time =" << vval; vval = snd_pcm_hw_params_is_batch(hwparams); qLog(QAudioInput) << "is batch =" << vval; vval = snd_pcm_hw_params_is_block_transfer(hwparams); qLog(QAudioInput) << "is block transfer =" << vval; vval = snd_pcm_hw_params_is_double(hwparams); qLog(QAudioInput) << "is double =" << vval; vval = snd_pcm_hw_params_is_half_duplex(hwparams); qLog(QAudioInput) << "is half duplex =" << vval; vval = snd_pcm_hw_params_is_joint_duplex(hwparams); qLog(QAudioInput) << "is joint duplex =" << vval; vval = snd_pcm_hw_params_can_overrange(hwparams); qLog(QAudioInput) << "can overrange =" << vval; vval = snd_pcm_hw_params_can_mmap_sample_resolution(hwparams); qLog(QAudioInput) << "can mmap =" << vval; vval = snd_pcm_hw_params_can_pause(hwparams); qLog(QAudioInput) << "can pause =" << vval; vval = snd_pcm_hw_params_can_resume(hwparams); qLog(QAudioInput) << "can resume =" << vval; vval = snd_pcm_hw_params_can_sync_start(hwparams); qLog(QAudioInput) << "can sync start =" << vval; snd_pcm_sw_params_t *swparams; snd_pcm_sw_params_alloca(&swparams); err = snd_pcm_sw_params_current(handle, swparams); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_sw_params_current: err %d",err); } err = snd_pcm_sw_params_set_start_threshold(handle,swparams,period_size); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_sw_params_set_start_threshold: err %d",err); } err = snd_pcm_sw_params_set_avail_min(handle, swparams,period_size); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_sw_params_set_avail_min: err %d",err); } err = snd_pcm_sw_params_set_xfer_align(handle, swparams, 1); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_sw_params_set_xfer_align: err %d",err); } err = snd_pcm_sw_params(handle, swparams); if ( err < 0 ) { qWarning( "QAudioInput: snd_pcm_sw_params: err %d",err); } snd_pcm_prepare(handle); snd_pcm_start(handle); int count = snd_pcm_poll_descriptors_count(handle); pollfd *pfds = new pollfd[count]; snd_pcm_poll_descriptors(handle, pfds, count); for (int i = 0; i < count; ++i) { if ((pfds[i].events & POLLIN) != 0) { notifier = new QSocketNotifier(pfds[i].fd, QSocketNotifier::Read); QObject::connect(notifier, SIGNAL(activated(int)), input, SIGNAL(readyRead())); break; } } if (notifier == NULL) { rc = false; } delete pfds; } return rc; }
// input: ALSA void* input_alsa(void* data) { struct audio_data *audio = (struct audio_data *)data; signed char *buffer; snd_pcm_t *handle; snd_pcm_hw_params_t *params; unsigned int val; snd_pcm_uframes_t frames; val = 44100; int i, n, o, size, dir, err; int tempr, templ; int radj, ladj; // alsa: open device to capture audio if ((err = snd_pcm_open(&handle, audio-> source, SND_PCM_STREAM_CAPTURE, 0) < 0)) { fprintf(stderr, "error opening stream: %s\n", snd_strerror(err)); exit(EXIT_FAILURE); } #ifdef DEBUG else printf("open stream successful\n"); #endif snd_pcm_hw_params_alloca(¶ms); //assembling params snd_pcm_hw_params_any (handle, params); //setting defaults or something snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); //interleaved mode right left right left snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); //trying to set 16bit snd_pcm_hw_params_set_channels(handle, params, 2); //assuming stereo val = 44100; snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); //trying 44100 rate frames = 256; snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); //number of frames pr read err = snd_pcm_hw_params(handle, params); //attempting to set params if (err < 0) { fprintf(stderr, "unable to set hw parameters: %s\n", snd_strerror(err)); exit(EXIT_FAILURE); } snd_pcm_hw_params_get_format(params, (snd_pcm_format_t * )&val); //getting actual format //converting result to number of bits if (val < 6)audio->format = 16; else if (val > 5 && val < 10)audio->format = 24; else if (val > 9)audio->format = 32; snd_pcm_hw_params_get_rate(params, &audio->rate, &dir); //getting rate snd_pcm_hw_params_get_period_size(params, &frames, &dir); snd_pcm_hw_params_get_period_time(params, &val, &dir); size = frames * (audio->format / 8) * 2; // frames * bits/8 * 2 channels buffer = malloc(size); radj = audio->format / 4; //adjustments for interleaved ladj = audio->format / 8; o = 0; while (1) { err = snd_pcm_readi(handle, buffer, frames); if (err == -EPIPE) { /* EPIPE means overrun */ #ifdef DEBUG fprintf(stderr, "overrun occurred\n"); #endif snd_pcm_prepare(handle); } else if (err < 0) { #ifdef DEBUG fprintf(stderr, "error from read: %s\n", snd_strerror(err)); #endif } else if (err != (int)frames) { #ifdef DEBUG fprintf(stderr, "short read, read %d %d frames\n", err, (int)frames); #endif } //sorting out one channel and only biggest octet n = 0; //frame counter for (i = 0; i < size ; i = i + (ladj) * 2) { //first channel tempr = (buffer[i + (radj) - 1]); //other channel templ = (buffer[i + (ladj) - 1]); //first channel //using the 10 upper bits this would give me a vert res of 1024, enough... //tempr = ((buffer[i + (radj) - 1 ] << 2)); //lo = ((buffer[i + (radj) - 2] >> 6)); //if (lo < 0)lo = abs(lo) + 1; //if (tempr >= 0)tempr = tempr + lo; //if (tempr < 0)tempr = tempr - lo; //other channel //templ = (buffer[i + (ladj) - 1] << 2); //lo = (buffer[i + (ladj) - 2] >> 6); //if (lo < 0)lo = abs(lo) + 1; //if (templ >= 0)templ = templ + lo; //else templ = templ - lo; //mono: adding channels and storing it in the buffer if (audio->channels == 1) audio->audio_out_l[o] = (tempr + templ) / 2; //stereo storing channels in buffer if (audio->channels == 2) { audio->audio_out_l[o] = templ; audio->audio_out_r[o] = tempr; } //o++; //if (o == 2047) o = 0; o = (o + 1) % 2047; n++; } } }
main(int argc, char **argv){ snd_pcm_t *handle; snd_pcm_hw_params_t *params; snd_pcm_uframes_t frames; //the libsamplerate stuff SRC_DATA datastr;//holds the data(inpu and output),input frames used, output frames generated SRC_STATE *statestr;//holds the state int error; //the lbsndfile stuff, one keeps the header the other the data SF_INFO sfinf;//has all the info like total frames,samplerate, channels, mode SNDFILE *input = NULL; //buffers used in computation to pass to the playback function float *buffin = NULL;//float into the converter float *filein = NULL; float *flangebuffout = NULL;//float to traverse the array for getting flange effects float *flangebase = NULL;//float to fix the array for initialising the flange effects float *buffout = NULL;//float out of the converter short *final = NULL;//final array to write to snd card float fldelmax = 256; float flfreq = 1; float flgain = .5; int fltime = 0; int pcm, readcount, pcmrc, blah;//pcm is used for error checking the alsa stuff, pcmrc is used in the main loop float *eofin;//to point to the end of the file's raw data int tmp;//used to hold information that is printed in stdio int i = 0;//index for initialising the output DAC // float fldelmax, flgain, flfreq; // pointer for the file input if (argc != 3){ printf("Usage requires music file and src ratio, please try again\n\n"); return 0; } char *inputname = argv[1]; //int *filein = argv[1]; input = sf_open(inputname, SFM_READ, &sfinf); if (input == NULL){ printf("could not open file sorry \n\n"); return 0; } fprintf(stderr, "Channels : %d\n", sfinf.channels); fprintf(stderr, "Sample rate; %d\n", sfinf.samplerate); fprintf(stderr, "Sections: %d\n", sfinf.sections); fprintf(stderr, "Format: %d\n", sfinf.format); // fprintf(stderr, "Frame Count: %d\n", sfinf.frames); //fprintf(stderr, "size: %d\n", sizeof(short)); //open sndcard if ((filein = malloc(sizeof(float)*sfinf.channels*sfinf.frames)) == NULL) { printf("MAN YOU OUT OF MEM"); return 0; } blah = sf_readf_float(input, filein, sfinf.frames); buffin = filein; eofin = filein + (sfinf.frames)*sfinf.channels; if (pcm =snd_pcm_open(&handle, PCM_DEVICE, SND_PCM_STREAM_PLAYBACK, 0)< 0){ printf("Error: CANNOT OPEN PCM DEVICE\n"); } //allocate default parameters snd_pcm_hw_params_alloca(¶ms); snd_pcm_hw_params_any(handle, params); //set parameters if (pcm = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED)< 0){ printf("Cannot set interleaved mode\n"); } if (pcm = snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE)< 0){ printf("CANNOT SET FORMAT\n"); } if (pcm = snd_pcm_hw_params_set_channels(handle, params, sfinf.channels)< 0){ printf("CANNOT SET CHANNELS \n"); } if (pcm = snd_pcm_hw_params_set_rate(handle, params, sfinf.samplerate, 0)< 0){ printf("CANNOT SET SAMPLERATES \n"); } if (pcm = snd_pcm_hw_params_set_periods(handle, params,1024, 0) < 0){ printf("CANNOT SET PERIOD TO 128"); } //write parameters if (pcm = snd_pcm_hw_params(handle, params)< 0){ printf("CANNOT SET HARDWARE PARAMETERS\n"); } printf("PCm NAME: %s\n", snd_pcm_name(handle)); printf("PCM state: %s \n", snd_pcm_state_name(snd_pcm_state(handle))); snd_pcm_hw_params_get_channels(params, &tmp); printf("channels: %i\n", tmp); snd_pcm_hw_params_get_rate(params, &tmp, 0); printf("rate: %d \n", tmp); //find size of period on hardware snd_pcm_hw_params_get_period_size(params, &frames, 0); fprintf(stderr, "# frames in a period: %d\n", frames); //buffers on buffers (buffout for float output from sample rate conversion), (final for short array to write to pcm) and flangebse for the flanger stuff buffout = malloc(frames*sfinf.channels * sizeof(float));//frames final = malloc(frames*sfinf.channels * sizeof(short));//frames
bool AlsaLayer::alsa_set_params(snd_pcm_t *pcm_handle) { #define TRY(call, error) do { \ if (ALSA_CALL(call, error) < 0) \ return false; \ } while(0) snd_pcm_hw_params_t *hwparams; snd_pcm_hw_params_alloca(&hwparams); const unsigned SFL_ALSA_PERIOD_SIZE = 160; const unsigned SFL_ALSA_NB_PERIOD = 8; const unsigned SFL_ALSA_BUFFER_SIZE = SFL_ALSA_PERIOD_SIZE * SFL_ALSA_NB_PERIOD; snd_pcm_uframes_t period_size = SFL_ALSA_PERIOD_SIZE; snd_pcm_uframes_t buffer_size = SFL_ALSA_BUFFER_SIZE; unsigned int periods = SFL_ALSA_NB_PERIOD; snd_pcm_uframes_t period_size_min = 0; snd_pcm_uframes_t period_size_max = 0; snd_pcm_uframes_t buffer_size_min = 0; snd_pcm_uframes_t buffer_size_max = 0; #define HW pcm_handle, hwparams /* hardware parameters */ TRY(snd_pcm_hw_params_any(HW), "hwparams init"); TRY(snd_pcm_hw_params_set_access(HW, SND_PCM_ACCESS_RW_INTERLEAVED), "access type"); TRY(snd_pcm_hw_params_set_format(HW, SND_PCM_FORMAT_S16_LE), "sample format"); TRY(snd_pcm_hw_params_set_rate_resample(HW, 0), "hardware sample rate"); /* prevent software resampling */ TRY(snd_pcm_hw_params_set_rate_near(HW, &audioFormat_.sample_rate, nullptr), "sample rate"); // TODO: use snd_pcm_query_chmaps or similar to get hardware channel num audioFormat_.nb_channels = 2; TRY(snd_pcm_hw_params_set_channels_near(HW, &audioFormat_.nb_channels), "channel count"); snd_pcm_hw_params_get_buffer_size_min(hwparams, &buffer_size_min); snd_pcm_hw_params_get_buffer_size_max(hwparams, &buffer_size_max); snd_pcm_hw_params_get_period_size_min(hwparams, &period_size_min, nullptr); snd_pcm_hw_params_get_period_size_max(hwparams, &period_size_max, nullptr); DEBUG("Buffer size range from %lu to %lu", buffer_size_min, buffer_size_max); DEBUG("Period size range from %lu to %lu", period_size_min, period_size_max); buffer_size = buffer_size > buffer_size_max ? buffer_size_max : buffer_size; buffer_size = buffer_size < buffer_size_min ? buffer_size_min : buffer_size; period_size = period_size > period_size_max ? period_size_max : period_size; period_size = period_size < period_size_min ? period_size_min : period_size; TRY(snd_pcm_hw_params_set_buffer_size_near(HW, &buffer_size), "Unable to set buffer size for playback"); TRY(snd_pcm_hw_params_set_period_size_near(HW, &period_size, nullptr), "Unable to set period size for playback"); TRY(snd_pcm_hw_params_set_periods_near(HW, &periods, nullptr), "Unable to set number of periods for playback"); TRY(snd_pcm_hw_params(HW), "hwparams"); snd_pcm_hw_params_get_buffer_size(hwparams, &buffer_size); snd_pcm_hw_params_get_period_size(hwparams, &period_size, nullptr); snd_pcm_hw_params_get_rate(hwparams, &audioFormat_.sample_rate, nullptr); snd_pcm_hw_params_get_channels(hwparams, &audioFormat_.nb_channels); DEBUG("Was set period_size = %lu", period_size); DEBUG("Was set buffer_size = %lu", buffer_size); if (2 * period_size > buffer_size) { ERROR("buffer to small, could not use"); return false; } #undef HW DEBUG("%s using format %s", (snd_pcm_stream(pcm_handle) == SND_PCM_STREAM_PLAYBACK) ? "playback" : "capture", audioFormat_.toString().c_str() ); snd_pcm_sw_params_t *swparams = NULL; snd_pcm_sw_params_alloca(&swparams); #define SW pcm_handle, swparams /* software parameters */ snd_pcm_sw_params_current(SW); TRY(snd_pcm_sw_params_set_start_threshold(SW, period_size * 2), "start threshold"); TRY(snd_pcm_sw_params(SW), "sw parameters"); #undef SW return true; #undef TRY }
int main() { int rc; snd_pcm_t* handle; snd_pcm_hw_params_t* params; unsigned int val; unsigned int val2; int dir; snd_pcm_uframes_t frames; if ( (rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0) { std::cerr << "unable to open pcm devices: " << snd_strerror(rc) << std::endl; exit(1); } snd_pcm_hw_params_alloca(¶ms); snd_pcm_hw_params_any(handle, params); snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); snd_pcm_hw_params_set_channels(handle, params, 2); val = 44100; snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); if ( (rc = snd_pcm_hw_params(handle, params)) < 0) { std::cerr << "unable to set hw parameters: " << snd_strerror(rc) << std::endl; exit(1); } std::cout << "PCM handle name = " << snd_pcm_name(handle) << std::endl; std::cout << "PCM state = " << snd_pcm_state_name(snd_pcm_state(handle)) << std::endl; snd_pcm_hw_params_get_access(params, (snd_pcm_access_t *)&val); std::cout << "access type = " << snd_pcm_access_name((snd_pcm_access_t)val) << std::endl; snd_pcm_hw_params_get_format(params, (snd_pcm_format_t*)(&val)); std::cout << "format = '" << snd_pcm_format_name((snd_pcm_format_t)val) << "' (" << snd_pcm_format_description((snd_pcm_format_t)val) << ")" << std::endl; snd_pcm_hw_params_get_subformat(params, (snd_pcm_subformat_t *)&val); std::cout << "subformat = '" << snd_pcm_subformat_name((snd_pcm_subformat_t)val) << "' (" << snd_pcm_subformat_description((snd_pcm_subformat_t)val) << ")" << std::endl; snd_pcm_hw_params_get_channels(params, &val); std::cout << "channels = " << val << std::endl; snd_pcm_hw_params_get_rate(params, &val, &dir); std::cout << "rate = " << val << " bps" << std::endl; snd_pcm_hw_params_get_period_time(params, &val, &dir); std::cout << "period time = " << val << " us" << std::endl; snd_pcm_hw_params_get_period_size(params, &frames, &dir); std::cout << "period size = " << static_cast<int>(frames) << " frames" << std::endl; snd_pcm_hw_params_get_buffer_time(params, &val, &dir); std::cout << "buffer time = " << val << " us" << std::endl; snd_pcm_hw_params_get_buffer_size(params, (snd_pcm_uframes_t *) &val); std::cout << "buffer size = " << val << " frames" << std::endl; snd_pcm_hw_params_get_periods(params, &val, &dir); std::cout << "periods per buffer = " << val << " frames" << std::endl; snd_pcm_hw_params_get_rate_numden(params, &val, &val2); std::cout << "exact rate = " << val/val2 << " bps" << std::endl; val = snd_pcm_hw_params_get_sbits(params); std::cout << "significant bits = " << val << std::endl; snd_pcm_hw_params_get_tick_time(params, &val, &dir); std::cout << "tick time = " << val << " us" << std::endl; val = snd_pcm_hw_params_is_batch(params); std::cout << "is batch = " << val << std::endl; val = snd_pcm_hw_params_is_block_transfer(params); std::cout << "is block transfer = " << val << std::endl; val = snd_pcm_hw_params_is_double(params); std::cout << "is double = " << val << std::endl; val = snd_pcm_hw_params_is_half_duplex(params); std::cout << "is half duplex = " << val << std::endl; val = snd_pcm_hw_params_is_joint_duplex(params); std::cout << "is joint duplex = " << val << std::endl; val = snd_pcm_hw_params_can_overrange(params); std::cout << "can overrange = " << val << std::endl; val = snd_pcm_hw_params_can_mmap_sample_resolution(params); std::cout << "can mmap = " << val << std::endl; val = snd_pcm_hw_params_can_pause(params); std::cout << "can pause = " << val << std::endl; val = snd_pcm_hw_params_can_resume(params); std::cout << "can resume = " << val << std::endl; val = snd_pcm_hw_params_can_sync_start(params); std::cout << "can sync start = " << val << std::endl; snd_pcm_close(handle); return 0; }
static int alsaio_setup(t_alsa_dev *dev, int out, int *channels, int *rate, int nfrags, int frag_size) { int bufsizeforthis, err; snd_pcm_hw_params_t* hw_params; unsigned int tmp_uint; snd_pcm_uframes_t tmp_snd_pcm_uframes; if (sys_verbose) { if (out) post("configuring sound output..."); else post("configuring sound input..."); } /* set hardware parameters... */ snd_pcm_hw_params_alloca(&hw_params); /* get the default params */ err = snd_pcm_hw_params_any(dev->a_handle, hw_params); check_error(err, "snd_pcm_hw_params_any"); /* try to set interleaved access */ err = snd_pcm_hw_params_set_access(dev->a_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) return (-1); check_error(err, "snd_pcm_hw_params_set_access"); #if 0 /* enable this to print out which formats are available */ { int i; for (i = 0; i <= SND_PCM_FORMAT_LAST; i++) fprintf(stderr, "%d -> %d\n", i, snd_pcm_hw_params_test_format(dev->a_handle, hw_params, i)); } #endif /* Try to set 32 bit format first */ err = snd_pcm_hw_params_set_format(dev->a_handle, hw_params, SND_PCM_FORMAT_S32); if (err < 0) { /* fprintf(stderr, "PD-ALSA: 32 bit format not available - trying 24\n"); */ err = snd_pcm_hw_params_set_format(dev->a_handle, hw_params, SND_PCM_FORMAT_S24_3LE); if (err < 0) { /* fprintf(stderr, "PD-ALSA: 32/24 bit format not available - using 16\n"); */ err = snd_pcm_hw_params_set_format(dev->a_handle, hw_params, SND_PCM_FORMAT_S16); check_error(err, "snd_pcm_hw_params_set_format"); dev->a_sampwidth = 2; } else dev->a_sampwidth = 3; } else dev->a_sampwidth = 4; if (sys_verbose) post("Sample width set to %d bytes", dev->a_sampwidth); /* set the subformat */ err = snd_pcm_hw_params_set_subformat(dev->a_handle, hw_params, SND_PCM_SUBFORMAT_STD); check_error(err, "snd_pcm_hw_params_set_subformat"); /* set the number of channels */ tmp_uint = *channels; err = snd_pcm_hw_params_set_channels_min(dev->a_handle, hw_params, &tmp_uint); check_error(err, "snd_pcm_hw_params_set_channels"); if (tmp_uint != (unsigned)*channels) post("ALSA: set %s channels to %d", (out?"output":"input"), tmp_uint); *channels = tmp_uint; dev->a_channels = *channels; /* set the sampling rate */ err = snd_pcm_hw_params_set_rate_min(dev->a_handle, hw_params, (unsigned int *)rate, 0); check_error(err, "snd_pcm_hw_params_set_rate_min (input)"); #if 0 err = snd_pcm_hw_params_get_rate(hw_params, &subunitdir); post("input sample rate %d", err); #endif /* post("frag size %d, nfrags %d", frag_size, nfrags); */ /* set "period size" */ #ifdef ALSAAPI9 err = snd_pcm_hw_params_set_period_size_near(dev->a_handle, hw_params, (snd_pcm_uframes_t)frag_size, 0); #else tmp_snd_pcm_uframes = frag_size; err = snd_pcm_hw_params_set_period_size_near(dev->a_handle, hw_params, &tmp_snd_pcm_uframes, 0); #endif check_error(err, "snd_pcm_hw_params_set_period_size_near (input)"); /* set the buffer size */ #ifdef ALSAAPI9 err = snd_pcm_hw_params_set_buffer_size_near(dev->a_handle, hw_params, nfrags * frag_size); #else tmp_snd_pcm_uframes = nfrags * frag_size; err = snd_pcm_hw_params_set_buffer_size_near(dev->a_handle, hw_params, &tmp_snd_pcm_uframes); #endif check_error(err, "snd_pcm_hw_params_set_buffer_size_near (input)"); err = snd_pcm_hw_params(dev->a_handle, hw_params); check_error(err, "snd_pcm_hw_params (input)"); /* set up the buffer */ bufsizeforthis = DEFDACBLKSIZE * dev->a_sampwidth * *channels; if (alsa_snd_buf) { if (alsa_snd_bufsize < bufsizeforthis) { if (!(alsa_snd_buf = realloc(alsa_snd_buf, bufsizeforthis))) { post("out of memory"); return (0); } memset(alsa_snd_buf, 0, bufsizeforthis); alsa_snd_bufsize = bufsizeforthis; } } else { if (!(alsa_snd_buf = (void *)malloc(bufsizeforthis))) { post("out of memory"); return (0); } memset(alsa_snd_buf, 0, bufsizeforthis); alsa_snd_bufsize = bufsizeforthis; } return (1); }
int main(int argc, char **argv){ int i; int aver,val,val2; int16_t buf[BUFSIZE]; double d_buffer[BUFSIZE]; double pitch = 0.0; struct timespec before,after; struct pitch_tracker_params *settings; snd_pcm_uframes_t period_size = PERIOD_SIZE; //ALSA PCM configuration snd_pcm_t *handle; snd_pcm_hw_params_t *params; int dir,rc; snd_pcm_uframes_t frames; /* Open PCM device for capture */ rc = snd_pcm_open( &handle, "default" , SND_PCM_STREAM_CAPTURE , 0); if(rc < 0 ){ fprintf(stderr,"unable to open pcm device: %s\n",snd_strerror(rc)); exit(1); } /* Allocate a hardware parameters object. */ snd_pcm_hw_params_alloca(¶ms); /* Fill it in with default values. */ snd_pcm_hw_params_any(handle, params); /* Set the desired hardware parameters. */ /* Interleaved mode */ snd_pcm_hw_params_set_access(handle, params,SND_PCM_ACCESS_RW_INTERLEAVED); /* unsigned 16-bit format */ snd_pcm_hw_params_set_format(handle, params,SND_PCM_FORMAT_S16); snd_pcm_hw_params_set_channels(handle, params, 1); /* 44100 bits/second sampling rate */ val = 44100; snd_pcm_hw_params_set_rate_near(handle,params, &val, &dir); /* set size time*/ snd_pcm_hw_params_set_period_size_near(handle, params, &period_size , &dir); /* write configuration */ rc = snd_pcm_hw_params(handle,params); /*Display info*/ printf("PCM handle name = '%s'\n", snd_pcm_name(handle)); printf("PCM state = %s\n", snd_pcm_state_name(snd_pcm_state(handle))); snd_pcm_hw_params_get_access(params, (snd_pcm_access_t *) &val); printf("access type = %s\n", snd_pcm_access_name((snd_pcm_access_t)val)); snd_pcm_hw_params_get_format(params, &val); printf("format = '%s' (%s)\n", snd_pcm_format_name((snd_pcm_format_t)val), snd_pcm_format_description( (snd_pcm_format_t)val)); snd_pcm_hw_params_get_subformat(params, (snd_pcm_subformat_t *)&val); printf("subformat = '%s' (%s)\n", snd_pcm_subformat_name((snd_pcm_subformat_t)val), snd_pcm_subformat_description( (snd_pcm_subformat_t)val)); snd_pcm_hw_params_get_channels(params, &val); printf("channels = %d\n", val); snd_pcm_hw_params_get_rate(params, &val, &dir); printf("rate = %d bps\n", val); snd_pcm_hw_params_get_period_time(params, &val, &dir); printf("period time = %d us\n", val); snd_pcm_hw_params_get_period_size(params, &frames, &dir); printf("period size = %d frames\n", (int)frames); snd_pcm_hw_params_get_buffer_time(params, &val, &dir); printf("buffer time = %d us\n", val); snd_pcm_hw_params_get_buffer_size(params, (snd_pcm_uframes_t *) &val); printf("buffer size = %d frames\n", val); snd_pcm_hw_params_get_periods(params, &val, &dir); printf("periods per buffer = %d frames\n", val); snd_pcm_hw_params_get_rate_numden(params, &val, &val2); printf("exact rate = %d/%d bps\n", val, val2); val = snd_pcm_hw_params_get_sbits(params); printf("significant bits = %d\n", val); val = snd_pcm_hw_params_is_batch(params); printf("is batch = %d\n", val); val = snd_pcm_hw_params_is_block_transfer(params); printf("is block transfer = %d\n", val); val = snd_pcm_hw_params_is_double(params); printf("is double = %d\n", val); val = snd_pcm_hw_params_is_half_duplex(params); printf("is half duplex = %d\n", val); val = snd_pcm_hw_params_is_joint_duplex(params); printf("is joint duplex = %d\n", val); val = snd_pcm_hw_params_can_overrange(params); printf("can overrange = %d\n", val); val = snd_pcm_hw_params_can_mmap_sample_resolution(params); printf("can mmap = %d\n", val); val = snd_pcm_hw_params_can_pause(params); printf("can pause = %d\n", val); val = snd_pcm_hw_params_can_resume(params); printf("can resume = %d\n", val); val = snd_pcm_hw_params_can_sync_start(params); printf("can sync start = %d\n", val); settings = open_pitch_tracker(); while(1){ rc = snd_pcm_readi(handle, buf, frames); if (rc == -EPIPE) { /* EPIPE means overrun */ fprintf(stderr, "overrun occurred\n"); snd_pcm_prepare(handle); } else if (rc < 0) { fprintf(stderr, "error from read: %s\n", snd_strerror(rc)); } else if (rc != (int)frames) { fprintf(stderr, "short read, read %d frames\n", rc); } for( i = 0 ; i< BUFSIZE ; i++){ d_buffer[i] = (double) buf[i]; } pitch = compute_pitch(d_buffer, BUFSIZE, S16, settings ,ACCURACY); if( pitch != 0.0 ) printf("frequency -> %f\n",pitch); memset(buf,0,BUFSIZE); } close_pitch_tracker(&settings); snd_pcm_drain(handle); snd_pcm_close(handle); return 0; }
int alsa_hook_hw_params(alsa_hook_t alsa_hook, snd_pcm_t *pcm, snd_pcm_hw_params_t *params) { struct alsa_hook_stream_s *stream; snd_pcm_format_t format; snd_pcm_uframes_t period_size; snd_pcm_access_t access; int dir, ret; alsa_hook_get_stream(alsa_hook, pcm, &stream); if (unlikely((ret = alsa_hook_lock_write(alsa_hook, stream)))) return ret; glc_log(alsa_hook->glc, GLC_DEBUG, "alsa_hook", "%p: creating/updating configuration for stream %d", stream->pcm, stream->id); /* extract information */ if (unlikely((ret = snd_pcm_hw_params_get_format(params, &format)) < 0)) goto err; stream->flags = 0; /* zero flags */ stream->format = pcm_fmt_to_glc_fmt(format); if (unlikely(!stream->format)) { glc_log(alsa_hook->glc, GLC_ERROR, "alsa_hook", "%p: unsupported audio format 0x%02x", stream->pcm, format); ret = ENOTSUP; goto err; } if (unlikely((ret = snd_pcm_hw_params_get_rate(params, &stream->rate, &dir)) < 0)) goto err; if (unlikely((ret = snd_pcm_hw_params_get_channels(params, &stream->channels)) < 0)) goto err; if (unlikely((ret = snd_pcm_hw_params_get_period_size(params, &period_size, NULL)) < 0)) goto err; if (unlikely((ret = snd_pcm_hw_params_get_access(params, &access)) < 0)) goto err; if ((access == SND_PCM_ACCESS_RW_INTERLEAVED) || (access == SND_PCM_ACCESS_MMAP_INTERLEAVED)) stream->flags |= GLC_AUDIO_INTERLEAVED; else if (access == SND_PCM_ACCESS_MMAP_COMPLEX) { stream->flags |= GLC_AUDIO_INTERLEAVED; /* convert to interleaved */ stream->complex = 1; /* do conversion */ } else { glc_log(alsa_hook->glc, GLC_ERROR, "alsa_hook", "%p: unsupported access mode 0x%02x", stream->pcm, access); ret = ENOTSUP; goto err; } glc_log(alsa_hook->glc, GLC_DEBUG, "alsa_hook", "%p: %d channels, rate %d, flags 0x%02x", stream->pcm, stream->channels, stream->rate, stream->flags); stream->fmt = 1; if (alsa_hook->started) { if (unlikely((ret = alsa_hook_stream_init(alsa_hook, stream)))) goto err; } alsa_hook_unlock_write(alsa_hook, stream); return 0; err: glc_log(alsa_hook->glc, GLC_ERROR, "alsa_hook", "%p: can't extract hardware configuration: %s (%d)", stream->pcm, snd_strerror(ret), ret); alsa_hook_unlock_write(alsa_hook, stream); return ret; }
int main(int argc, char ** argv) { // Variable declaration int rc; char * buffer; int buffer_size; int periods_per_buffer; snd_pcm_t *handle; snd_pcm_hw_params_t *params; snd_pcm_uframes_t frames; unsigned int channels; unsigned int rate; wav_header * wav_header_info; FILE * fp; // Argument parsing if (argc != 2) { printf("Incorrect usage: Enter filename of the wav file you want to play as an argument: %s filename.txt\n", argv[0]); return 1; } // Open wav file to read fp = fopen(argv[1], "rb"); if (fp == NULL) { printf("ERROR: %s does not exist, or cannot be opened.\n", argv[1]); return 1; } wav_header_info = malloc(44); fread(wav_header_info, 1, 44, fp); // print_wav_header(wav_header_info); // Assign variables that were read from the wave file channels = wav_header_info->number_of_channels; rate = wav_header_info->sample_rate; periods_per_buffer = 2; // Down to user preference, depending on size of internal ring buffer of ALSA // Open PCM device for playback if ((rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0) { printf("ERROR: Cannot open pcm device. %s\n", snd_strerror(rc)); } // Allocate hardware parameters if ((rc = snd_pcm_hw_params_malloc(¶ms)) < 0) { printf("ERROR: Cannot allocate hardware parameters. %s\n", snd_strerror(rc)); } // Initialize parameters with default values if ((rc = snd_pcm_hw_params_any(handle, params)) < 0) { printf("ERROR: Cannot initialize hardware parameters. %s\n", snd_strerror(rc)); } // Setting hardware parameters if ((rc = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { printf("ERROR: Cannot set interleaved mode. %s\n", snd_strerror(rc)); } if ((rc = snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE)) < 0) { printf("ERROR: Cannot set PCM format. %s\n", snd_strerror(rc)); } if ((rc = snd_pcm_hw_params_set_channels_near(handle, params, &channels)) < 0) { printf("ERROR: Cannot set number of channels. %s\n", snd_strerror(rc)); } if ((rc = snd_pcm_hw_params_set_rate_near(handle, params, &rate, 0)) < 0) { printf("ERROR: Cannot set plyabck rate. %s\n", snd_strerror(rc)); } if ((rc = snd_pcm_hw_params(handle, params)) < 0) { printf("ERROR: Cannot set hardware parameters. %s\n", snd_strerror(rc)); } // Get hardware parameters if ((rc = snd_pcm_hw_params_get_period_size(params, &frames, 0)) < 0) { printf("Playback ERROR: Can't get period size. %s\n", snd_strerror(rc)); } printf("Frames: %lu\n", frames); if ((rc = snd_pcm_hw_params_get_channels(params, &channels)) < 0) { printf("Playback ERROR: Can't get channel number. %s\n", snd_strerror(rc)); } if ((rc = snd_pcm_hw_params_get_rate(params, &rate, 0)) < 0) { printf("ERROR: Cannot get rate. %s\n", snd_strerror(rc)); } // Free paraemeters snd_pcm_hw_params_free(params); // Create buffer buffer_size = frames * periods_per_buffer * channels * sizeof(int16_t); /* 2 bytes/sample, 2 channels */ buffer = (char *) malloc(buffer_size); // Send info to ALSA //while ((rc = read(0, buffer, buffer_size)) != 0) while (rc = fread(buffer, 1, periods_per_buffer * frames * channels * sizeof(int16_t), fp) != 0) { rc = snd_pcm_writei(handle, buffer, frames * periods_per_buffer); if (rc == -EPIPE) { fprintf(stderr, "underrun occurred\n"); snd_pcm_prepare(handle); } else if (rc < 0) { printf("ERROR: Cannot write to playback device. %s\n", strerror(rc)); } } printf("Info set: Device is now draining...\n"); snd_pcm_drain(handle); printf("Done playing, closing connections.\n"); snd_pcm_close(handle); free(wav_header_info); free(buffer); fclose(fp); return 0; }
static int set_params(AudioDevice *ad, AudioFormat *format_p, int *ch_p, unsigned int *rate_p) { ALSA_data *alsa = (ALSA_data *)ad->private_data; int r, err; snd_pcm_format_t f; AudioFormat format = *format_p; snd_pcm_hw_params_t *hwparams; snd_pcm_sw_params_t *swparams; int ch = *ch_p; unsigned int rate = *rate_p; unsigned int buffer, period; snd_pcm_hw_params_alloca(&hwparams); snd_pcm_sw_params_alloca(&swparams); ad->format = _AUDIO_FORMAT_UNSET; *format_p = _AUDIO_FORMAT_UNSET; *ch_p = 0; *rate_p = 0; /* format part */ switch (format) { case _AUDIO_FORMAT_MU_LAW: f = SND_PCM_FORMAT_MU_LAW; break; case _AUDIO_FORMAT_A_LAW: f = SND_PCM_FORMAT_A_LAW; break; case _AUDIO_FORMAT_ADPCM: f = SND_PCM_FORMAT_IMA_ADPCM; break; case _AUDIO_FORMAT_U8: f = SND_PCM_FORMAT_U8; break; case _AUDIO_FORMAT_S8: f = SND_PCM_FORMAT_S8; break; case _AUDIO_FORMAT_U16_LE: f = SND_PCM_FORMAT_U16_LE; break; case _AUDIO_FORMAT_U16_BE: f = SND_PCM_FORMAT_U16_BE; break; case _AUDIO_FORMAT_S16_LE: f = SND_PCM_FORMAT_S16_LE; break; case _AUDIO_FORMAT_S16_BE: f = SND_PCM_FORMAT_S16_BE; break; #if 0 case _AUDIO_FORMAT_S32_LE: f = SND_PCM_FORMAT_U32_LE; break; case _AUDIO_FORMAT_S32_BE: f = SND_PCM_FORMAT_S32_BE; break; #endif default: show_message_fnc("format %d is invalid.\n", format); return 0; } if ((err = snd_pcm_hw_params_any(alsa->fd, hwparams)) < 0) { show_message_fnc("snd_pcm_hw_params_any() failed.\n"); return 0; } if ((err = snd_pcm_hw_params_set_access(alsa->fd, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { show_message_fnc("snd_pcm_hw_params_set_access() failed.\n"); return 0; } if ((err = snd_pcm_hw_params_set_format(alsa->fd, hwparams, f)) < 0) { show_message_fnc("snd_pcm_hw_params_set_format() failed.\n"); return 0; } ad->format = format; *format_p = format; /* channel part */ if ((err = snd_pcm_hw_params_set_channels(alsa->fd, hwparams, ch)) < 0) { show_message_fnc("snd_pcm_hw_params_set_channels() failed.\n"); return 0; } *ch_p = ch; /* rate part */ if ((err = snd_pcm_hw_params_set_rate_near(alsa->fd, hwparams, &rate, 0)) < 0) { show_message_fnc("snd_pcm_hw_params_set_rate_near() failed.\n"); return 0; } *rate_p = rate; /* buffer & period */ buffer = 500000; period = 500000 / 4; if ((err = snd_pcm_hw_params_set_buffer_time_near(alsa->fd, hwparams, &buffer, 0)) < 0) { show_message_fnc("snd_pcm_hw_params_set_buffer_near() failed.\n"); return 0; } r = snd_pcm_hw_params_get_buffer_size(hwparams, &alsa->buffer_size); if ((err = snd_pcm_hw_params_set_period_time_near(alsa->fd, hwparams, &period, 0)) < 0) { show_message_fnc("snd_pcm_hw_params_set_period_near() failed.\n"); return 0; } r = snd_pcm_hw_params_get_period_size(hwparams, &alsa->period_size, 0); if ((err = snd_pcm_hw_params(alsa->fd, hwparams)) < 0) { perror("snd_pcm_hw_params"); err_message_fnc("snd_pcm_hw_params() failed.\n"); snd_pcm_hw_params_dump(hwparams, alsa->log); return 0; } r = snd_pcm_hw_params_get_channels(hwparams, &ad->channels); r = snd_pcm_hw_params_get_rate(hwparams, &ad->speed, 0); r = r; // dummy #ifdef DEBUG { snd_pcm_format_t form; debug_message_fnc("format "); r = snd_pcm_hw_params_get_format(hwparams, &form); switch (form) { case SND_PCM_FORMAT_MU_LAW: debug_message("MU_LAW "); break; case SND_PCM_FORMAT_A_LAW: debug_message("A_LAW "); break; case SND_PCM_FORMAT_IMA_ADPCM: debug_message("ADPCM "); break; case SND_PCM_FORMAT_U8: debug_message("U8 "); break; case SND_PCM_FORMAT_S8: debug_message("S8 "); break; case SND_PCM_FORMAT_U16_LE: debug_message("U16LE "); break; case SND_PCM_FORMAT_U16_BE: debug_message("U16BE "); break; case SND_PCM_FORMAT_S16_LE: debug_message("S16LE "); break; case SND_PCM_FORMAT_S16_BE: debug_message("S16BE "); break; #if 0 case SND_PCM_FORMAT_U32_LE: debug_message("U32LE "); break; case SND_PCM_FORMAT_S32_BE: debug_message("S32BE "); break; #endif default: debug_message("UNKNOWN "); break; } debug_message("%d ch %d Hz buffer %ld period %ld OK\n", ad->channels, ad->speed, alsa->buffer_size, alsa->period_size); } #endif /* sw_params */ if ((err = snd_pcm_sw_params_current(alsa->fd, swparams)) < 0) { show_message_fnc("snd_pcm_sw_params_any() failed.\n"); return 0; } if ((err = snd_pcm_sw_params(alsa->fd, swparams)) < 0) { show_message_fnc("snd_pcm_sw_params() failed.\n"); return 0; } debug_message_fnc("1 sample -> %ld bytes\n", snd_pcm_samples_to_bytes(alsa->fd, 1)); return 1; }
int VPOutPluginAlsa::init(VPlayer *v, VPBuffer *in) { DBG("Alsa:init"); owner = v; bin = in; if (snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NO_AUTO_RESAMPLE) < 0){ DBG("Alsa:init: failed to open pcm"); exit(0); return -1; } snd_pcm_sw_params_t *swparams; snd_pcm_sw_params_malloc(&swparams); snd_pcm_sw_params_current (handle, swparams); snd_pcm_sw_params_set_start_threshold (handle, swparams, VPBUFFER_FRAMES - PERIOD_SIZE); snd_pcm_sw_params (handle, swparams); snd_pcm_sw_params_free(swparams); snd_pcm_hw_params_alloca(¶ms); snd_pcm_hw_params_any(handle, params); snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); snd_pcm_format_mask_t *mask; snd_pcm_format_mask_alloca(&mask); snd_pcm_hw_params_get_format_mask(params, mask); if (snd_pcm_format_mask_test(mask, SND_PCM_FORMAT_S32)) { DBG("bit depth is 32"); snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S32); multiplier = (1<<31) -1 ; DBG(multiplier); } else if (snd_pcm_format_mask_test(mask, SND_PCM_FORMAT_S24)) { DBG("bit depth is 24"); snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S24); multiplier = (1<<23) -1; } else if (snd_pcm_format_mask_test(mask, SND_PCM_FORMAT_S16)) { DBG("bit depth is 16"); snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16); multiplier = (1<<15) -1; } else if (snd_pcm_format_mask_test(mask, SND_PCM_FORMAT_S8)) { DBG("bit depth is 8"); snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S8); multiplier = (1<<7) -1;; } snd_pcm_hw_params_set_channels(handle, params, bin->chans); snd_pcm_hw_params_set_period_size(handle, params, PERIOD_SIZE, 0); if (snd_pcm_hw_params(handle, params) < 0) { DBG("Alsa:init: failed to set pcm params"); return -1; } snd_pcm_hw_params_current(handle, params); int dir; snd_pcm_hw_params_get_rate(params, &out_srate, &dir); in_srate = bin->srate; int rerr; rs = src_new(SRC_SINC_FASTEST, bin->chans, &rerr); if (!rs){ DBG("SRC error"<<rerr); return -1; } rd.src_ratio = (out_srate*1.0)/(in_srate*1.0); out_frames = (VPBUFFER_FRAMES*rd.src_ratio)*2; out_buf = (float *)ALIGNED_ALLOC(sizeof(float)*out_frames*bin->chans); out_buf_i = (int *)ALIGNED_ALLOC(sizeof(int)*out_frames*bin->chans); DBG("target rate "<<out_srate); work = true; paused = false; pause_check = false; FULL_MEMORY_BARRIER; in_fd = inotify_init(); if ( in_fd < 0 ) { DBG("error initializing inotify, auto pause won't work"); } else { in_wd[0]=inotify_add_watch( in_fd, "/dev/snd/pcmC0D0p", IN_OPEN | IN_CLOSE ); } fcntl(in_fd, F_SETFL, O_NONBLOCK); worker = new std::thread((void(*)(void*))worker_run, this); worker->high_priority(); DBG("alsa thread made"); DBG((void *)VPOutPluginAlsa::check_contention); VPEvents::getSingleton()->schedulerAddJob((VPEvents::VPJob) VPOutPluginAlsa::check_contention, this,0); return 0; }
int main() { int rc; snd_pcm_t *handle; snd_pcm_hw_params_t *params; unsigned int val, val2; int dir; snd_pcm_uframes_t frames; /* Open PCM device for playback. */ rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0); if (rc < 0) { fprintf(stderr, "unable to open pcm device: %s\n", snd_strerror(rc)); exit(1); } /* Allocate a hardware parameters object. */ snd_pcm_hw_params_alloca(¶ms); /* Fill it in with default values. */ snd_pcm_hw_params_any(handle, params); /* Set the desired hardware parameters. */ /* Interleaved mode */ snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); /* Signed 16-bit little-endian format */ snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); /* Two channels (stereo) */ snd_pcm_hw_params_set_channels(handle, params, 2); /* 44100 bits/second sampling rate (CD quality) */ val = 44100; snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); /* Write the parameters to the driver */ rc = snd_pcm_hw_params(handle, params); if (rc < 0) { fprintf(stderr, "unable to set hw parameters: %s\n", snd_strerror(rc)); exit(1); } /* Display information about the PCM interface */ printf("PCM handle name = '%s'\n", snd_pcm_name(handle)); printf("PCM state = %s\n", snd_pcm_state_name(snd_pcm_state(handle))); snd_pcm_hw_params_get_access(params, (snd_pcm_access_t *) &val); printf("access type = %s\n", snd_pcm_access_name((snd_pcm_access_t)val)); snd_pcm_hw_params_get_format(params, &val); printf("format = '%s' (%s)\n", snd_pcm_format_name((snd_pcm_format_t)val), snd_pcm_format_description( (snd_pcm_format_t)val)); snd_pcm_hw_params_get_subformat(params, (snd_pcm_subformat_t *)&val); printf("subformat = '%s' (%s)\n", snd_pcm_subformat_name((snd_pcm_subformat_t)val), snd_pcm_subformat_description( (snd_pcm_subformat_t)val)); snd_pcm_hw_params_get_channels(params, &val); printf("channels = %d\n", val); snd_pcm_hw_params_get_rate(params, &val, &dir); printf("rate = %d bps\n", val); snd_pcm_hw_params_get_period_time(params, &val, &dir); printf("period time = %d us\n", val); snd_pcm_hw_params_get_period_size(params, &frames, &dir); printf("period size = %d frames\n", (int)frames); snd_pcm_hw_params_get_buffer_time(params, &val, &dir); printf("buffer time = %d us\n", val); snd_pcm_hw_params_get_buffer_size(params, (snd_pcm_uframes_t *) &val); printf("buffer size = %d frames\n", val); snd_pcm_hw_params_get_periods(params, &val, &dir); printf("periods per buffer = %d frames\n", val); snd_pcm_hw_params_get_rate_numden(params, &val, &val2); printf("exact rate = %d/%d bps\n", val, val2); val = snd_pcm_hw_params_get_sbits(params); printf("significant bits = %d\n", val); snd_pcm_hw_params_get_tick_time(params, &val, &dir); printf("tick time = %d us\n", val); val = snd_pcm_hw_params_is_batch(params); printf("is batch = %d\n", val); val = snd_pcm_hw_params_is_block_transfer(params); printf("is block transfer = %d\n", val); val = snd_pcm_hw_params_is_double(params); printf("is double = %d\n", val); val = snd_pcm_hw_params_is_half_duplex(params); printf("is half duplex = %d\n", val); val = snd_pcm_hw_params_is_joint_duplex(params); printf("is joint duplex = %d\n", val); val = snd_pcm_hw_params_can_overrange(params); printf("can overrange = %d\n", val); val = snd_pcm_hw_params_can_mmap_sample_resolution(params); printf("can mmap = %d\n", val); val = snd_pcm_hw_params_can_pause(params); printf("can pause = %d\n", val); val = snd_pcm_hw_params_can_resume(params); printf("can resume = %d\n", val); val = snd_pcm_hw_params_can_sync_start(params); printf("can sync start = %d\n", val); snd_pcm_close(handle); return 0; }
int main() { 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; }
int main( int argc, char *argv[] ) { struct structArgs cmdArgs; unsigned int val, val2; int dir; int errNum; cmdArgs.card = 0; // Default card. cmdArgs.control = 1; // Default control. // ************************************************************************ // ALSA control elements. // ************************************************************************ snd_pcm_t *pcmp; snd_pcm_hw_params_t *params; // snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK; snd_pcm_stream_t stream = SND_PCM_STREAM_CAPTURE; snd_pcm_uframes_t frames; // ************************************************************************ // Get command line parameters. // ************************************************************************ argp_parse( &argp, argc, argv, 0, 0, &cmdArgs ); printf( "Card = %i\n", cmdArgs.card ); printf( "Control = %i\n", cmdArgs.control ); sprintf( cmdArgs.deviceID, "hw:%i,%i", cmdArgs.card, cmdArgs.control ); printf( "Using device %s :", cmdArgs.deviceID ); /* Allocate a hardware parameters object. */ if ( snd_pcm_hw_params_alloca( ¶ms ) < 0 ) { fprintf( stderr, "Unable to allocate.\n" ); return -1; } /* Open PCM device for playback. */ // if ( snd_pcm_open( &pcmp, cmdArgs.deviceID, stream, 0 ) < 0 ) // { // fprintf( stderr, "Unable to open pcm device.\n" ); // return -1; // } /* Fill it in with default values. */ // if ( snd_pcm_hw_params_any( pcmp, params ) < 0 // { // fprintf( stderr, "Unable to set default values.\n" ); // return -1; // } /* Interleaved mode */ // snd_pcm_hw_params_set_access( pcmp, params, // SND_PCM_ACCESS_RW_INTERLEAVED ); /* Signed 16-bit little-endian format */ snd_pcm_hw_params_set_format( pcmp, params, SND_PCM_FORMAT_S16_LE ); /* Two channels (stereo) */ snd_pcm_hw_params_set_channels( pcmp, params, 2 ); /* 44100 bits/second sampling rate (CD quality) */ val = 44100; snd_pcm_hw_params_set_rate_near( pcmp, params, &val, &dir ); /* Write the parameters to the driver */ errNum = snd_pcm_hw_params( pcmp, params ); if ( errNum < 0 ) { fprintf(stderr, "unable to set hw parameters: %s\n", snd_strerror( errNum )); exit( 1 ); } /* Display information about the PCM interface */ printf( "PCM handle name = '%s'\n", snd_pcm_name( pcmp )); printf("PCM state = %s\n", snd_pcm_state_name( snd_pcm_state( pcmp ))); snd_pcm_hw_params_get_access( params, ( snd_pcm_access_t * ) &val ); printf( "access type = %s\n", snd_pcm_access_name(( snd_pcm_access_t ) val )); snd_pcm_hw_params_get_format( params, ( snd_pcm_format_t * ) &val ); printf( "format = '%s' (%s)\n", snd_pcm_format_name(( snd_pcm_format_t ) val ), snd_pcm_format_description(( snd_pcm_format_t ) val )); snd_pcm_hw_params_get_subformat( params, ( snd_pcm_subformat_t * ) &val ); printf( "subformat = '%s' (%s)\n", snd_pcm_subformat_name(( snd_pcm_subformat_t ) val ), snd_pcm_subformat_description(( snd_pcm_subformat_t ) val )); snd_pcm_hw_params_get_channels( params, &val ); printf( "channels = %d\n", val ); snd_pcm_hw_params_get_rate( params, &val, &dir ); printf( "rate = %d bps\n", val ); snd_pcm_hw_params_get_period_time( params, &val, &dir ); printf( "period time = %d us\n", val ); snd_pcm_hw_params_get_period_size( params, &frames, &dir ); printf( "period size = %d frames\n", ( int ) frames ); snd_pcm_hw_params_get_buffer_time( params, &val, &dir ); printf( "buffer time = %d us\n", val ); snd_pcm_hw_params_get_buffer_size( params, ( snd_pcm_uframes_t * ) &val ); printf( "buffer size = %d frames\n", val ); snd_pcm_hw_params_get_periods( params, &val, &dir ); printf( "periods per buffer = %d frames\n", val ); snd_pcm_hw_params_get_rate_numden( params, &val, &val2 ); printf( "exact rate = %d/%d bps\n", val, val2 ); val = snd_pcm_hw_params_get_sbits( params ); printf( "significant bits = %d\n", val ); // snd_pcm_hw_params_get_tick_time( params, &val, &dir ); // printf( "tick time = %d us\n", val ); val = snd_pcm_hw_params_is_batch( params ); printf( "is batch = %d\n", val ); val = snd_pcm_hw_params_is_block_transfer( params ); printf( "is block transfer = %d\n", val ); val = snd_pcm_hw_params_is_double( params ); printf( "is double = %d\n", val ); val = snd_pcm_hw_params_is_half_duplex( params ); printf( "is half duplex = %d\n", val ); val = snd_pcm_hw_params_is_joint_duplex( params ); printf( "is joint duplex = %d\n", val ); val = snd_pcm_hw_params_can_overrange( params ); printf( "can overrange = %d\n", val ); val = snd_pcm_hw_params_can_mmap_sample_resolution( params ); printf( "can mmap = %d\n", val ); val = snd_pcm_hw_params_can_pause( params ); printf( "can pause = %d\n", val ); val = snd_pcm_hw_params_can_resume( params ); printf( "can resume = %d\n", val ); val = snd_pcm_hw_params_can_sync_start( params ); printf( "can sync start = %d\n", val ); snd_pcm_close( pcmp ); return 0; }
int main() { 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; }
bool open() { // Open the Alsa playback device. int err=-1,count=0; unsigned int freakuency = frequency; while((count < 5) && (err < 0)) { err = snd_pcm_open ( &handle, ALSA_OUTPUT_NAME, SND_PCM_STREAM_PLAYBACK, 0 ); if(err < 0) { count++; qWarning()<<"QAudioOutput::open() err="<<err<<", count="<<count; } } if (( err < 0)||(handle == 0)) { qWarning( "QAudioOuput: snd_pcm_open: error %d", err ); return false; } snd_pcm_nonblock( handle, 0 ); // Set the desired HW parameters. snd_pcm_hw_params_t *hwparams; snd_pcm_hw_params_alloca( &hwparams ); err = snd_pcm_hw_params_any( handle, hwparams ); if ( err < 0 ) { qWarning( "QAudioOutput: snd_pcm_hw_params_any: err %d", err); return false; } err = snd_pcm_hw_params_set_access( handle, hwparams, access ); if ( err < 0 ) { qWarning( "QAudioOutput: snd_pcm_hw_params_set_access: err %d", err); return false; } err = snd_pcm_hw_params_set_format( handle, hwparams, ( bitsPerSample == 16 ? SND_PCM_FORMAT_S16 : SND_PCM_FORMAT_U8 ) ); if ( err < 0 ) { qWarning( "QAudioOutput: snd_pcm_hw_params_set_format: err %d", err); return false; } err = snd_pcm_hw_params_set_channels ( handle, hwparams, (unsigned int)channels ); if ( err < 0 ) { qWarning( "QAudioOutput: snd_pcm_hw_params_set_channels: err %d", err); return false; } err = snd_pcm_hw_params_set_rate_near ( handle, hwparams, &freakuency, 0 ); if ( err < 0 ) { qWarning( "QAudioOutput: snd_pcm_hw_params_set_rate_near: err %d", err); return false; } #ifndef ALSA_BUFFER_SIZE err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, 0); if ( err < 0 ) { qWarning( "QAudioOutput: snd_pcm_hw_params_set_buffer_time_near: err %d",err); } err = snd_pcm_hw_params_get_buffer_size(hwparams, &buffer_size); if ( err < 0 ) { qWarning( "QAudioOutput: snd_pcm_hw_params_get_buffer_size: err %d",err); } #else buffer_size = ALSA_BUFFER_SIZE; err = snd_pcm_hw_params_set_buffer_size_near(handle, hwparams, &buffer_size); if ( err < 0 ) { qWarning( "QAudioOutput: snd_pcm_hw_params_set_buffer_time_near: err %d",err); } #endif #ifndef ALSA_PERIOD_SIZE period_time = buffer_time/4; err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, 0); if ( err < 0 ) { qWarning( "QAudioOutput: snd_pcm_hw_params_set_period_time_near: err %d",err); } #else period_size = ALSA_PERIOD_SIZE; err = snd_pcm_hw_params_set_period_size_near(handle, hwparams, &period_size, 0); if ( err < 0 ) { qWarning( "QAudioOutput: snd_pcm_hw_params_set_period_size_near: err %d",err); } #endif err = snd_pcm_hw_params(handle, hwparams); if ( err < 0 ) { qWarning( "QAudioOutput: snd_pcm_hw_params: err %d", err); return false; } int dir; unsigned int vval, vval2; snd_pcm_access_t val; snd_pcm_format_t fval; snd_pcm_subformat_t sval; qLog(QAudioOutput) << "PCM handle name =" << snd_pcm_name(handle); qLog(QAudioOutput) << "PCM state =" << snd_pcm_state_name(snd_pcm_state(handle)); snd_pcm_hw_params_get_access(hwparams,&val); vval = (unsigned int)val; if ( (int)vval != (int)access ) { qWarning( "QAudioInput: access type not set, want %s got %s", snd_pcm_access_name((snd_pcm_access_t)access), snd_pcm_access_name((snd_pcm_access_t)vval) ); access = (snd_pcm_access_t)vval; } qLog(QAudioOutput) << "access type =" << snd_pcm_access_name((snd_pcm_access_t)vval); snd_pcm_hw_params_get_format(hwparams, &fval); vval = (unsigned int)fval; if ( (int)vval != (int)format ) { qWarning( "QAudioInput: format type not set, want %s got %s", snd_pcm_format_name((snd_pcm_format_t)format), snd_pcm_format_name((snd_pcm_format_t)vval) ); format = (snd_pcm_format_t)vval; } qLog(QAudioOutput) << QString("format = '%1' (%2)").arg(snd_pcm_format_name((snd_pcm_format_t)vval)) .arg(snd_pcm_format_description((snd_pcm_format_t)vval)) .toLatin1().constData(); snd_pcm_hw_params_get_subformat(hwparams,&sval); vval = (unsigned int)sval; qLog(QAudioOutput) << QString("subformat = '%1' (%2)").arg(snd_pcm_subformat_name((snd_pcm_subformat_t)vval)) .arg(snd_pcm_subformat_description((snd_pcm_subformat_t)vval)) .toLatin1().constData(); snd_pcm_hw_params_get_channels(hwparams, &vval); if ( (int)vval != (int)channels ) { qWarning( "QAudioInput: channels type not set, want %d got %d",channels,vval); channels = vval; } qLog(QAudioOutput) << "channels =" << vval; snd_pcm_hw_params_get_rate(hwparams, &vval, &dir); if ( (int)vval != (int)frequency ) { qWarning( "QAudioInput: frequency type not set, want %d got %d",frequency,vval); frequency = vval; } qLog(QAudioOutput) << "rate =" << vval << "bps"; snd_pcm_hw_params_get_period_time(hwparams,&period_time, &dir); qLog(QAudioOutput) << "period time =" << period_time << "us"; snd_pcm_hw_params_get_period_size(hwparams,&period_size, &dir); qLog(QAudioOutput) << "period size =" << (int)period_size << "frames"; qLog(QAudioOutput) << "buffer time =" << (int)buffer_time << "us"; qLog(QAudioOutput) << "buffer size =" << (int)buffer_size << "frames"; snd_pcm_hw_params_get_periods(hwparams, &vval, &dir); periods = vval; qLog(QAudioOutput) << "periods per buffer =" << vval << "frames"; snd_pcm_hw_params_get_rate_numden(hwparams, &vval, &vval2); qLog(QAudioOutput) << QString("exact rate = %1/%2 bps").arg(vval).arg(vval2).toLatin1().constData(); vval = snd_pcm_hw_params_get_sbits(hwparams); qLog(QAudioOutput) << "significant bits =" << vval; vval = snd_pcm_hw_params_is_batch(hwparams); qLog(QAudioOutput) << "is batch =" << vval; vval = snd_pcm_hw_params_is_block_transfer(hwparams); qLog(QAudioOutput) << "is block transfer =" << vval; vval = snd_pcm_hw_params_is_double(hwparams); qLog(QAudioOutput) << "is double =" << vval; vval = snd_pcm_hw_params_is_half_duplex(hwparams); qLog(QAudioOutput) << "is half duplex =" << vval; vval = snd_pcm_hw_params_is_joint_duplex(hwparams); qLog(QAudioOutput) << "is joint duplex =" << vval; vval = snd_pcm_hw_params_can_overrange(hwparams); qLog(QAudioOutput) << "can overrange =" << vval; vval = snd_pcm_hw_params_can_mmap_sample_resolution(hwparams); qLog(QAudioOutput) << "can mmap =" << vval; vval = snd_pcm_hw_params_can_pause(hwparams); qLog(QAudioOutput) << "can pause =" << vval; vval = snd_pcm_hw_params_can_resume(hwparams); qLog(QAudioOutput) << "can resume =" << vval; vval = snd_pcm_hw_params_can_sync_start(hwparams); qLog(QAudioOutput) << "can sync start =" << vval; // Set the desired SW parameters. snd_pcm_sw_params_t *swparams; snd_pcm_sw_params_alloca(&swparams); err = snd_pcm_sw_params_current(handle, swparams); if ( err < 0 ) { qWarning( "QAudioOutput: snd_pcm_sw_params_current: err %d",err); } err = snd_pcm_sw_params_set_start_threshold(handle,swparams,buffer_size); if ( err < 0 ) { qWarning( "QAudioOutput: snd_pcm_sw_params_set_start_threshold: err %d",err); } err = snd_pcm_sw_params_set_stop_threshold(handle,swparams,buffer_size); if ( err < 0 ) { qWarning( "QAudioOutput: snd_pcm_sw_params_set_stop_threshold: err %d",err); } err = snd_pcm_sw_params_set_avail_min(handle, swparams,period_size); if ( err < 0 ) { qWarning( "QAudioOutput: snd_pcm_sw_params_set_avail_min: err %d",err); } err = snd_pcm_sw_params(handle, swparams); if ( err < 0 ) { qWarning( "QAudioOutput: snd_pcm_sw_params: err %d",err); } // Prepare for audio output. snd_pcm_prepare( handle ); return true; }
static int bluetooth_a2dp_init(struct bluetooth_data *data, snd_pcm_hw_params_t *params) { struct bluetooth_alsa_config *cfg = &data->alsa_config; sbc_capabilities_t *cap = &data->a2dp.sbc_capabilities; unsigned int max_bitpool, min_bitpool, rate, channels; int dir; snd_pcm_hw_params_get_rate(params, &rate, &dir); snd_pcm_hw_params_get_channels(params, &channels); switch (rate) { case 48000: cap->frequency = BT_SBC_SAMPLING_FREQ_48000; break; case 44100: cap->frequency = BT_SBC_SAMPLING_FREQ_44100; break; case 32000: cap->frequency = BT_SBC_SAMPLING_FREQ_32000; break; case 16000: cap->frequency = BT_SBC_SAMPLING_FREQ_16000; break; default: DBG("Rate %d not supported", rate); return -1; } if (cfg->has_channel_mode) cap->channel_mode = cfg->channel_mode; else if (channels == 2) { if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_JOINT_STEREO) cap->channel_mode = BT_A2DP_CHANNEL_MODE_JOINT_STEREO; else if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_STEREO) cap->channel_mode = BT_A2DP_CHANNEL_MODE_STEREO; else if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL) cap->channel_mode = BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL; } else { if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_MONO) cap->channel_mode = BT_A2DP_CHANNEL_MODE_MONO; } if (!cap->channel_mode) { DBG("No supported channel modes"); return -1; } if (cfg->has_block_length) cap->block_length = cfg->block_length; else if (cap->block_length & BT_A2DP_BLOCK_LENGTH_16) cap->block_length = BT_A2DP_BLOCK_LENGTH_16; else if (cap->block_length & BT_A2DP_BLOCK_LENGTH_12) cap->block_length = BT_A2DP_BLOCK_LENGTH_12; else if (cap->block_length & BT_A2DP_BLOCK_LENGTH_8) cap->block_length = BT_A2DP_BLOCK_LENGTH_8; else if (cap->block_length & BT_A2DP_BLOCK_LENGTH_4) cap->block_length = BT_A2DP_BLOCK_LENGTH_4; else { DBG("No supported block lengths"); return -1; } if (cfg->has_subbands) cap->subbands = cfg->subbands; if (cap->subbands & BT_A2DP_SUBBANDS_8) cap->subbands = BT_A2DP_SUBBANDS_8; else if (cap->subbands & BT_A2DP_SUBBANDS_4) cap->subbands = BT_A2DP_SUBBANDS_4; else { DBG("No supported subbands"); return -1; } if (cfg->has_allocation_method) cap->allocation_method = cfg->allocation_method; if (cap->allocation_method & BT_A2DP_ALLOCATION_LOUDNESS) cap->allocation_method = BT_A2DP_ALLOCATION_LOUDNESS; else if (cap->allocation_method & BT_A2DP_ALLOCATION_SNR) cap->allocation_method = BT_A2DP_ALLOCATION_SNR; if (cfg->has_bitpool) min_bitpool = max_bitpool = cfg->bitpool; else { min_bitpool = MAX(MIN_BITPOOL, cap->min_bitpool); max_bitpool = MIN(default_bitpool(cap->frequency, cap->channel_mode), cap->max_bitpool); } cap->min_bitpool = min_bitpool; cap->max_bitpool = max_bitpool; return 0; }
pcm_player *pcm_player_init(int framerate, int nchannels, int sampwidth) { pcm_player *player; int retval, format, buffsz; char *buff, *devname; snd_pcm_t *pcm_handle; snd_pcm_stream_t stream; snd_pcm_hw_params_t *hwparams; snd_pcm_uframes_t periodsize; // check parameters if(nchannels != 1 && nchannels != 2) { fprintf(stderr, "error: unsupported channels: %d\n", nchannels); return NULL; } if(sampwidth == 1) format = SND_PCM_FORMAT_U8; else if(sampwidth == 2) format = SND_PCM_FORMAT_S16_LE; else if(sampwidth == 3) format = SND_PCM_FORMAT_S24_LE; else if(sampwidth == 4) format = SND_PCM_FORMAT_S32_LE; else { fprintf(stderr, "error: unsupported sample width: %d\n", sampwidth); return NULL; } // allocate the structure player = (pcm_player*)malloc(sizeof(pcm_player)); if(player == NULL) return NULL; // open the PCM device in playback mode devname = "default"; stream = SND_PCM_STREAM_PLAYBACK; if((retval = snd_pcm_open(&pcm_handle, devname, stream, 0)) < 0) { fprintf(stderr, "error: can't PCM device: %s\n", snd_strerror(retval)); free(player); return NULL; } // allocate parameters object and fill it with default values snd_pcm_hw_params_alloca(&hwparams); snd_pcm_hw_params_any(pcm_handle, hwparams); // set parameters if((retval = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { fprintf(stderr, "error: can't set interleaved mode: %s\n", snd_strerror(retval)); snd_pcm_close(pcm_handle); free(player); return NULL; } if ((retval = snd_pcm_hw_params_set_format(pcm_handle, hwparams, format)) < 0) { fprintf(stderr, "error: can't set format: %s\n", snd_strerror(retval)); snd_pcm_close(pcm_handle); free(player); return NULL; } if ((retval = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, nchannels)) < 0) { fprintf(stderr, "error: can't set channels: %s\n", snd_strerror(retval)); snd_pcm_close(pcm_handle); free(player); return NULL; } if ((retval = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &framerate, 0)) < 0) { fprintf(stderr, "error: can't set rate: %s\n", snd_strerror(retval)); snd_pcm_close(pcm_handle); free(player); return NULL; } periodsize = framerate / 10; if((retval = snd_pcm_hw_params_set_period_size(pcm_handle, hwparams, periodsize, 0)) < 0) { fprintf(stderr, "error: can't set period size: %s\n", snd_strerror(retval)); snd_pcm_close(pcm_handle); free(player); return NULL; } // write parameters if ((retval = snd_pcm_hw_params(pcm_handle, hwparams)) < 0) { fprintf(stderr, "error: can't set hardware parameters: %s\n", snd_strerror(retval)); snd_pcm_close(pcm_handle); free(player); return NULL; } // resume information printf("PCM name: %s\n", snd_pcm_name(pcm_handle)); snd_pcm_hw_params_get_channels(hwparams, &nchannels); printf("channels: %i ", nchannels); if (nchannels == 1) printf("(mono)\n"); else if (nchannels == 2) printf("(stereo)\n"); snd_pcm_hw_params_get_rate(hwparams, &framerate, 0); printf("framerate: %d Hz\n", framerate); // allocate buffer to hold single period snd_pcm_hw_params_get_period_size(hwparams, &periodsize, 0); printf("period size: %d\n", periodsize); buffsz = sampwidth * nchannels * periodsize; printf("buffer size: %d\n", buffsz); buff = (char*)malloc(buffsz); if(buff == NULL) { fprintf(stderr, "error: can't allocate pcm buffer\n"); snd_pcm_close(pcm_handle); free(player); return NULL; } // set player attributes player->pcm_handle = pcm_handle; player->framerate = framerate; player->nchannels = nchannels; player->sampwidth = sampwidth; player->periodsize = periodsize; player->buffersize = buffsz; player->buffer = buff; return player; }
static int alsa_audio_reconfig(audio_decoder_t *ad) { decoder_t *d = (decoder_t *)ad; snd_pcm_t *h; int r; alsa_audio_fini(ad); if(d->h != NULL) { snd_pcm_close(d->h); d->h = NULL; TRACE(TRACE_DEBUG, "ALSA", "Closing device"); } const char *dev = alsa_get_devicename(); if((r = snd_pcm_open(&h, dev, SND_PCM_STREAM_PLAYBACK, 0) < 0)) { TRACE(TRACE_ERROR, "ALSA", "Unable to open %s -- %s", dev, snd_strerror(r)); return -1; } r = snd_pcm_set_params(h, SND_PCM_FORMAT_S16, SND_PCM_ACCESS_RW_INTERLEAVED, 2, 48000, 0, 100000); if(r < 0) { TRACE(TRACE_ERROR, "ALSA", "Unable to set params on %s -- %s", dev, snd_strerror(r)); return -1; } snd_pcm_hw_params_t *hwp; snd_pcm_hw_params_alloca(&hwp); snd_pcm_hw_params_current(h, hwp); unsigned int val; snd_pcm_uframes_t psize, bsize; snd_pcm_hw_params_get_rate(hwp, &val, 0); ad->ad_out_sample_rate = val; snd_pcm_hw_params_get_period_size(hwp, &psize, 0); ad->ad_tile_size = psize * 2; snd_pcm_hw_params_get_buffer_size(hwp, &bsize); d->max_frames_per_write = bsize; TRACE(TRACE_DEBUG, "ALSA", "Opened %s", dev); ad->ad_out_sample_format = AV_SAMPLE_FMT_S16; ad->ad_out_sample_rate = 48000; ad->ad_out_channel_layout = AV_CH_LAYOUT_STEREO; d->h = h; snd_pcm_prepare(d->h); int channels = 2; d->tmp = malloc(sizeof(uint16_t) * channels * d->max_frames_per_write); return 0; }