void *write_pcmdata(void *arg) { dbg("Enter write_pcmdata thread.....\n"); int ret; msg_t pcm_data; snd_pcm_sframes_t avail; common_data_t *p_common_data = (common_data_t *)arg; dbg("PCM handle name = '%s'\n",snd_pcm_name(p_common_data->handle)); dbg("period szie = %lu\n",p_common_data->period_size); while (1) { sem_wait(&p_common_data->queue.wait); if((read_item_from_queue(&p_common_data->queue, &pcm_data)) == EMPTY){ dbg("queue is empty...\n"); //TODO:block? continue; } snd_pcm_prepare(p_common_data->handle); ret = snd_pcm_writei(p_common_data->handle, pcm_data.pcm_msg, p_common_data->period_size); if (ret == -EAGAIN) { //means try again /* wait 1000ms for pcm device to become ready */ dbg_alsa("EAGAIN error, Sleep for 1000ms\n"); snd_pcm_wait(p_common_data->handle, 1000); } else if (ret == -EPIPE) { /* EPIPE means underrun */ snd_pcm_prepare(p_common_data->handle); dbg_alsa("underrun occurred\n"); } else if(ret == -ESTRPIPE) { dbg_alsa("Need suspend\n"); } else if (ret < 0) { dbg_alsa("error from writei: %s\n", snd_strerror(ret)); } ret = snd_pcm_state(p_common_data->handle); dbg("state is %d\n", ret); sem_post(&p_common_data->queue.full); } }
bool CAESinkALSA::TryDevice(const std::string &name, snd_pcm_t **pcmp, snd_config_t *lconf) { /* Check if this device was already open (e.g. when checking for supported * channel count in EnumerateDevice()) */ if (*pcmp) { if (name == snd_pcm_name(*pcmp)) return true; snd_pcm_close(*pcmp); *pcmp = NULL; } int err = snd_pcm_open_lconf(pcmp, name.c_str(), SND_PCM_STREAM_PLAYBACK, ALSA_OPTIONS, lconf); if (err < 0) { CLog::Log(LOGINFO, "CAESinkALSA - Unable to open device \"%s\" for playback", name.c_str()); } return err == 0; }
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); }
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; }
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 void set_params(void) { snd_pcm_hw_params_t *params; snd_pcm_sw_params_t *swparams; snd_pcm_uframes_t buffer_size; int err; size_t n; unsigned int rate; snd_pcm_uframes_t start_threshold, stop_threshold; snd_pcm_hw_params_alloca(¶ms); snd_pcm_sw_params_alloca(&swparams); err = snd_pcm_hw_params_any(handle, params); if (err < 0) { error("Broken configuration for this PCM: no configurations available"); exit(EXIT_FAILURE); } if (mmap_flag) { snd_pcm_access_mask_t *mask = alloca(snd_pcm_access_mask_sizeof()); snd_pcm_access_mask_none(mask); snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_INTERLEAVED); snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED); snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_COMPLEX); err = snd_pcm_hw_params_set_access_mask(handle, params, mask); } else if (interleaved) err = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); else err = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_NONINTERLEAVED); if (err < 0) { error("Access type not available"); exit(EXIT_FAILURE); } err = snd_pcm_hw_params_set_format(handle, params, hwparams.format); if (err < 0) { error("Sample format non available"); exit(EXIT_FAILURE); } err = snd_pcm_hw_params_set_channels(handle, params, hwparams.channels); if (err < 0) { error("Channels count non available"); exit(EXIT_FAILURE); } #if 0 err = snd_pcm_hw_params_set_periods_min(handle, params, 2); assert(err >= 0); #endif rate = hwparams.rate; err = snd_pcm_hw_params_set_rate_near(handle, params, &hwparams.rate, 0); assert(err >= 0); if ((float)rate * 1.05 < hwparams.rate || (float)rate * 0.95 > hwparams.rate) { if (!quiet_mode) { char plugex[64]; const char *pcmname = snd_pcm_name(handle); fprintf(stderr, "Warning: rate is not accurate (requested = %iHz, got = %iHz)\n", rate, hwparams.rate); if (! pcmname || strchr(snd_pcm_name(handle), ':')) *plugex = 0; else snprintf(plugex, sizeof(plugex), "(-Dplug:%s)", snd_pcm_name(handle)); fprintf(stderr, " please, try the plug plugin %s\n", plugex); } } rate = hwparams.rate; if (buffer_time == 0 && buffer_frames == 0) { err = snd_pcm_hw_params_get_buffer_time_max(params, &buffer_time, 0); assert(err >= 0); if (buffer_time > 500000) buffer_time = 500000; } 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(handle, params, &period_time, 0); else err = snd_pcm_hw_params_set_period_size_near(handle, params, &period_frames, 0); assert(err >= 0); if (buffer_time > 0) { err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, 0); } else { err = snd_pcm_hw_params_set_buffer_size_near(handle, params, &buffer_frames); } assert(err >= 0); err = snd_pcm_hw_params(handle, params); if (err < 0) { error("Unable to install hw params:"); snd_pcm_hw_params_dump(params, log); exit(EXIT_FAILURE); } 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) { error("Can't use period equal to buffer size (%lu == %lu)", chunk_size, buffer_size); exit(EXIT_FAILURE); } snd_pcm_sw_params_current(handle, swparams); if (avail_min < 0) n = chunk_size; else n = (double) rate * avail_min / 1000000; err = snd_pcm_sw_params_set_avail_min(handle, swparams, n); if (err < 0) { error("Setting sw params failed\n"); } /* round up to closest transfer boundary */ n = buffer_size; if (start_delay <= 0) { start_threshold = n + (double) rate * start_delay / 1000000; } else start_threshold = (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(handle, swparams, start_threshold); assert(err >= 0); if (stop_delay <= 0) stop_threshold = buffer_size + (double) rate * stop_delay / 1000000; else stop_threshold = (double) rate * stop_delay / 1000000; err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, stop_threshold); assert(err >= 0); if (snd_pcm_sw_params(handle, swparams) < 0) { error("unable to install sw params:"); snd_pcm_sw_params_dump(swparams, log); exit(EXIT_FAILURE); } if (verbose) snd_pcm_dump(handle, log); bits_per_sample = snd_pcm_format_physical_width(hwparams.format); bits_per_frame = bits_per_sample * hwparams.channels; chunk_bytes = chunk_size * bits_per_frame / 8; audiobuf = realloc(audiobuf, chunk_bytes); if (audiobuf == NULL) { error("not enough memory"); exit(EXIT_FAILURE); } // fprintf(stderr, "real chunk_size = %i, frags = %i, total = %i\n", chunk_size, setup.buf.block.frags, setup.buf.block.frags * chunk_size); /* stereo VU-meter isn't always available... */ if (vumeter == VUMETER_STEREO) { if (hwparams.channels != 2 || !interleaved || verbose > 2) vumeter = VUMETER_MONO; } /* show mmap buffer arragment */ if (mmap_flag && verbose) { const snd_pcm_channel_area_t *areas; snd_pcm_uframes_t offset; int i; err = snd_pcm_mmap_begin(handle, &areas, &offset, &chunk_size); if (err < 0) { error("snd_pcm_mmap_begin problem: %s", snd_strerror(err)); exit(EXIT_FAILURE); } for (i = 0; i < hwparams.channels; i++) fprintf(stderr, "mmap_area[%i] = %p,%u,%u (%u)\n", i, areas[i].addr, areas[i].first, areas[i].step, snd_pcm_format_physical_width(hwparams.format)); /* not required, but for sure */ snd_pcm_mmap_commit(handle, offset, 0); } buffer_frames = buffer_size; /* for position test */ }
bool CAESinkALSA::Initialize(AEAudioFormat &format, std::string &device) { m_initDevice = device; m_initFormat = format; /* if we are raw, correct the data format */ if (AE_IS_RAW(format.m_dataFormat)) { m_channelLayout = GetChannelLayout(format); format.m_dataFormat = AE_FMT_S16NE; m_passthrough = true; } else { m_channelLayout = GetChannelLayout(format); m_passthrough = false; } if (m_channelLayout.Count() == 0) { CLog::Log(LOGERROR, "CAESinkALSA::Initialize - Unable to open the requested channel layout"); return false; } format.m_channelLayout = m_channelLayout; AEDeviceType devType = AEDeviceTypeFromName(device); std::string AESParams; /* digital interfaces should have AESx set, though in practice most * receivers don't care */ if (m_passthrough || devType == AE_DEVTYPE_HDMI || devType == AE_DEVTYPE_IEC958) GetAESParams(format, AESParams); CLog::Log(LOGINFO, "CAESinkALSA::Initialize - Attempting to open device \"%s\"", device.c_str()); /* get the sound config */ snd_config_t *config; snd_config_copy(&config, snd_config); snd_config_t *dmixRateConf; long dmixRate; if (snd_config_search(config, "defaults.pcm.dmix.rate", &dmixRateConf) < 0 || snd_config_get_integer(dmixRateConf, &dmixRate) < 0) dmixRate = 48000; /* assume default */ /* Prefer dmix for non-passthrough stereo when sample rate matches */ if (!OpenPCMDevice(device, AESParams, m_channelLayout.Count(), &m_pcm, config, format.m_sampleRate == dmixRate && !m_passthrough)) { CLog::Log(LOGERROR, "CAESinkALSA::Initialize - failed to initialize device \"%s\"", device.c_str()); snd_config_delete(config); return false; } /* get the actual device name that was used */ device = snd_pcm_name(m_pcm); m_device = device; CLog::Log(LOGINFO, "CAESinkALSA::Initialize - Opened device \"%s\"", device.c_str()); /* free the sound config */ snd_config_delete(config); if (!InitializeHW(format) || !InitializeSW(format)) return false; snd_pcm_nonblock(m_pcm, 1); snd_pcm_prepare (m_pcm); m_format = format; m_formatSampleRateMul = 1.0 / (double)m_format.m_sampleRate; return true; }
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 init_alsa(void) { list_cards(); // open PCM device for recording rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_CAPTURE, 0); if (rc < 0) { printf("Unable to open pcm device: %s\n", snd_strerror(rc)); return 1; } else printf("Using %s\n", snd_pcm_name(handle)); // allocate a hardware parameter object snd_pcm_hw_params_alloca(¶ms); if (rc < 0) { printf("Unable to configure this PCM device\n"); return 1; } // fill it with default values snd_pcm_hw_params_any(handle, params); // // set the desired hardware parameters // // interleaved mode rc = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); if (rc < 0) { printf("Unable to set interleaved mode\n"); return 1; } // signed 16-bit little-endian format rc = snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); if (rc < 0) { printf("Unable to set format\n"); return 1; } // two channel stereo rc = snd_pcm_hw_params_set_channels(handle, params, 2); if (rc < 0) { printf("Unable to set to two channel stereo\n"); return 1; } // 44100 bits/second sample rate unsigned int exact_rate = rate; rc = snd_pcm_hw_params_set_rate_near(handle, params, &exact_rate, 0); if (rc < 0) { printf("Error setting rate\n"); return 1; } if (rate != exact_rate) { printf("%d Hz not supported. Using %d Hz instead", rate, exact_rate); } // set period size to 32 frames rc = snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); if (rc < 0) { printf("Error setting period size\n"); return 1; } // write the parameters to the driver rc = snd_pcm_hw_params(handle, params); if (rc < 0) { printf("Unable to set hw parameters: %s\n", snd_strerror(rc)); return 1; } size = frames * 4; // 2 bytes / sample, 2 channels buffer = (unsigned char *) malloc(size); printf("Frames: %d\n", (int)frames); printf("Allocating buffer of size: %d\n", size); snd_pcm_hw_params_get_period_time(params, &rate, &dir); return 0; }
bool CAESinkALSA::Initialize(AEAudioFormat &format, std::string &device) { CAEChannelInfo channelLayout; m_initDevice = device; m_initFormat = format; /* if we are raw, correct the data format */ if (AE_IS_RAW(format.m_dataFormat)) { channelLayout = GetChannelLayout(format); format.m_dataFormat = AE_FMT_S16NE; m_passthrough = true; } else { channelLayout = GetChannelLayout(format); m_passthrough = false; } #if defined(HAS_LIBAMCODEC) if (aml_present()) { aml_set_audio_passthrough(m_passthrough); device = "default"; } #endif if (channelLayout.Count() == 0) { CLog::Log(LOGERROR, "CAESinkALSA::Initialize - Unable to open the requested channel layout"); return false; } format.m_channelLayout = channelLayout; AEDeviceType devType = AEDeviceTypeFromName(device); std::string AESParams; /* digital interfaces should have AESx set, though in practice most * receivers don't care */ if (m_passthrough || devType == AE_DEVTYPE_HDMI || devType == AE_DEVTYPE_IEC958) GetAESParams(format, AESParams); CLog::Log(LOGINFO, "CAESinkALSA::Initialize - Attempting to open device \"%s\"", device.c_str()); /* get the sound config */ snd_config_t *config; snd_config_copy(&config, snd_config); if (!OpenPCMDevice(device, AESParams, channelLayout.Count(), &m_pcm, config)) { CLog::Log(LOGERROR, "CAESinkALSA::Initialize - failed to initialize device \"%s\"", device.c_str()); snd_config_delete(config); return false; } /* get the actual device name that was used */ device = snd_pcm_name(m_pcm); m_device = device; CLog::Log(LOGINFO, "CAESinkALSA::Initialize - Opened device \"%s\"", device.c_str()); /* free the sound config */ snd_config_delete(config); if (!InitializeHW(format) || !InitializeSW(format)) return false; // we want it blocking snd_pcm_nonblock(m_pcm, 0); snd_pcm_prepare (m_pcm); m_format = format; m_formatSampleRateMul = 1.0 / (double)m_format.m_sampleRate; return true; }
int main(int argc, char **argv){ int i; int aver,val,val2; int16_t buf[BUFSIZE]; double d_buffer[BUFSIZE]; double pitch = 0.0; struct timespec before,after; struct pitch_tracker_params *settings; snd_pcm_uframes_t period_size = PERIOD_SIZE; //ALSA PCM configuration snd_pcm_t *handle; snd_pcm_hw_params_t *params; int dir,rc; snd_pcm_uframes_t frames; /* Open PCM device for capture */ rc = snd_pcm_open( &handle, "default" , SND_PCM_STREAM_CAPTURE , 0); if(rc < 0 ){ fprintf(stderr,"unable to open pcm device: %s\n",snd_strerror(rc)); exit(1); } /* Allocate a hardware parameters object. */ snd_pcm_hw_params_alloca(¶ms); /* Fill it in with default values. */ snd_pcm_hw_params_any(handle, params); /* Set the desired hardware parameters. */ /* Interleaved mode */ snd_pcm_hw_params_set_access(handle, params,SND_PCM_ACCESS_RW_INTERLEAVED); /* unsigned 16-bit format */ snd_pcm_hw_params_set_format(handle, params,SND_PCM_FORMAT_S16); snd_pcm_hw_params_set_channels(handle, params, 1); /* 44100 bits/second sampling rate */ val = 44100; snd_pcm_hw_params_set_rate_near(handle,params, &val, &dir); /* set size time*/ snd_pcm_hw_params_set_period_size_near(handle, params, &period_size , &dir); /* write configuration */ rc = snd_pcm_hw_params(handle,params); /*Display info*/ printf("PCM handle name = '%s'\n", snd_pcm_name(handle)); printf("PCM state = %s\n", snd_pcm_state_name(snd_pcm_state(handle))); snd_pcm_hw_params_get_access(params, (snd_pcm_access_t *) &val); printf("access type = %s\n", snd_pcm_access_name((snd_pcm_access_t)val)); snd_pcm_hw_params_get_format(params, &val); printf("format = '%s' (%s)\n", snd_pcm_format_name((snd_pcm_format_t)val), snd_pcm_format_description( (snd_pcm_format_t)val)); snd_pcm_hw_params_get_subformat(params, (snd_pcm_subformat_t *)&val); printf("subformat = '%s' (%s)\n", snd_pcm_subformat_name((snd_pcm_subformat_t)val), snd_pcm_subformat_description( (snd_pcm_subformat_t)val)); snd_pcm_hw_params_get_channels(params, &val); printf("channels = %d\n", val); snd_pcm_hw_params_get_rate(params, &val, &dir); printf("rate = %d bps\n", val); snd_pcm_hw_params_get_period_time(params, &val, &dir); printf("period time = %d us\n", val); snd_pcm_hw_params_get_period_size(params, &frames, &dir); printf("period size = %d frames\n", (int)frames); snd_pcm_hw_params_get_buffer_time(params, &val, &dir); printf("buffer time = %d us\n", val); snd_pcm_hw_params_get_buffer_size(params, (snd_pcm_uframes_t *) &val); printf("buffer size = %d frames\n", val); snd_pcm_hw_params_get_periods(params, &val, &dir); printf("periods per buffer = %d frames\n", val); snd_pcm_hw_params_get_rate_numden(params, &val, &val2); printf("exact rate = %d/%d bps\n", val, val2); val = snd_pcm_hw_params_get_sbits(params); printf("significant bits = %d\n", val); val = snd_pcm_hw_params_is_batch(params); printf("is batch = %d\n", val); val = snd_pcm_hw_params_is_block_transfer(params); printf("is block transfer = %d\n", val); val = snd_pcm_hw_params_is_double(params); printf("is double = %d\n", val); val = snd_pcm_hw_params_is_half_duplex(params); printf("is half duplex = %d\n", val); val = snd_pcm_hw_params_is_joint_duplex(params); printf("is joint duplex = %d\n", val); val = snd_pcm_hw_params_can_overrange(params); printf("can overrange = %d\n", val); val = snd_pcm_hw_params_can_mmap_sample_resolution(params); printf("can mmap = %d\n", val); val = snd_pcm_hw_params_can_pause(params); printf("can pause = %d\n", val); val = snd_pcm_hw_params_can_resume(params); printf("can resume = %d\n", val); val = snd_pcm_hw_params_can_sync_start(params); printf("can sync start = %d\n", val); settings = open_pitch_tracker(); while(1){ rc = snd_pcm_readi(handle, buf, frames); if (rc == -EPIPE) { /* EPIPE means overrun */ fprintf(stderr, "overrun occurred\n"); snd_pcm_prepare(handle); } else if (rc < 0) { fprintf(stderr, "error from read: %s\n", snd_strerror(rc)); } else if (rc != (int)frames) { fprintf(stderr, "short read, read %d frames\n", rc); } for( i = 0 ; i< BUFSIZE ; i++){ d_buffer[i] = (double) buf[i]; } pitch = compute_pitch(d_buffer, BUFSIZE, S16, settings ,ACCURACY); if( pitch != 0.0 ) printf("frequency -> %f\n",pitch); memset(buf,0,BUFSIZE); } close_pitch_tracker(&settings); snd_pcm_drain(handle); snd_pcm_close(handle); return 0; }
static int init_audio_device(common_data_t *p_common_data) { int ret; int dir = 0; unsigned int val; snd_pcm_hw_params_t *p_params; snd_pcm_uframes_t buffer_size; unsigned int buffer_time; unsigned int period_time; snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE; size_t bits_per_sample; size_t bits_per_frame; ret = snd_pcm_open(&p_common_data->handle, "plughw:0,0", SND_PCM_STREAM_PLAYBACK, 0); if (ret < 0) { dbg_alsa("unable to open pcm device: %s\n", snd_strerror(ret)); return -1; } snd_pcm_hw_params_alloca(&p_params); snd_pcm_hw_params_any(p_common_data->handle, p_params); snd_pcm_hw_params_set_access(p_common_data->handle, p_params, SND_PCM_ACCESS_RW_INTERLEAVED); snd_pcm_hw_params_set_format(p_common_data->handle, p_params, SND_PCM_FORMAT_S16_LE); snd_pcm_hw_params_set_channels(p_common_data->handle, p_params, 2); val = 44100; snd_pcm_hw_params_set_rate_near(p_common_data->handle, p_params, &val, &dir); snd_pcm_hw_params_get_buffer_time_max(p_params, &buffer_time, 0); // if (buffer_time > 500000) // buffer_time = 500000; // // period_time = buffer_time / 4; // // snd_pcm_hw_params_set_period_time_near(p_common_data->handle, p_params, &period_time, 0); // snd_pcm_hw_params_set_buffer_time_near(p_common_data->handle, p_params, &buffer_time, 0); p_common_data->period_size = 2048; snd_pcm_hw_params_set_period_size_near(p_common_data->handle, p_params, &p_common_data->period_size, &dir); ret = snd_pcm_hw_params(p_common_data->handle, p_params); if (ret < 0){ dbg_alsa("unable to set hw parameters: %s\n", snd_strerror(ret)); exit(1); } ret = snd_pcm_state(p_common_data->handle); dbg("state is %d\n", ret); snd_pcm_hw_params_get_period_size(p_params, &p_common_data->period_size, &dir); snd_pcm_hw_params_get_buffer_size(p_params, &buffer_size); if (p_common_data->period_size == buffer_size) { dbg_alsa("Can't use period size equal to buffer size (%lu == %lu)\n", p_common_data->period_size, buffer_size); } dbg("period size is : %lu frames\n", p_common_data->period_size); dbg("buffer size is : %lu frames\n", buffer_size); bits_per_sample = snd_pcm_format_physical_width(format); bits_per_frame = bits_per_sample * 2; p_common_data->chunk_bytes = p_common_data->period_size * bits_per_frame / 8; //g_buf = (msg_t *)malloc(sizeof(msg_t)+(char)p_common_data->chunk_bytes); dbg("sample rate is %d\n", val); dbg("bits_per_sample %d\n", bits_per_sample); dbg("bits_per_frame %d\n", bits_per_frame); dbg("chunk_bytes %d\n", p_common_data->chunk_bytes); dbg("PCM handle name = '%s'\n",snd_pcm_name(p_common_data->handle)); return 0; }
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; }
static int set_snd_pcm_params(struct bat *bat, struct pcm_container *sndpcm) { snd_pcm_hw_params_t *params; unsigned int buffer_time = 0; unsigned int period_time = 0; unsigned int rate; int err; const char *device_name = snd_pcm_name(sndpcm->handle); /* Allocate a hardware parameters object. */ snd_pcm_hw_params_alloca(¶ms); /* Fill it in with default values. */ err = snd_pcm_hw_params_any(sndpcm->handle, params); if (err < 0) { fprintf(bat->err, _("Set parameter to device error: ")); fprintf(bat->err, _("default params: %s: %s(%d)\n"), device_name, snd_strerror(err), err); return err; } /* Set access mode */ err = snd_pcm_hw_params_set_access(sndpcm->handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { fprintf(bat->err, _("Set parameter to device error: ")); fprintf(bat->err, _("access type: %s: %s(%d)\n"), device_name, snd_strerror(err), err); return err; } /* Set format */ err = snd_pcm_hw_params_set_format(sndpcm->handle, params, bat->format); if (err < 0) { fprintf(bat->err, _("Set parameter to device error: ")); fprintf(bat->err, _("PCM format: %d %s: %s(%d)\n"), bat->format, device_name, snd_strerror(err), err); return err; } /* Set channels */ err = snd_pcm_hw_params_set_channels(sndpcm->handle, params, bat->channels); if (err < 0) { fprintf(bat->err, _("Set parameter to device error: ")); fprintf(bat->err, _("channel number: %d %s: %s(%d)\n"), bat->channels, device_name, snd_strerror(err), err); return err; } /* Set sampling rate */ rate = bat->rate; err = snd_pcm_hw_params_set_rate_near(sndpcm->handle, params, &bat->rate, 0); if (err < 0) { fprintf(bat->err, _("Set parameter to device error: ")); fprintf(bat->err, _("sample rate: %d %s: %s(%d)\n"), bat->rate, device_name, snd_strerror(err), err); return err; } if ((float) rate * (1 + RATE_RANGE) < bat->rate || (float) rate * (1 - RATE_RANGE) > bat->rate) { fprintf(bat->err, _("Invalid parameters: sample rate: ")); fprintf(bat->err, _("requested %dHz, got %dHz\n"), rate, bat->rate); return -EINVAL; } if (snd_pcm_hw_params_get_buffer_time_max(params, &buffer_time, 0) < 0) { fprintf(bat->err, _("Get parameter from device error: ")); fprintf(bat->err, _("buffer time: %d %s: %s(%d)\n"), buffer_time, device_name, snd_strerror(err), err); return -EINVAL; } if (buffer_time > MAX_BUFFERTIME) buffer_time = MAX_BUFFERTIME; period_time = buffer_time / DIV_BUFFERTIME; /* Set buffer time and period time */ err = snd_pcm_hw_params_set_buffer_time_near(sndpcm->handle, params, &buffer_time, 0); if (err < 0) { fprintf(bat->err, _("Set parameter to device error: ")); fprintf(bat->err, _("buffer time: %d %s: %s(%d)\n"), buffer_time, device_name, snd_strerror(err), err); return err; } err = snd_pcm_hw_params_set_period_time_near(sndpcm->handle, params, &period_time, 0); if (err < 0) { fprintf(bat->err, _("Set parameter to device error: ")); fprintf(bat->err, _("period time: %d %s: %s(%d)\n"), period_time, device_name, snd_strerror(err), err); return err; } /* Write the parameters to the driver */ if (snd_pcm_hw_params(sndpcm->handle, params) < 0) { fprintf(bat->err, _("Set parameter to device error: ")); fprintf(bat->err, _("hw params: %s: %s(%d)\n"), device_name, snd_strerror(err), err); return -EINVAL; } err = snd_pcm_hw_params_get_period_size(params, &sndpcm->period_size, 0); if (err < 0) { fprintf(bat->err, _("Get parameter from device error: ")); fprintf(bat->err, _("period size: %lu %s: %s(%d)\n"), sndpcm->period_size, device_name, snd_strerror(err), err); return err; } err = snd_pcm_hw_params_get_buffer_size(params, &sndpcm->buffer_size); if (err < 0) { fprintf(bat->err, _("Get parameter from device error: ")); fprintf(bat->err, _("buffer size: %lu %s: %s(%d)\n"), sndpcm->buffer_size, device_name, snd_strerror(err), err); return err; } if (sndpcm->period_size == sndpcm->buffer_size) { fprintf(bat->err, _("Invalid parameters: can't use period ")); fprintf(bat->err, _("equal to buffer size (%lu)\n"), sndpcm->period_size); return -EINVAL; } err = snd_pcm_format_physical_width(bat->format); if (err < 0) { fprintf(bat->err, _("Invalid parameters: ")); fprintf(bat->err, _("snd_pcm_format_physical_width: %d\n"), err); return err; } sndpcm->sample_bits = err; sndpcm->frame_bits = sndpcm->sample_bits * bat->channels; /* Calculate the period bytes */ sndpcm->period_bytes = sndpcm->period_size * sndpcm->frame_bits / 8; sndpcm->buffer = (char *) malloc(sndpcm->period_bytes); if (sndpcm->buffer == NULL) { fprintf(bat->err, _("Not enough memory: size=%zd\n"), sndpcm->period_bytes); return -ENOMEM; } return 0; }
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; }
static int set_snd_pcm_params(struct bat *bat, struct snd_pcm_container *sndpcm) { snd_pcm_format_t format; snd_pcm_hw_params_t *params; unsigned int buffer_time = 0; unsigned int period_time = 0; unsigned int rate; int err; const char *device_name = snd_pcm_name(sndpcm->handle); /* Allocate a hardware parameters object. */ snd_pcm_hw_params_alloca(¶ms); /* Fill it in with default values. */ err = snd_pcm_hw_params_any(sndpcm->handle, params); if (err < 0) { loge(E_SETDEV S_DEFAULT, "%s: %s(%d)", device_name, snd_strerror(err), err); goto fail_exit; } /* Set access mode */ err = snd_pcm_hw_params_set_access(sndpcm->handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { loge(E_SETDEV S_ACCESS, "%s: %s(%d)", device_name, snd_strerror(err), err); goto fail_exit; } /* Set format */ switch (bat->sample_size) { case 1: format = SND_PCM_FORMAT_S8; break; case 2: format = SND_PCM_FORMAT_S16_LE; break; case 3: format = SND_PCM_FORMAT_S24_3LE; break; case 4: format = SND_PCM_FORMAT_S32_LE; break; default: loge(E_PARAMS S_PCMFORMAT, "size=%d", bat->sample_size); goto fail_exit; } err = snd_pcm_hw_params_set_format(sndpcm->handle, params, format); if (err < 0) { loge(E_SETDEV S_PCMFORMAT, "%d %s: %s(%d)", format, device_name, snd_strerror(err), err); goto fail_exit; } /* Set channels */ err = snd_pcm_hw_params_set_channels(sndpcm->handle, params, bat->channels); if (err < 0) { loge(E_SETDEV S_CHANNELS, "%d %s: %s(%d)", bat->channels, device_name, snd_strerror(err), err); goto fail_exit; } /* Set sampling rate */ rate = bat->rate; err = snd_pcm_hw_params_set_rate_near(sndpcm->handle, params, &bat->rate, 0); if (err < 0) { loge(E_SETDEV S_SAMPLERATE, "%d %s: %s(%d)", bat->rate, device_name, snd_strerror(err), err); goto fail_exit; } if ((float) rate * 1.05 < bat->rate || (float) rate * 0.95 > bat->rate) { loge(E_PARAMS S_SAMPLERATE, "requested %dHz, got %dHz", rate, bat->rate); goto fail_exit; } if (snd_pcm_hw_params_get_buffer_time_max(params, &buffer_time, 0) < 0) { loge(E_GETDEV S_BUFFERTIME, "%d %s: %s(%d)", buffer_time, device_name, snd_strerror(err), err); goto fail_exit; } if (buffer_time > 500000) buffer_time = 500000; /* Was 4, changed to 8 to remove reduce capture overrun */ period_time = buffer_time / 8; /* Set buffer time and period time */ err = snd_pcm_hw_params_set_buffer_time_near(sndpcm->handle, params, &buffer_time, 0); if (err < 0) { loge(E_SETDEV S_BUFFERTIME, "%d %s: %s(%d)", buffer_time, device_name, snd_strerror(err), err); goto fail_exit; } err = snd_pcm_hw_params_set_period_time_near(sndpcm->handle, params, &period_time, 0); if (err < 0) { loge(E_SETDEV S_PERIODTIME, "%d %s: %s(%d)", period_time, device_name, snd_strerror(err), err); goto fail_exit; } /* Write the parameters to the driver */ if (snd_pcm_hw_params(sndpcm->handle, params) < 0) { loge(E_SETDEV S_HWPARAMS, "%s: %s(%d)", device_name, snd_strerror(err), err); goto fail_exit; } err = snd_pcm_hw_params_get_period_size(params, &sndpcm->period_size, 0); if (err < 0) { loge(E_GETDEV S_PERIODSIZE, "%zd %s: %s(%d)", sndpcm->period_size, device_name, snd_strerror(err), err); goto fail_exit; } err = snd_pcm_hw_params_get_buffer_size(params, &sndpcm->buffer_size); if (err < 0) { loge(E_GETDEV S_BUFFERSIZE, "%zd %s: %s(%d)", sndpcm->buffer_size, device_name, snd_strerror(err), err); goto fail_exit; } if (sndpcm->period_size == sndpcm->buffer_size) { loge(E_PARAMS, "can't use period equal to buffer size (%zd)", sndpcm->period_size); goto fail_exit; } err = snd_pcm_format_physical_width(format); if (err < 0) { loge(E_PARAMS, "snd_pcm_format_physical_width: %d", err); goto fail_exit; } sndpcm->sample_bits = err; sndpcm->frame_bits = sndpcm->sample_bits * bat->channels; /* Calculate the period bytes */ sndpcm->period_bytes = sndpcm->period_size * sndpcm->frame_bits / 8; sndpcm->buffer = (char *) malloc(sndpcm->period_bytes); if (sndpcm->buffer == NULL) { loge(E_MALLOC, "size=%zd", sndpcm->period_bytes); goto fail_exit; } return 0; fail_exit: return -1; }
static void set_params(void) { snd_pcm_hw_params_t *params; snd_pcm_sw_params_t *swparams; snd_pcm_uframes_t buffer_size; int err; size_t n; snd_pcm_uframes_t xfer_align; unsigned int rate; snd_pcm_uframes_t start_threshold, stop_threshold; snd_pcm_hw_params_alloca(¶ms); snd_pcm_sw_params_alloca(&swparams); err = snd_pcm_hw_params_any(handle, params); if (err < 0) { error(_("Broken configuration for this PCM: no configurations available")); exit(EXIT_FAILURE); } err = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { error(_("Access type not available")); exit(EXIT_FAILURE); } err = snd_pcm_hw_params_set_format(handle, params, hwparams.format); if (err < 0) { error(_("Sample format non available")); exit(EXIT_FAILURE); } err = snd_pcm_hw_params_set_channels(handle, params, hwparams.channels); if (err < 0) { error(_("Channels count non available")); exit(EXIT_FAILURE); } #if 0 err = snd_pcm_hw_params_set_periods_min(handle, params, 2); assert(err >= 0); #endif rate = hwparams.rate; err = snd_pcm_hw_params_set_rate_near(handle, params, &hwparams.rate, 0); assert(err >= 0); if ((float)rate * 1.05 < hwparams.rate || (float)rate * 0.95 > hwparams.rate) { if (!quiet_mode) { char plugex[64]; const char *pcmname = snd_pcm_name(handle); fprintf(stderr, _("Warning: rate is not accurate (requested = %iHz, got = %iHz)\n"), rate, hwparams.rate); if (! pcmname || strchr(snd_pcm_name(handle), ':')) *plugex = 0; else snprintf(plugex, sizeof(plugex), "(-Dplug:%s)", snd_pcm_name(handle)); fprintf(stderr, _(" please, try the plug plugin %s\n"), plugex); } } rate = hwparams.rate; if (buffer_time == 0 && buffer_frames == 0) { err = snd_pcm_hw_params_get_buffer_time_max(params, &buffer_time, 0); assert(err >= 0); if (buffer_time > 500000) buffer_time = 500000; } 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(handle, params, &period_time, 0); else err = snd_pcm_hw_params_set_period_size_near(handle, params, &period_frames, 0); assert(err >= 0); if (buffer_time > 0) { err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, 0); } else { err = snd_pcm_hw_params_set_buffer_size_near(handle, params, &buffer_frames); } assert(err >= 0); err = snd_pcm_hw_params(handle, params); if (err < 0) { error(_("Unable to install hw params:")); snd_pcm_hw_params_dump(params, log); exit(EXIT_FAILURE); } 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) { error(_("Can't use period equal to buffer size (%lu == %lu)"), chunk_size, buffer_size); exit(EXIT_FAILURE); } snd_pcm_sw_params_current(handle, swparams); err = snd_pcm_sw_params_get_xfer_align(swparams, &xfer_align); if (err < 0) { error(_("Unable to obtain xfer align\n")); exit(EXIT_FAILURE); } if (sleep_min) xfer_align = 1; err = snd_pcm_sw_params_set_sleep_min(handle, swparams, sleep_min); assert(err >= 0); if (avail_min < 0) n = chunk_size; else n = (double) rate * avail_min / 1000000; err = snd_pcm_sw_params_set_avail_min(handle, swparams, n); // round up to closest transfer boundary n = (buffer_size / xfer_align) * xfer_align; start_threshold = n; if (start_threshold < 1) start_threshold = 1; if (start_threshold > n) start_threshold = n; err = snd_pcm_sw_params_set_start_threshold(handle, swparams, start_threshold); assert(err >= 0); stop_threshold = buffer_size; err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, stop_threshold); assert(err >= 0); err = snd_pcm_sw_params_set_xfer_align(handle, swparams, xfer_align); assert(err >= 0); if (snd_pcm_sw_params(handle, swparams) < 0) { error(_("unable to install sw params:")); snd_pcm_sw_params_dump(swparams, log); exit(EXIT_FAILURE); } bits_per_sample = snd_pcm_format_physical_width(hwparams.format); bits_per_frame = bits_per_sample * hwparams.channels; chunk_bytes = chunk_size * bits_per_frame / 8; audiobuf = realloc(audiobuf, chunk_bytes); if (audiobuf == NULL) { error(_("not enough memory")); exit(EXIT_FAILURE); } // fprintf(stderr, "real chunk_size = %i, frags = %i, total = %i\n", chunk_size, setup.buf.block.frags, setup.buf.block.frags * chunk_size); }
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 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; }
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