audio_t * audio_new(audio_config_t *cfg, audio_device_t *device) { struct pcm_config config; struct pcm *pcm; audio_t *c; if (cfg->bits != 16 && cfg->bits != 24 && cfg->bits != 32) { errno = EINVAL; return NULL; } config.channels = cfg->channels; config.rate = cfg->rate; config.period_size = 1024; config.period_count = 4; config.format = cfg->bits == 16 ? PCM_FORMAT_S16_LE : cfg->bits == 32 ? PCM_FORMAT_S32_LE : PCM_FORMAT_S24_LE; config.start_threshold = config.stop_threshold = config.silence_threshold = 0; if ((pcm = pcm_open(device->card, device->device, device->playback ? PCM_OUT : PCM_IN, &config)) == NULL || ! pcm_is_ready(pcm)) { fprintf(stderr, "Failed to open: %s\n", pcm_get_error(pcm)); return NULL; } c = fatal_malloc(sizeof(*c)); c->pcm = pcm; c->cfg = *cfg; c->dev = *device; c->buffer_size = pcm_frames_to_bytes(pcm, pcm_get_buffer_size(pcm)); return c; }
static int hdmi_out_open_pcm(hdmi_out_t *out) { int card = hdmi_out_find_card(); int dev = HDMI_PCM_DEV; int ret; TRACEM("out=%p", out); /* out->up must be 0 (down) */ if (out->up) { ALOGE("Trying to open a PCM that's already up. " "This will probably deadlock... so aborting"); return 0; } out->pcm = pcm_open(card, dev, PCM_OUT, &out->config); if(out->pcm && pcm_is_ready(out->pcm)) { out->up = 1; ret = 0; } else { ALOGE("cannot open HDMI pcm card %d dev %d error: %s", card, dev, pcm_get_error(out->pcm)); pcm_close(out->pcm); out->pcm = 0; out->up = 0; ret = 1; } return ret; }
bool AudioRecordingLocal::doPrepare(AudioHardware::SamplingRate samplingRate, int samplesInOneGo) { releaseHw(); struct pcm_config config; memset(&config, 0, sizeof(config)); config.channels = 2; config.rate = samplingRate; config.period_size = 1024; config.period_count = 32; config.format = PCM_FORMAT_S16_LE; config.start_threshold = 0; config.stop_threshold = 0; config.silence_threshold = 0; mPcmHandle = pcm_open(mHwId, 0, PCM_IN, &config); if (!mPcmHandle || !pcm_is_ready(mPcmHandle)) { LOGE("Unable to open PCM device(%d) (%s)\n", mHwId, pcm_get_error(mPcmHandle)); return false; } mSamples = samplesInOneGo; mSizes = samplesInOneGo * 4; // stereo, 16bit mBufferSize = pcm_get_buffer_size(mPcmHandle); LOGD("buffer size %d, read size %d", mBufferSize, mSizes); return true; }
status_t AudioALSACaptureDataProviderBase::openPcmDriver(const unsigned int device) { ALOGD("+%s(), pcm device = %d", __FUNCTION__, device); ASSERT(mPcm == NULL); mPcm = pcm_open(kAudioSoundCardIndex, device, PCM_IN, &mConfig); if (mPcm == NULL) { ALOGE("%s(), mPcm == NULL!!", __FUNCTION__); } else if (pcm_is_ready(mPcm) == false) { ALOGE("%s(), pcm_is_ready(%p) == false due to %s, close pcm.", __FUNCTION__, mPcm, pcm_get_error(mPcm)); pcm_close(mPcm); mPcm = NULL; } else { pcm_start(mPcm); } ALOGD("-%s(), mPcm = %p", __FUNCTION__, mPcm); ASSERT(mPcm != NULL); return NO_ERROR; }
int proxy_open(alsa_device_proxy * proxy) { alsa_device_profile* profile = proxy->profile; ALOGV("proxy_open(card:%d device:%d %s)", profile->card, profile->device, profile->direction == PCM_OUT ? "PCM_OUT" : "PCM_IN"); if (profile->card < 0 || profile->device < 0) { return -EINVAL; } proxy->pcm = pcm_open(profile->card, profile->device, profile->direction | PCM_MONOTONIC, &proxy->alsa_config); if (proxy->pcm == NULL) { return -ENOMEM; } if (!pcm_is_ready(proxy->pcm)) { ALOGE(" proxy_open() pcm_open() failed: %s", pcm_get_error(proxy->pcm)); #if defined(LOG_PCM_PARAMS) log_pcm_config(&proxy->alsa_config, "config"); #endif pcm_close(proxy->pcm); proxy->pcm = NULL; return -ENOMEM; } return 0; }
bool TinyAlsaCtlPortConfig::doOpenStream(StreamDirection streamDirection, std::string &error) { struct pcm *&streamHandle = _streamHandle[streamDirection]; struct pcm_config pcmConfig; const AlsaCtlPortConfig::PortConfig &portConfig = getPortConfig(); // Fill PCM configuration structure pcmConfig.channels = portConfig.channelNumber; pcmConfig.rate = portConfig.sampleRate; // Check Format is supported by the plugin if (portConfig.format >= pcmFormatTranslationTableSize) { error = "The format n°" + asString(portConfig.format) + " is not supported by the TinyAlsa plugin"; return false; } uint8_t format = pcmFormatTranslationTable[portConfig.format].formatAsNumerical; // Check format is supported by Tinyalsa if (format == std::numeric_limits<uint8_t>::max()) { error = "The format " + pcmFormatTranslationTable[portConfig.format].formatAsString + " is not supported by Tinyalsa"; return false; } pcmConfig.format = static_cast<pcm_format>(format); pcmConfig.period_size = _periodTimeMs * pcmConfig.rate / _msPerSec; pcmConfig.period_count = _nbRingBuffer; pcmConfig.start_threshold = 0; pcmConfig.stop_threshold = 0; pcmConfig.silence_threshold = 0; pcmConfig.silence_size = 0; pcmConfig.avail_min = 0; // Open and configure streamHandle = pcm_open(getCardNumber(), getDeviceNumber(), streamDirection == Capture ? PCM_IN : PCM_OUT, &pcmConfig); // Prepare the stream if (!pcm_is_ready(streamHandle) || (pcm_prepare(streamHandle) != 0)) { // Format error error = formatAlsaError(streamDirection, "open", pcm_get_error(streamHandle)); doCloseStream(streamDirection); return false; } return true; }
static size_t read_frames(void **frames) { unsigned int card = 0; unsigned int device = 0; int flags = PCM_IN; const struct pcm_config config = { .channels = 2, .rate = 48000, .format = PCM_FORMAT_S32_LE, .period_size = 1024, .period_count = 2, .start_threshold = 1024, .silence_threshold = 1024 * 2, .stop_threshold = 1024 * 2 }; struct pcm *pcm = pcm_open(card, device, flags, &config); if (pcm == NULL) { fprintf(stderr, "failed to allocate memory for PCM\n"); return EXIT_FAILURE; } else if (!pcm_is_ready(pcm)){ pcm_close(pcm); fprintf(stderr, "failed to open PCM\n"); return EXIT_FAILURE; } unsigned int frame_size = pcm_frames_to_bytes(pcm, 1); unsigned int frames_per_sec = pcm_get_rate(pcm); *frames = malloc(frame_size * frames_per_sec); if (*frames == NULL) { fprintf(stderr, "failed to allocate frames\n"); pcm_close(pcm); return EXIT_FAILURE; } int read_count = pcm_readi(pcm, *frames, frames_per_sec); size_t byte_count = pcm_frames_to_bytes(pcm, read_count); pcm_close(pcm); return byte_count; } static int write_file(const void *frames, size_t size) { FILE *output_file = fopen("audio.raw", "wb"); if (output_file == NULL) { perror("failed to open 'audio.raw' for writing"); return EXIT_FAILURE; } fwrite(frames, 1, size, output_file); fclose(output_file); return 0; }
void play_sample(FILE *file, unsigned int device, unsigned int channels, unsigned int rate, unsigned int bits) { struct pcm_config config; struct pcm *pcm0; char *buffer; int size; int num_read; /* channels = 2,period_size = 8092; buffer_size = 8092*4 = 32k channels = 4, period_size = 4096, buffer_size = 4096*8 = 32k channels = 4, period_size = 2048, buffer_size = 2048*8 = 16k channels = 4, period_size = 1024, buffer_size = 1024*8 = 8k */ config.channels = 4; config.rate = rate; config.period_size = 1024;//4096;//2048 config.period_count = 1; if (bits == 32) config.format = PCM_FORMAT_S32_LE; else if (bits == 16) config.format = PCM_FORMAT_S16_LE; config.start_threshold = 0; config.stop_threshold = 0; config.silence_threshold = 0; /*0 is audiocodec, 1 is hdmiaudio, 2 is spdif*/ pcm0 = pcm_open(1, device, PCM_OUT, &config); if (!pcm0 || !pcm_is_ready(pcm0)) { fprintf(stderr, "Unable to open PCM device %u (%s)\n", device, pcm_get_error(pcm0)); return; } size = pcm_get_buffer_size(pcm0); buffer = malloc(size); if (!buffer) { fprintf(stderr, "Unable to allocate %d bytes\n", size); free(buffer); pcm_close(pcm0); return; } size =size; printf("hx-Playing sample:size:%d, %u ch, %u hz, %u bit\n", size, channels, rate, bits); do { num_read = fread(buffer, 1, size, file); if (num_read > 0) { if (pcm_write(pcm0, buffer, num_read)) { fprintf(stderr, "Error playing sample\n"); break; } } } while (num_read > 0); free(buffer); pcm_close(pcm0); }
static int write_frames(const void * frames, size_t byte_count){ unsigned int card = 0; unsigned int device = 0; int flags = PCM_OUT; const struct pcm_config config = { .channels = 2, .rate = 48000, .format = PCM_FORMAT_S32_LE, .period_size = 1024, .period_count = 2, .start_threshold = 1024, .silence_threshold = 1024 * 2, .stop_threshold = 1024 * 2 }; struct pcm * pcm = pcm_open(card, device, flags, &config); if (pcm == NULL) { fprintf(stderr, "failed to allocate memory for PCM\n"); return -1; } else if (!pcm_is_ready(pcm)){ pcm_close(pcm); fprintf(stderr, "failed to open PCM\n"); return -1; } unsigned int frame_count = pcm_bytes_to_frames(pcm, byte_count); int err = pcm_writei(pcm, frames, frame_count); if (err != 0) { printf("error: %s\n", pcm_get_error(pcm)); } pcm_close(pcm); return 0; } int main(void) { void *frames; size_t size; size = read_file(&frames); if (size == 0) { return EXIT_FAILURE; } if (write_frames(frames, size) < 0) { return EXIT_FAILURE; } free(frames); return EXIT_SUCCESS; }
status_t AudioALSACaptureDataProviderBTSCO::open() { ALOGD("%s()", __FUNCTION__); ASSERT(mClientLock.tryLock() != 0); // lock by base class attach AudioAutoTimeoutLock _l(mEnableLock); ASSERT(mEnable == false); // config attribute (will used in client SRC/Enh/... later) // TODO(Harvey): query this mStreamAttributeSource.audio_format = AUDIO_FORMAT_PCM_16_BIT; mStreamAttributeSource.audio_channel_mask = AUDIO_CHANNEL_IN_MONO; mStreamAttributeSource.num_channels = android_audio_legacy::AudioSystem::popCount(mStreamAttributeSource.audio_channel_mask); mStreamAttributeSource.sample_rate = mWCNChipController->GetBTCurrentSamplingRateNumber(); // pcm config mConfig.channels = mStreamAttributeSource.num_channels; mConfig.rate = mStreamAttributeSource.sample_rate; // Buffer size: 2048(period_size) * 1(ch) * 2(byte) * 4(period_count) = 16 kb mConfig.period_size = 2048; mConfig.period_count = 4; mConfig.format = PCM_FORMAT_S16_LE; mConfig.start_threshold = 0; mConfig.stop_threshold = 0; mConfig.silence_threshold = 0; ALOGD("%s(), audio_format = %d, audio_channel_mask=%x, num_channels=%d, sample_rate=%d", __FUNCTION__, mStreamAttributeSource.audio_format, mStreamAttributeSource.audio_channel_mask, mStreamAttributeSource.num_channels, mStreamAttributeSource.sample_rate); ALOGD("%s(), format = %d, channels=%d, rate=%d", __FUNCTION__, mConfig.format, mConfig.channels, mConfig.rate); OpenPCMDump(LOG_TAG); // enable pcm ASSERT(mPcm == NULL); mPcm = pcm_open(0, 12, PCM_IN | PCM_MONOTONIC, &mConfig); ASSERT(mPcm != NULL && pcm_is_ready(mPcm) == true); ALOGV("%s(), mPcm = %p", __FUNCTION__, mPcm); pcm_start(mPcm); // create reading thread mEnable = true; int ret = pthread_create(&hReadThread, NULL, AudioALSACaptureDataProviderBTSCO::readThread, (void *)this); if (ret != 0) { ALOGE("%s() create thread fail!!", __FUNCTION__); return UNKNOWN_ERROR; } return NO_ERROR; }
unsigned int capture_sample(FILE *file, unsigned int card, unsigned int device, unsigned int channels, unsigned int rate, enum pcm_format format, unsigned int period_size, unsigned int period_count) { struct pcm_config config; struct pcm *pcm; char *buffer; unsigned int size; unsigned int bytes_read = 0; memset(&config, 0, sizeof(config)); config.channels = channels; config.rate = rate; config.period_size = period_size; config.period_count = period_count; config.format = format; config.start_threshold = 0; config.stop_threshold = 0; config.silence_threshold = 0; pcm = pcm_open(card, device, PCM_IN, &config); if (!pcm || !pcm_is_ready(pcm)) { fprintf(stderr, "Unable to open PCM device (%s)\n", pcm_get_error(pcm)); return 0; } size = pcm_frames_to_bytes(pcm, pcm_get_buffer_size(pcm)); buffer = malloc(size); if (!buffer) { fprintf(stderr, "Unable to allocate %d bytes\n", size); free(buffer); pcm_close(pcm); return 0; } printf("Capturing sample: %u ch, %u hz, %u bit\n", channels, rate, pcm_format_to_bits(format)); while (capturing && !pcm_read(pcm, buffer, size)) { if (fwrite(buffer, 1, size, file) != size) { fprintf(stderr,"Error capturing sample\n"); break; } bytes_read += size; } free(buffer); pcm_close(pcm); return pcm_bytes_to_frames(pcm, bytes_read); }
unsigned int capture_sample(FILE *file, unsigned int device, unsigned int channels, unsigned int rate, unsigned int bits) { struct pcm_config config; struct pcm *pcm; char *buffer; unsigned int size; unsigned int bytes_read = 0; config.channels = channels; config.rate = rate; config.period_size = 1024; config.period_count = 4; if (bits == 32) config.format = PCM_FORMAT_S32_LE; else if (bits == 16) config.format = PCM_FORMAT_S16_LE; pcm = pcm_open(0, device, PCM_IN, &config); if (!pcm || !pcm_is_ready(pcm)) { fprintf(stderr, "Unable to open PCM device (%s)\n", pcm_get_error(pcm)); return 0; } size = pcm_get_buffer_size(pcm); buffer = malloc(size); if (!buffer) { fprintf(stderr, "Unable to allocate %d bytes\n", size); free(buffer); pcm_close(pcm); return 0; } printf("Capturing sample: %u ch, %u hz, %u bit\n", channels, rate, bits); while (capturing && !pcm_read(pcm, buffer, size)) { if (fwrite(buffer, 1, size, file) != size) { fprintf(stderr,"Error capturing sample\n"); break; } bytes_read += size; } free(buffer); pcm_close(pcm); return bytes_read / ((bits / 8) * channels); }
static int inner_main(struct tone_generator_config config) { struct pcm_config *pcm_config = &config.pcm_config; struct pcm *pcm; unsigned pos; void *buf; pcm = pcm_open(config.card, config.device, PCM_OUT, pcm_config); if (!pcm) { fprintf(stderr, "Could not open sound card\n"); fprintf(stderr, "%s\n", pcm_get_error(pcm)); return 1; } if (!pcm_is_ready(pcm)) { fprintf(stderr, "Sound card not ready\n"); fprintf(stderr, "%s\n", pcm_get_error(pcm)); return 1; } buf = calloc(config.bits / 8, pcm_config->period_size * pcm_config->channels); if (!buf) { fprintf(stderr, "Could not allocate memory for buffer\n"); return 1; } for (pos=0 ; (!config.duration || (pos < config.duration)) ; pos += pcm_config->period_size) { oscillator_table_render(buf, config.wave_table, pos, pcm_config->period_size, config.wave_scale, pcm_config->channels, config.chan_mask, /* write to all channels */ config.volume, config.bits); if (pcm_write(pcm, buf, pcm_config->channels * pcm_config->period_size * (config.bits/8))) { fprintf(stderr, "Error writing to sound card\n"); fprintf(stderr, "%s\n", pcm_get_error(pcm)); } } pcm_close(pcm); return 0; }
static bool profile_test_sample_rate(alsa_device_profile* profile, unsigned rate) { struct pcm_config config = profile->default_config; config.rate = rate; bool works = false; /* let's be pessimistic */ struct pcm * pcm = pcm_open(profile->card, profile->device, profile->direction, &config); if (pcm != NULL) { works = pcm_is_ready(pcm); pcm_close(pcm); } return works; }
EXTERN_TAG int pcm_output_init(int sr,int ch) { int card = 0; int device = 2; cached_len = 0; wfd_config_out.channels = 2; wfd_config_out.rate = 48000; wfd_config_out.period_size = WFD_PERIOD_SIZE; wfd_config_out.period_count = WFD_PERIOD_NUM; wfd_config_out.format = PCM_FORMAT_S16_LE; wfd_config_out.start_threshold = WFD_PERIOD_SIZE; wfd_config_out.avail_min = 0;//SHORT_PERIOD_SIZE; card = get_aml_card(); if(card < 0) { card = 0; adec_print("get aml card fail, use default \n"); } // if hdmi state on if(get_hdmi_switch_state()) device = get_spdif_port(); else device = 0; //i2s output for analog output if(device < 0) { device = 0; adec_print("get aml card device fail, use default \n"); } adec_print("open output device card %d, device %d \n",card,device); if(sr < 32000|| sr > 48000 || ch != 2){ adec_print("wfd output: not right parameter sr %d,ch %d \n",sr,ch); return -1; } wfd_config_out.rate = sr; wfd_config_out.channels = ch; wfd_pcm = pcm_open(card, device, PCM_OUT /*| PCM_MMAP | PCM_NOIRQ*/, &wfd_config_out); if (!pcm_is_ready(wfd_pcm)) { adec_print("wfd cannot open pcm_out driver: %s", pcm_get_error(wfd_pcm)); pcm_close(wfd_pcm); return -1; } adec_print("pcm_output_init done wfd : %p,\n",wfd_pcm); return 0; }
/* must be called with hw device and output stream mutexes locked */ static int start_output_stream(struct stream_out *out) { struct audio_device *adev = out->dev; int i; if ((adev->card < 0) || (adev->device < 0)) return -EINVAL; out->pcm = pcm_open(adev->card, adev->device, PCM_OUT, &pcm_config); if (out->pcm && !pcm_is_ready(out->pcm)) { ALOGE("pcm_open() failed: %s", pcm_get_error(out->pcm)); pcm_close(out->pcm); return -ENOMEM; } return 0; }
int InStream::startInputStream() { LOGFUNC("%s(%p)", __func__, this); mUcm.activateEntry(mEntry, this); int card = mUcm.getCaptureCard(mEntry); int port = mUcm.getCapturePort(mEntry); ALOGE("setting capture card=%d port=%d", card, port); mPcm = pcm_open(card, port, PCM_IN, &mConfig); if (!pcm_is_ready(mPcm)) { ALOGE("cannot open pcm_in driver: %s", pcm_get_error(mPcm)); pcm_close(mPcm); mPcm = NULL; mUcm.deactivateEntry(mEntry); return -ENOMEM; } mStandby = false; return 0; }
bool SpeechANCController::StartPCMIn(char mTypePCM, uint32_t device, pcm_config mConfig) { ALOGD("+%s(), pcm device = %d", __FUNCTION__, device); pcm *mPcm; //ASSERT(mPcm == NULL); mPcm = pcm_open(kAudioSoundCardIndex, device, PCM_IN, &mConfig); if (mPcm == NULL) { ALOGE("%s(), mPcm == NULL!!", __FUNCTION__); } else if (pcm_is_ready(mPcm) == false) { ALOGE("%s(), pcm_is_ready(%p) == false due to %s, close pcm.", __FUNCTION__, mPcm, pcm_get_error(mPcm)); pcm_close(mPcm); mPcm = NULL; } else { pcm_start(mPcm); } ALOGD("-%s(), mPcm = %p", __FUNCTION__, mPcm); ASSERT(mPcm != NULL); switch (mTypePCM) { case 0: mPcmIn_MOD = mPcm ; break; case 1: mPcmIn_IO2 = mPcm; break; case 2: mPcmIn_ADC2 = mPcm; break; } return true; }
int start_input_stream(struct stream_in *in) { int ret = 0; struct audio_device *adev = in->dev; adev->card = get_card_number_by_name("USB Audio"); adev->device = DEFAULT_DEVICE; ALOGVV("%s: USB card number = %d, device = %d",__func__,adev->card,adev->device); ALOGV("%s :: requested params \ \r \t channels = %d, \ \r \t rate = %d, \ \r \t period_size = %d, \ \r \t period_count = %d, \ \r \t format = %d", __func__, in->pcm_config.channels,in->pcm_config.rate, in->pcm_config.period_size,in->pcm_config.period_count, in->pcm_config.format); ret = validate_input_hardware_params(in); if(ret != 0) { ALOGE("Unsupport input stream parameters"); in->pcm = NULL; return -ENOSYS; } in->pcm = pcm_open(adev->card, adev->device, PCM_IN, &in->pcm_config); if (in->pcm && !pcm_is_ready(in->pcm)) { ALOGE("%s: %s", __func__, pcm_get_error(in->pcm)); pcm_close(in->pcm); in->pcm = NULL; ret = -EIO; ALOGD("%s: exit: status(%d)", __func__, ret); return ret; } else { ALOGV("%s: exit capture pcm = %x", __func__,in->pcm); return ret; } }
status_t AudioALSACaptureDataProviderTDM::open() { ALOGD("%s()", __FUNCTION__); ASSERT(mClientLock.tryLock() != 0); // lock by base class attach AudioAutoTimeoutLock _l(mEnableLock); AudioAutoTimeoutLock _l2(*AudioALSADriverUtility::getInstance()->getStreamSramDramLock()); ASSERT(mEnable == false); // config attribute (will used in client SRC/Enh/... later) // TODO(Harvey): query this mStreamAttributeSource.audio_format = AUDIO_FORMAT_PCM_16_BIT; mStreamAttributeSource.audio_channel_mask = AUDIO_CHANNEL_IN_STEREO; mStreamAttributeSource.num_channels = android_audio_legacy::AudioSystem::popCount(mStreamAttributeSource.audio_channel_mask); mStreamAttributeSource.sample_rate = 44100; OpenPCMDump(LOG_TAG); // enable pcm ASSERT(mPcm == NULL); mPcm = pcm_open(0, 13, PCM_IN, &mConfig); // mPcm = pcm_open(0, 1, PCM_IN, &mConfig); ASSERT(mPcm != NULL && pcm_is_ready(mPcm) == true); ALOGV("%s(), mPcm = %p", __FUNCTION__, mPcm); pcm_start(mPcm); // create reading thread mEnable = true; int ret = pthread_create(&hReadThread, NULL, AudioALSACaptureDataProviderTDM::readThread, (void *)this); if (ret != 0) { ALOGE("%s() create thread fail!!", __FUNCTION__); return UNKNOWN_ERROR; } return NO_ERROR; }
int muroard_driver_init(const char * dev) { struct pcm_config config; unsigned int period_size = muroard_state_member(abuffer_size); unsigned int period_count = 4; unsigned int card = 0; unsigned int device = 0; config.channels = muroard_state_member(sa_channels); config.rate = muroard_state_member(sa_rate); config.format = PCM_FORMAT_S16_LE; config.start_threshold = 0; config.stop_threshold = 0; config.silence_threshold = 0; config.period_size = period_size; config.period_count = period_count; muroard_state_member(driver_vp) = pcm_open(card, device, PCM_OUT, &config); if (!muroard_state_member(driver_vp) || !pcm_is_ready(muroard_state_member(driver_vp))) return -1; return 0; }
static int initialize_device(out123_handle *ao) { mpg123_tinyalsa_t* ta = (mpg123_tinyalsa_t*)ao->userptr; ta->config.channels = ao->channels; ta->config.rate = ao->rate; ta->config.period_size = 1024; ta->config.period_count = 4; ta->config.format = PCM_FORMAT_S16_LE; ta->config.start_threshold = 0; ta->config.stop_threshold = 0; ta->config.silence_threshold = 0; ta->pcm = pcm_open(ta->card, ta->device, PCM_OUT, &ta->config); if (!ta->pcm || !pcm_is_ready(ta->pcm)) { if(!AOQUIET) error3( "(open) Unable to open card %u PCM device %u (%s)\n" , ta->card, ta->device, pcm_get_error(ta->pcm) ); return -1; } return 0; }
status_t AudioALSAFMController::setFmDirectConnection(const bool enable, const bool bforce) { ALOGD("+%s(), enable = %d, bforce = %d", __FUNCTION__, enable, bforce); // Check Current Status if (mIsFmDirectConnectionMode == enable && bforce == false) { ALOGW("-%s(), enable = %d, bforce = %d", __FUNCTION__, enable, bforce); return INVALID_OPERATION; } // Apply if (enable == true) { mConfig.channels = 2; mConfig.rate = getFmDownlinkSamplingRate(); mConfig.period_size = 3072; mConfig.period_count = 2; mConfig.format = PCM_FORMAT_S16_LE; mConfig.start_threshold = 0; mConfig.stop_threshold = 0; mConfig.silence_threshold = 0; if (mPcm == NULL) { // Get pcm open Info int card_index = -1; int pcm_index = -1; if (WCNChipController::GetInstance()->IsFMMergeInterfaceSupported() == true) { card_index = AudioALSADeviceParser::getInstance()->GetCardIndexByString(keypcmMRGrxPlayback); pcm_index = AudioALSADeviceParser::getInstance()->GetPcmIndexByString(keypcmMRGrxPlayback); } else { card_index = AudioALSADeviceParser::getInstance()->GetCardIndexByString(keypcmFMI2SPlayback); pcm_index = AudioALSADeviceParser::getInstance()->GetPcmIndexByString(keypcmFMI2SPlayback); } ALOGD("%s(), card_index = %d, pcm_index = %d", __FUNCTION__, card_index, pcm_index); mPcm = pcm_open(card_index, pcm_index , PCM_OUT, &mConfig); ALOGD("%s(), pcm_open mPcm = %p", __FUNCTION__, mPcm); } if (mPcm == NULL || pcm_is_ready(mPcm) == false) { ALOGE("%s(), Unable to open mPcm device %u (%s)", __FUNCTION__, 6 , pcm_get_error(mPcm)); } pcm_start(mPcm); } else { if (mPcm != NULL) { pcm_stop(mPcm); pcm_close(mPcm); mPcm = NULL; } } // Update Direct Mode Status mIsFmDirectConnectionMode = enable; // Update (HW_GAIN2) Volume for Direct Mode Only if (mIsFmDirectConnectionMode == true) { setFmVolume(mFmVolume); } ALOGD("-%s(), enable = %d, bforce = %d", __FUNCTION__, enable, bforce); return NO_ERROR; }
static int start_output_stream(struct stream_out *out) { struct audio_device *adev = out->dev; int ret = 0; ALOGV("%s enter input params %d,%d,%d,%d,%d",__func__, out->pcm_config.channels, out->pcm_config.rate, out->pcm_config.period_size, out->pcm_config.period_count, out->pcm_config.format); out->pcm_config.start_threshold = 0; out->pcm_config.stop_threshold = 0; out->pcm_config.silence_threshold = 0; // close the active device and make HD device active if(out->flags & AUDIO_OUTPUT_FLAG_DIRECT) { ALOGV("direct flag active stream"); if(adev->active_pcm) { ALOGVV("Current active stream is closed to open HD interface %d",(int)adev->active_pcm); pcm_close(adev->active_pcm); } adev->hdaudio_active = true; adev->active_pcm = NULL; } // if HD device is active, use the same for subsequent streams if((adev->active_pcm) && (adev->hdaudio_active)) { out->pcm = adev->active_pcm; ALOGV("USB PCM interface already opened - use same params to render till its closed"); goto skip_open; } /*TODO - this needs to be updated once the device connect intent sends card, device id*/ adev->card = get_card_number_by_name("USB Audio"); adev->device = DEFAULT_DEVICE; ALOGD("%s: USB card number = %d, device = %d",__func__,adev->card,adev->device); /* query & validate sink supported params and input params*/ ret = validate_output_hardware_params(out); if(ret != 0) { ALOGE("Unsupport input stream parameters"); adev->active_pcm = NULL; adev->hdaudio_active = false; out->pcm = NULL; return -ENOSYS; } out->pcm = pcm_open(adev->card, adev->device, PCM_OUT, &out->pcm_config); if (out->pcm && !pcm_is_ready(out->pcm)) { ALOGE("pcm_open() failed: %s", pcm_get_error(out->pcm)); pcm_close(out->pcm); adev->active_pcm = NULL; adev->hdaudio_active = false; out->pcm = NULL; return -ENOSYS; } //update the newly opened pcm to be active adev->active_pcm = out->pcm; skip_open: ALOGV("Initialized PCM device for channels %d sample rate %d activepcm = %d", out->pcm_config.channels,out->pcm_config.rate,(int)adev->active_pcm); ALOGV("%s exit",__func__); return 0; }
status_t AudioALSACaptureDataProviderEchoRefExt::open() { ALOGD("%s()", __FUNCTION__); ASSERT(mClientLock.tryLock() != 0); // lock by base class attach AudioAutoTimeoutLock _l(mEnableLock); AudioAutoTimeoutLock _l2(*AudioALSADriverUtility::getInstance()->getStreamSramDramLock()); ASSERT(mEnable == false); AudioALSASampleRateController *pAudioALSASampleRateController = AudioALSASampleRateController::getInstance(); pAudioALSASampleRateController->setScenarioStatus(PLAYBACK_SCENARIO_ECHO_REF_EXT); // config attribute (will used in client SRC/Enh/... later) // TODO(Sam): query the mConfig? mStreamAttributeSource.audio_format = AUDIO_FORMAT_PCM_16_BIT; mStreamAttributeSource.audio_channel_mask = AUDIO_CHANNEL_IN_STEREO; mStreamAttributeSource.num_channels = android_audio_legacy::AudioSystem::popCount(mStreamAttributeSource.audio_channel_mask); mStreamAttributeSource.sample_rate = AudioALSASampleRateController::getInstance()->getPrimaryStreamOutSampleRate(); mConfig.channels = mStreamAttributeSource.num_channels; mConfig.rate = mStreamAttributeSource.sample_rate; // Buffer size: 2048(period_size) * 2(ch) * 2(byte) * 8(period_count) = 64 kb mConfig.period_size = 2048; mConfig.period_count = 8; mConfig.format = PCM_FORMAT_S16_LE; mConfig.start_threshold = 0; mConfig.stop_threshold = 0; mConfig.silence_threshold = 0; #if 0 //latency time, set as DataProvider buffer size mStreamAttributeSource.latency = (kReadBufferSize * 1000) / (mStreamAttributeSource.num_channels * mStreamAttributeSource.sample_rate * (mStreamAttributeSource.audio_format == AUDIO_FORMAT_PCM_8_BIT ? 1 : //8 1byte/frame (mStreamAttributeSource.audio_format == AUDIO_FORMAT_PCM_32_BIT ? 4 : //24bit 3bytes/frame 2))); //default 2bytes/sample #else //latency time, set as hardware buffer size mStreamAttributeSource.latency = (mConfig.period_size * mConfig.period_count * 1000) / mConfig.rate; #endif ALOGD("%s(), audio_format = %d, audio_channel_mask=%x, num_channels=%d, sample_rate=%d, latency=%dms", __FUNCTION__, mStreamAttributeSource.audio_format, mStreamAttributeSource.audio_channel_mask, mStreamAttributeSource.num_channels, mStreamAttributeSource.sample_rate, mStreamAttributeSource.latency); ALOGD("%s(), format = %d, channels=%d, rate=%d", __FUNCTION__, mConfig.format, mConfig.channels, mConfig.rate); #ifdef NXP_SMARTPA_SUPPORT MTK_Tfa98xx_EchoReferenceConfigure(1); #endif OpenPCMDump(LOG_TAG); // enable pcm ASSERT(mPcm == NULL); mPcm = pcm_open(0, 16, PCM_IN | PCM_MONOTONIC, &mConfig); ASSERT(mPcm != NULL && pcm_is_ready(mPcm) == true); pcm_start(mPcm); // create reading thread mEnable = true; int ret = pthread_create(&hReadThread, NULL, AudioALSACaptureDataProviderEchoRefExt::readThread, (void *)this); if (ret != 0) { ALOGE("%s() create thread fail!!", __FUNCTION__); return UNKNOWN_ERROR; } return NO_ERROR; }
int play(int argc, char **argv) { int nMixer = -1, nDevice = -1; pcm_config cfg = { channels : 0, rate : 0, period_size : 1024, period_count : 4, format : PCM_FORMAT_S16_LE, start_threshold : 0, stop_threshold : 0, silence_threshold : 0, }; if (argc == 6) { nMixer = atoi(argv[2]); nDevice = atoi(argv[3]); cfg.rate = atoi(argv[4]); cfg.channels = atoi(argv[5]); } if (argc != 6 || nMixer < 0 || nMixer > 7 || nDevice < 0 || cfg.rate <= 0 || cfg.channels <= 0 || cfg.channels > 2) { printf("Usage: ainfo play <card number> <device number> <rate> <channels>\n" "where <card number> is between 0 and 7\n" "<device number> is the device to play on\n" "<rate> is the sampling rate\n" "<channels> is either 1 or 2\n" "NOTE The file to be played is read from stdin\n"); return 0; } pcm *p = pcm_open(nMixer, nDevice, PCM_OUT, &cfg); if (!pcm_is_ready(p)) { printf("Device not ready. Probably due to invalid parameters."); pcm_close(p); return -1; } unsigned bufsize = pcm_get_buffer_size(p); char *data = new char[bufsize]; if (!data) { printf("Could not allocate %d bytes.\n", bufsize); return -1; } while (read(0, data, bufsize) == bufsize) { printf("."); if (pcm_write(p, data, bufsize)) break; } printf("\b.\nFinished.\n"); delete [] data; pcm_close(p); return 0; } int main(int argc, char **argv) { if (argc >= 2) { if (!strcmp(argv[1], "list")) return list(argc, argv); else if (!strcmp(argv[1], "read")) return read(argc, argv); else if (!strcmp(argv[1], "read-range")) return read_range(argc, argv); else if (!strcmp(argv[1], "write")) return write(argc, argv); else if (!strcmp(argv[1], "write-percentage")) return write_percentage(argc, argv); else if (!strcmp(argv[1], "play")) return play(argc, argv); } printf("Usage: audiotest <command>\nwhere <command> is one of:\n" "list, read, read-range, write, write-percentage, play\n"); return 0; }
static gboolean gst_tinyalsa_sink_prepare (GstAudioSink * asink, GstAudioRingBufferSpec * spec) { GstTinyalsaSink *sink = GST_TINYALSA_SINK (asink); struct pcm_config config = { 0, }; struct pcm_params *params = NULL; int period_size_min, period_size_max; int periods_min, periods_max; pcm_config_from_spec (&config, spec); GST_DEBUG_OBJECT (sink, "Requesting %u periods of %u frames", config.period_count, config.period_size); params = pcm_params_get (sink->card, sink->device, PCM_OUT); if (!params) GST_ERROR_OBJECT (sink, "Could not get PCM params"); period_size_min = pcm_params_get_min (params, PCM_PARAM_PERIOD_SIZE); period_size_max = pcm_params_get_max (params, PCM_PARAM_PERIOD_SIZE); periods_min = pcm_params_get_min (params, PCM_PARAM_PERIODS); periods_max = pcm_params_get_max (params, PCM_PARAM_PERIODS); pcm_params_free (params); /* Snap period size/count to the permitted range */ config.period_size = CLAMP (config.period_size, period_size_min, period_size_max); config.period_count = CLAMP (config.period_count, periods_min, periods_max); /* mutex with getcaps */ GST_OBJECT_LOCK (sink); sink->pcm = pcm_open (sink->card, sink->device, PCM_OUT | PCM_NORESTART, &config); GST_OBJECT_UNLOCK (sink); if (!sink->pcm || !pcm_is_ready (sink->pcm)) { GST_ERROR_OBJECT (sink, "Could not open device: %s", pcm_get_error (sink->pcm)); goto fail; } if (pcm_prepare (sink->pcm) < 0) { GST_ERROR_OBJECT (sink, "Could not prepare device: %s", pcm_get_error (sink->pcm)); goto fail; } spec->segsize = pcm_frames_to_bytes (sink->pcm, config.period_size); spec->segtotal = config.period_count; GST_DEBUG_OBJECT (sink, "Configured for %u periods of %u frames", config.period_count, config.period_size); return TRUE; fail: if (sink->pcm) pcm_close (sink->pcm); return FALSE; }
void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int channels, unsigned int rate, unsigned int bits, unsigned int period_size, unsigned int period_count) { struct pcm_config config; struct pcm *pcm; char *buffer; int size; int num_read; memset(&config, 0, sizeof(config)); config.channels = channels; config.rate = rate; config.period_size = period_size; config.period_count = period_count; if (bits == 32) config.format = PCM_FORMAT_S32_LE; else if (bits == 16) config.format = PCM_FORMAT_S16_LE; config.start_threshold = 0; config.stop_threshold = 0; config.silence_threshold = 0; if (!sample_is_playable(card, device, channels, rate, bits, period_size, period_count)) { return; } pcm = pcm_open(card, device, PCM_OUT, &config); if (!pcm || !pcm_is_ready(pcm)) { fprintf(stderr, "Unable to open PCM device %u (%s)\n", device, pcm_get_error(pcm)); return; } size = pcm_frames_to_bytes(pcm, pcm_get_buffer_size(pcm)); buffer = malloc(size); if (!buffer) { fprintf(stderr, "Unable to allocate %d bytes\n", size); free(buffer); pcm_close(pcm); return; } printf("Playing sample: %u ch, %u hz, %u bit\n", channels, rate, bits); /* catch ctrl-c to shutdown cleanly */ signal(SIGINT, stream_close); do { num_read = fread(buffer, 1, size, file); if (num_read > 0) { if (pcm_write(pcm, buffer, num_read)) { fprintf(stderr, "Error playing sample\n"); break; } } } while (!close && num_read > 0); free(buffer); pcm_close(pcm); }
bool AudioPlayer::threadLoop() { struct pcm_config config; struct pcm *pcm = NULL; bool moreChunks = true; const struct chunk_fmt* chunkFmt = NULL; int bufferSize; const uint8_t* wavData; size_t wavLength; const struct riff_wave_header* wavHeader; if (mCurrentFile == NULL) { ALOGE("mCurrentFile is NULL"); return false; } wavData = (const uint8_t *)mCurrentFile->getDataPtr(); if (!wavData) { ALOGE("Could not access WAV file data"); goto exit; } wavLength = mCurrentFile->getDataLength(); wavHeader = (const struct riff_wave_header *)wavData; if (wavLength < sizeof(*wavHeader) || (wavHeader->riff_id != ID_RIFF) || (wavHeader->wave_id != ID_WAVE)) { ALOGE("Error: audio file is not a riff/wave file\n"); goto exit; } wavData += sizeof(*wavHeader); wavLength -= sizeof(*wavHeader); do { const struct chunk_header* chunkHeader = (const struct chunk_header*)wavData; if (wavLength < sizeof(*chunkHeader)) { ALOGE("EOF reading chunk headers"); goto exit; } wavData += sizeof(*chunkHeader); wavLength -= sizeof(*chunkHeader); switch (chunkHeader->id) { case ID_FMT: chunkFmt = (const struct chunk_fmt *)wavData; wavData += chunkHeader->sz; wavLength -= chunkHeader->sz; break; case ID_DATA: /* Stop looking for chunks */ moreChunks = 0; break; default: /* Unknown chunk, skip bytes */ wavData += chunkHeader->sz; wavLength -= chunkHeader->sz; } } while (moreChunks); if (!chunkFmt) { ALOGE("format not found in WAV file"); goto exit; } memset(&config, 0, sizeof(config)); config.channels = chunkFmt->num_channels; config.rate = chunkFmt->sample_rate; config.period_size = mPeriodSize; config.period_count = mPeriodCount; config.start_threshold = mPeriodSize / 4; config.stop_threshold = INT_MAX; config.avail_min = config.start_threshold; if (chunkFmt->bits_per_sample != 16) { ALOGE("only 16 bit WAV files are supported"); goto exit; } config.format = PCM_FORMAT_S16_LE; pcm = pcm_open(mCard, mDevice, PCM_OUT, &config); if (!pcm || !pcm_is_ready(pcm)) { ALOGE("Unable to open PCM device (%s)\n", pcm_get_error(pcm)); goto exit; } bufferSize = pcm_frames_to_bytes(pcm, pcm_get_buffer_size(pcm)); while (wavLength > 0) { if (exitPending()) goto exit; size_t count = bufferSize; if (count > wavLength) count = wavLength; if (pcm_write(pcm, wavData, count)) { ALOGE("pcm_write failed (%s)", pcm_get_error(pcm)); goto exit; } wavData += count; wavLength -= count; } exit: if (pcm) pcm_close(pcm); mCurrentFile->release(); mCurrentFile = NULL; return false; }