static int adev_set_master_volume(struct audio_hw_device *dev, float volume) { #if 0 //TARGET_AUDIO_PRIMARY struct mixer *mixer; struct mixer_ctl *ctl; struct audio_device * adev = (struct audio_device *)dev; if ((0 > volume) || (1 < volume) || (NULL == adev)) return -EINVAL; pthread_mutex_lock(&adev->lock); adev->master_volume = (int)(volume*100); if (!(mixer = mixer_open(0))) { pthread_mutex_unlock(&adev->lock); return -ENOSYS; } ctl = mixer_get_ctl_by_name(mixer, "HP Playback Volume"); mixer_ctl_set_value(ctl,0,adjust_volume(adev->master_volume)); mixer_ctl_set_value(ctl,1,adjust_volume(adev->master_volume)); mixer_close(mixer); pthread_mutex_unlock(&adev->lock); return 0; #else return -ENOSYS; #endif }
bool AudioALSAPlaybackHandlerNormal::SetLowJitterMode(bool bEnable,uint32_t SampleRate) { ALOGD("%s() bEanble = %d SampleRate = %u", __FUNCTION__, bEnable,SampleRate); enum mixer_ctl_type type; struct mixer_ctl *ctl; int retval = 0; // check need open low jitter mode if(SampleRate < GetLowJitterModeSampleRate() && (AudioALSADriverUtility::getInstance()->GetPropertyValue(PROPERTY_KEY_EXTDAC)) == false) { ALOGD("%s(), bEanble = %d", __FUNCTION__, bEnable); return false; } ctl = mixer_get_ctl_by_name(mMixer, "Audio_I2S0dl1_hd_Switch"); if (ctl == NULL) { ALOGE("Audio_I2S0dl1_hd_Switch not support"); return false; } if (bEnable == true) { retval = mixer_ctl_set_enum_by_string(ctl, "On"); ASSERT(retval == 0); } else { retval = mixer_ctl_set_enum_by_string(ctl, "Off"); ASSERT(retval == 0); } return true; }
void mixer_ctl_set(struct mixer *mixer, const char *name, const char *val) { struct mixer_ctl *ctl = mixer_get_ctl_by_name(mixer, name); int ret = mixer_ctl_set_enum_by_string(ctl, val); if (ret != 0) LOGE("Failed to set %s to %s\n", name, val); }
int offload_update_mixer_and_effects_ctl(int card, int device_id, struct mixer *mixer, struct mixer_ctl *ctl) { char mixer_string[128]; snprintf(mixer_string, sizeof(mixer_string), "%s %d", "Audio Effects Config", device_id); ALOGV("%s: mixer_string: %s", __func__, mixer_string); mixer = mixer_open(card); if (!mixer) { ALOGE("Failed to open mixer"); ctl = NULL; return -EINVAL; } else { ctl = mixer_get_ctl_by_name(mixer, mixer_string); if (!ctl) { ALOGE("mixer_get_ctl_by_name failed"); mixer_close(mixer); mixer = NULL; return -EINVAL; } } ALOGV("mixer: %p, ctl: %p", mixer, ctl); return 0; }
int platform_listen_connect_mad ( void *platform, bool en, audio_listen_session_t *p_ses ) { #ifndef PLATFORM_APQ8084 return 0; #else /* This mixer control is only valid for CPE supported codec */ struct platform_data *my_data = (struct platform_data *)platform; audio_listen_hardware_t *listen_hal = my_data->listen_hal; int status = 0; struct mixer_ctl *ctl = NULL; const char *mixer_ctl_name = "MAD_SEL MUX"; ctl = mixer_get_ctl_by_name(listen_hal->mixer, mixer_ctl_name); if (!ctl) { ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s", __func__, mixer_ctl_name); return -EINVAL; } if(p_ses->exec_mode == LISTEN_EXEC_MODE_CPE) status = mixer_ctl_set_enum_by_string(ctl, "SPE"); else status = mixer_ctl_set_enum_by_string(ctl, "MSM"); if (status) ALOGE("%s: ERROR. Mixer ctl set failed", __func__); return status; #endif }
static void tinymix_set_value(struct mixer *mixer, const char *control, char **values, unsigned int num_values) { struct mixer_ctl *ctl; enum mixer_ctl_type type; unsigned int num_ctl_values; unsigned int i; if (isdigit(control[0])) ctl = mixer_get_ctl(mixer, atoi(control)); else ctl = mixer_get_ctl_by_name(mixer, control); if (!ctl) { fprintf(stderr, "Invalid mixer control\n"); return; } type = mixer_ctl_get_type(ctl); num_ctl_values = mixer_ctl_get_num_values(ctl); if (isdigit(values[0][0])) { if (num_values == 1) { /* Set all values the same */ int value = atoi(values[0]); for (i = 0; i < num_ctl_values; i++) { if (mixer_ctl_set_value(ctl, i, value)) { fprintf(stderr, "Error: invalid value\n"); return; } } } else { /* Set multiple values */ if (num_values > num_ctl_values) { fprintf(stderr, "Error: %d values given, but control only takes %d\n", num_values, num_ctl_values); return; } for (i = 0; i < num_values; i++) { if (mixer_ctl_set_value(ctl, i, atoi(values[i]))) { fprintf(stderr, "Error: invalid value for index %d\n", i); return; } } } } else { if (type == MIXER_CTL_TYPE_ENUM) { if (num_values != 1) { fprintf(stderr, "Enclose strings in quotes and try again\n"); return; } if (mixer_ctl_set_enum_by_string(ctl, values[0])) fprintf(stderr, "Error: invalid enum value\n"); } else { fprintf(stderr, "Error: only enum types can be set with strings\n"); } } }
static void tinymix_set_value(struct mixer *mixer, char *name, char *value) { struct mixer_ctl *ctl; enum mixer_ctl_type type; unsigned int i, num_values; ctl = mixer_get_ctl_by_name(mixer, name); if(!ctl) { log_err("cannot find control \'%s\'", name); return; } type = mixer_ctl_get_type(ctl); num_values = mixer_ctl_get_num_values(ctl); if(isdigit(value[0])) { int val = atoi(value); for(i = 0; i < num_values; i++) { if(mixer_ctl_set_value(ctl, i, val)) { log_err("value %d not accepted for %s", val, name); return; } } } else if(type == MIXER_CTL_TYPE_ENUM) { if(mixer_ctl_set_enum_by_string(ctl, value)) log_err("value %s not accepted for %s", value, name); } else if(type == MIXER_CTL_TYPE_BOOL) { if(strcasecmp(value,"on") == 0) i = 1; else if(strcasecmp(value, "off") == 0) i = 0; else { log_err("cannot set %s to \'%s\', on/off or 1/0 expected", name, value); return; } if(mixer_ctl_set_value(ctl, 0, i)) log_err("value %d not accepted for %s", i, name); } else log_err("type mismatch for %s, ignored", name); }
static int set_clocks_enabled(bool enable) { enum mixer_ctl_type type; struct mixer_ctl *ctl; struct mixer *mixer = mixer_open(0); if (mixer == NULL) { ALOGE("Error opening mixer 0"); return -1; } ctl = mixer_get_ctl_by_name(mixer, AMP_MIXER_CTL); if (ctl == NULL) { mixer_close(mixer); ALOGE("%s: Could not find %s\n", __func__, AMP_MIXER_CTL); return -ENODEV; } type = mixer_ctl_get_type(ctl); if (type != MIXER_CTL_TYPE_ENUM) { ALOGE("%s: %s is not supported\n", __func__, AMP_MIXER_CTL); mixer_close(mixer); return -ENOTTY; } mixer_ctl_set_value(ctl, 0, enable); mixer_close(mixer); return 0; }
size_t actlstr(char *buf, size_t n, char *ch, struct mixer *mx) { size_t ret; char *status; struct mixer_ctl *ctl; if (!(ctl = mixer_get_ctl_by_name(mx, ch))) { mixer_close(mx); die("couldn't find mixer ctl '%s'\n", ch); } switch (mixer_ctl_get_type(ctl)) { case MIXER_CTL_TYPE_INT: if ((ret = snprintf(buf, n, "%d%%", mixer_ctl_get_percent(ctl, 0))) > n) ret = n; break; case MIXER_CTL_TYPE_BOOL: status = mixer_ctl_get_value(ctl, 0) ? "On" : "Off"; ret = stpncpy(buf, status, n) - buf; break; default: mixer_close(mx); die("unsupported ctl type '%s'\n", mixer_ctl_get_type_string(ctl)); }; return ret; }
void mixer_ctl_set(struct mixer *mixer, const char *name, int val) { struct mixer_ctl *ctl = mixer_get_ctl_by_name(mixer, name); int ret = mixer_ctl_set_value(ctl, 0, val); if (ret != 0) LOGE("Failed to set %s to %d\n", name, val); mixer_ctl_set_value(ctl, 1, val); }
static void tinymix_detail_control(struct mixer *mixer, const char *control, int print_all) { struct mixer_ctl *ctl; enum mixer_ctl_type type; unsigned int num_values; unsigned int i; int min, max; if (isdigit(control[0])) ctl = mixer_get_ctl(mixer, atoi(control)); else ctl = mixer_get_ctl_by_name(mixer, control); if (!ctl) { fprintf(stderr, "Invalid mixer control\n"); return; } type = mixer_ctl_get_type(ctl); num_values = mixer_ctl_get_num_values(ctl); if (print_all) printf("%s:", mixer_ctl_get_name(ctl)); for (i = 0; i < num_values; i++) { switch (type) { case MIXER_CTL_TYPE_INT: printf(" %d", mixer_ctl_get_value(ctl, i)); break; case MIXER_CTL_TYPE_BOOL: printf(" %s", mixer_ctl_get_value(ctl, i) ? "On" : "Off"); break; case MIXER_CTL_TYPE_ENUM: tinymix_print_enum(ctl, print_all); break; case MIXER_CTL_TYPE_BYTE: printf(" 0x%02x", mixer_ctl_get_value(ctl, i)); break; default: printf(" unknown"); break; }; } if (print_all) { if (type == MIXER_CTL_TYPE_INT) { min = mixer_ctl_get_range_min(ctl); max = mixer_ctl_get_range_max(ctl); printf(" (range %d->%d)", min, max); } } printf("\n"); }
static bool setMixerValue(struct mixer* mixer, const char* name, const char* values) { if (!mixer) { ALOGE("no mixer in setMixerValue"); return false; } struct mixer_ctl *ctl = mixer_get_ctl_by_name(mixer, name); if (!ctl) { ALOGE("mixer_get_ctl_by_name failed for %s", name); return false; } enum mixer_ctl_type type = mixer_ctl_get_type(ctl); int numValues = mixer_ctl_get_num_values(ctl); int intValue; char stringValue[MAX_LINE_LENGTH]; for (int i = 0; i < numValues && values; i++) { // strip leading space while (*values == ' ') values++; if (*values == 0) break; switch (type) { case MIXER_CTL_TYPE_BOOL: case MIXER_CTL_TYPE_INT: if (sscanf(values, "%d", &intValue) == 1) { if (mixer_ctl_set_value(ctl, i, intValue) != 0) { ALOGE("mixer_ctl_set_value failed for %s %d", name, intValue); } } else { ALOGE("Could not parse %s as int for %s", values, name); } break; case MIXER_CTL_TYPE_ENUM: if (sscanf(values, "%s", stringValue) == 1) { if (mixer_ctl_set_enum_by_string(ctl, stringValue) != 0) { ALOGE("mixer_ctl_set_enum_by_string failed for %s %s", name, stringValue); } } else { ALOGE("Could not parse %s as enum for %s", values, name); } break; default: ALOGE("unsupported mixer type %d for %s", type, name); break; } values = strchr(values, ' '); } return true; }
static int SetAudio_gain_4eng(struct audio_pga *pga, pga_gain_nv_t *pga_gain_nv, AUDIO_TOTAL_T *aud_params_ptr) { int card_id = 0; int32_t lmode = 0; struct mixer *mixer = NULL; struct mixer_ctl *pa_config_ctl = NULL; ALOGD("vb_pga.c %s", __func__); if((NULL == aud_params_ptr) || (NULL == pga_gain_nv) || (NULL == pga)){ ALOGE("%s aud_params_ptr or pga_gain_nv or audio_pga is NULL",__func__); return -1; } card_id = get_snd_card_number(CARD_SPRDPHONE); if (card_id < 0){ ALOGE("%s get_snd_card_number error(%d)",__func__,card_id); return -1; } mixer = mixer_open(card_id); if (!mixer) { ALOGE("%s Unable to open the mixer, aborting.",__func__); return -1; } pa_config_ctl = mixer_get_ctl_by_name(mixer, MIXER_CTL_INNER_PA_CONFIG); lmode = GetAudio_mode_number_from_nv(aud_params_ptr); ALOGD("vb_pga.c %s, mode: %d", __func__, lmode); if(0 == lmode){ //Headset audio_pga_apply(pga,pga_gain_nv->fm_pga_gain_l,"linein-hp-l"); audio_pga_apply(pga,pga_gain_nv->fm_pga_gain_r,"linein-hp-r"); audio_pga_apply(pga,pga_gain_nv->dac_pga_gain_l,"headphone-l"); audio_pga_apply(pga,pga_gain_nv->dac_pga_gain_r,"headphone-r"); audio_pga_apply(pga,pga_gain_nv->adc_pga_gain_l,"capture-l"); audio_pga_apply(pga,pga_gain_nv->adc_pga_gain_r,"capture-r"); }else if(1 == lmode){ //Headfree audio_pga_apply(pga,pga_gain_nv->dac_pga_gain_l,"headphone-spk-l"); audio_pga_apply(pga,pga_gain_nv->dac_pga_gain_r,"headphone-spk-r"); mixer_ctl_set_value(pa_config_ctl, 0, pga_gain_nv->pa_config); }else if(2 == lmode){ //Handset audio_pga_apply(pga,pga_gain_nv->dac_pga_gain_l,"earpiece"); audio_pga_apply(pga,pga_gain_nv->adc_pga_gain_l,"capture-l"); audio_pga_apply(pga,pga_gain_nv->adc_pga_gain_r,"capture-r"); }else if(3 == lmode){ //Handsfree audio_pga_apply(pga,pga_gain_nv->fm_pga_gain_l,"linein-spk-l"); audio_pga_apply(pga,pga_gain_nv->fm_pga_gain_r,"linein-spk-r"); audio_pga_apply(pga,pga_gain_nv->dac_pga_gain_l,"speaker-l"); audio_pga_apply(pga,pga_gain_nv->dac_pga_gain_r,"speaker-r"); mixer_ctl_set_value(pa_config_ctl, 0, pga_gain_nv->pa_config); audio_pga_apply(pga,pga_gain_nv->adc_pga_gain_l,"capture-l"); audio_pga_apply(pga,pga_gain_nv->adc_pga_gain_r,"capture-r"); } mixer_close(mixer); ALOGW("%s, set cp mode(0x%x) ",__func__,lmode); return 0; }
/// Speaker over current test int AudioFtm::Audio_READ_SPK_OC_STA(void) { ALOGD("%s()", __FUNCTION__); struct mixer_ctl *ctl; int retval, dValue; ctl = mixer_get_ctl_by_name(mMixer, "Audio_Speaker_OC_Falg"); if (NULL == ctl) { ALOGD("[%s] [%d]", __FUNCTION__, __LINE__); return true; //true means SPK OC fail } dValue = mixer_ctl_get_value(ctl, 0); ALOGD("-%s() value [0x%x]", __FUNCTION__, dValue); return dValue; }
static void send_app_type_cfg(void *platform, struct mixer *mixer, struct listnode *streams_output_cfg_list) { int app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT] = {-1}; int length = 0, i, num_app_types = 0; struct listnode *node; bool update; struct mixer_ctl *ctl = NULL; const char *mixer_ctl_name = "App Type Config"; struct streams_output_cfg *so_info; if (!mixer) { ALOGE("%s: mixer is null",__func__); return; } ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name); if (!ctl) { ALOGE("%s: Could not get ctl for mixer cmd - %s",__func__, mixer_ctl_name); return; } if (streams_output_cfg_list == NULL) { app_type_cfg[length++] = 1; app_type_cfg[length++] = platform_get_default_app_type(platform); app_type_cfg[length++] = 48000; app_type_cfg[length++] = 16; mixer_ctl_set_array(ctl, app_type_cfg, length); return; } app_type_cfg[length++] = num_app_types; list_for_each(node, streams_output_cfg_list) { so_info = node_to_item(node, struct streams_output_cfg, list); update = true; for (i=0; i<length; i=i+3) { if (app_type_cfg[i+1] == -1) break; else if (app_type_cfg[i+1] == so_info->app_type_cfg.app_type) { update = false; break; } } if (update && ((length + 3) <= MAX_LENGTH_MIXER_CONTROL_IN_INT)) { num_app_types += 1 ; app_type_cfg[length++] = so_info->app_type_cfg.app_type; app_type_cfg[length++] = so_info->app_type_cfg.sample_rate; app_type_cfg[length++] = so_info->app_type_cfg.bit_width; } }
status_t AudioALSACodecDeviceOutSpeakerEarphonePMIC::close() { ALOGD("+%s(), mClientCount = %d", __FUNCTION__, mClientCount); mClientCount--; if (mClientCount == 0) { if (mixer_ctl_set_enum_by_string(mixer_get_ctl_by_name(mMixer, "Headset_Speaker_Amp_Switch"), "Off")) { ALOGE("Error: Audio_Amp_R_Switch invalid value"); } } ALOGD("-%s(), mClientCount = %d", __FUNCTION__, mClientCount); return NO_ERROR; }
static bool do_set_volume(struct mixer *mixer, const char *name, unsigned volume) { struct mixer_ctl *ctl; unsigned i; ctl = mixer_get_ctl_by_name(mixer, name); if (! ctl) { fprintf(stderr, "Failed to find control: %s\n", name); mixer_close(mixer); return false; } for (i = 0; i < mixer_ctl_get_num_values(ctl); i++) { mixer_ctl_set_percent(ctl, i, volume); } return true; }
bool AudioFtm::ReadAuxadcData(int channel, int *value) { struct mixer_ctl *ctl; int retval, dValue; channel = 0x001B; //AUX_SPK_THR_I_AP include mt_pmic.h ALOGD("+%s() channel [0x%x] (force to replace)", __FUNCTION__, channel); ctl = mixer_get_ctl_by_name(mMixer, "Audio AUXADC Data"); if (NULL == ctl || NULL == value) { ALOGD("[%s] [%d]", __FUNCTION__, __LINE__); return false; } retval = mixer_ctl_set_value(ctl, 0, channel); usleep(1000); dValue = mixer_ctl_get_value(ctl, 0); *value = dValue; ALOGD("-%s() value [0x%x]", __FUNCTION__, dValue); return false; }
static int set_stream_app_type_mixer_ctrl(struct audio_device *adev, int pcm_device_id, int app_type, int acdb_dev_id, int sample_rate, int stream_type, snd_device_t snd_device) { char mixer_ctl_name[MAX_LENGTH_MIXER_CONTROL_IN_INT]; struct mixer_ctl *ctl; int app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT], len = 0, rc = 0; int snd_device_be_idx = -1; if (stream_type == PCM_PLAYBACK) { snprintf(mixer_ctl_name, sizeof(mixer_ctl_name), "Audio Stream %d App Type Cfg", pcm_device_id); } else if (stream_type == PCM_CAPTURE) { snprintf(mixer_ctl_name, sizeof(mixer_ctl_name), "Audio Stream Capture %d App Type Cfg", pcm_device_id); } ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name); if (!ctl) { ALOGE("%s: Could not get ctl for mixer cmd - %s", __func__, mixer_ctl_name); rc = -EINVAL; goto exit; } app_type_cfg[len++] = app_type; app_type_cfg[len++] = acdb_dev_id; app_type_cfg[len++] = sample_rate; snd_device_be_idx = platform_get_snd_device_backend_index(snd_device); if (snd_device_be_idx > 0) app_type_cfg[len++] = snd_device_be_idx; ALOGV("%s: stream type %d app_type %d, acdb_dev_id %d " "sample rate %d, snd_device_be_idx %d", __func__, stream_type, app_type, acdb_dev_id, sample_rate, snd_device_be_idx); mixer_ctl_set_array(ctl, app_type_cfg, len); exit: return rc; }
status_t AudioALSACodecDeviceOutSpeakerPMIC::close() { ALOGD("+%s(), mClientCount = %d", __FUNCTION__, mClientCount); mClientCount--; if (mClientCount == 0) { if (mixer_ctl_set_enum_by_string(mixer_get_ctl_by_name(mMixer, "Speaker_Amp_Switch"), "Off")) { ALOGE("Error: Speaker_Amp_Switch invalid value"); } #if defined(MTK_SPEAKER_MONITOR_SUPPORT) //AudioALSASpeakerMonitor::getInstance()->EnableSpeakerMonitorThread(false); AudioALSASpeakerMonitor::getInstance()->Deactivate(); #endif } ALOGD("-%s(), mClientCount = %d", __FUNCTION__, mClientCount); return NO_ERROR; }
void audio_extn_utils_send_default_app_type_cfg(void *platform, struct mixer *mixer) { int app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT] = {-1}; int length = 0, app_type = 0,rc = 0; struct mixer_ctl *ctl = NULL; const char *mixer_ctl_name = "App Type Config"; ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name); if (!ctl) { ALOGE("%s: Could not get ctl for mixer cmd - %s",__func__, mixer_ctl_name); return; } rc = platform_get_default_app_type_v2(platform, PCM_PLAYBACK, &app_type); if (rc == 0) { app_type_cfg[length++] = 1; app_type_cfg[length++] = app_type; app_type_cfg[length++] = 48000; app_type_cfg[length++] = 16; mixer_ctl_set_array(ctl, app_type_cfg, length); } return; }
status_t AudioALSAPlaybackHandlerSphDL::close() { ALOGD("+%s()", __FUNCTION__); // close codec driver // Don't stopoutputDevice here, let speech driver to open. mHardwareResourceManager->stopOutputDevice(); //Echo reference path if (mixer_ctl_set_enum_by_string(mixer_get_ctl_by_name(mMixer, "Audio_Dl1_MD_Echo_Ref_Switch"), "Off")) { ALOGE("Error: Audio_Dl1_MD_Echo_Ref_Switch invalid value"); } // close pcm driver closePcmDriver(); // bit conversion deinitBitConverter(); // SRC deinitBliSrc(); // post processing deinitPostProcessing(); // debug pcm dump ClosePCMDump(); ALOGD("-%s()", __FUNCTION__); return NO_ERROR; }
status_t AudioALSAPlaybackHandlerSphDL::open() { ALOGD("+%s(), mDevice = 0x%x", __FUNCTION__, mStreamAttributeSource->output_devices); // debug pcm dump OpenPCMDump(LOG_TAG); int pcmindex = AudioALSADeviceParser::getInstance()->GetPcmIndexByString(keypcmI2S0Dl1Playback); int cardindex = AudioALSADeviceParser::getInstance()->GetCardIndexByString(keypcmI2S0Dl1Playback); ALOGD("AudioALSAPlaybackHandlerSphDL::open() pcmindex = %d", pcmindex); ListPcmDriver(cardindex, pcmindex); struct pcm_params *params; params = pcm_params_get(cardindex, pcmindex, PCM_OUT); if (params == NULL) { ALOGD("Device does not exist.\n"); } mStreamAttributeTarget.buffer_size = pcm_params_get_max(params, PCM_PARAM_BUFFER_BYTES); ALOGD("buffersizemax = %d", mStreamAttributeTarget.buffer_size); pcm_params_free(params); // HW attribute config // TODO(Harvey): query this mStreamAttributeTarget.audio_format = AUDIO_FORMAT_PCM_16_BIT; mStreamAttributeTarget.audio_channel_mask = AUDIO_CHANNEL_IN_MONO; mStreamAttributeTarget.num_channels = android_audio_legacy::AudioSystem::popCount(mStreamAttributeTarget.audio_channel_mask); mStreamAttributeTarget.sample_rate = mStreamAttributeSource->sample_rate; // same as source stream // HW pcm config mConfig.channels = mStreamAttributeTarget.num_channels; mConfig.rate = mStreamAttributeTarget.sample_rate; // Buffer size: 1536(period_size) * 2(ch) * 4(byte) * 2(period_count) = 24 kb mConfig.period_count = 4; //mConfig.period_size = (0x4000/(mConfig.channels*mConfig.period_count))/((mStreamAttributeTarget.audio_format == AUDIO_FORMAT_PCM_16_BIT) ? 2 : 4); mConfig.period_size = 512; mConfig.format = transferAudioFormatToPcmFormat(mStreamAttributeTarget.audio_format); mConfig.start_threshold = 0; mConfig.stop_threshold = 0; mConfig.silence_threshold = 0; ALOGD("%s(), mConfig: channels = %d, rate = %d, period_size = %d, period_count = %d, format = %d", __FUNCTION__, mConfig.channels, mConfig.rate, mConfig.period_size, mConfig.period_count, mConfig.format); // post processing initPostProcessing(); #if defined(MTK_SPEAKER_MONITOR_SUPPORT) unsigned int fc, bw; int th; if (mAudioFilterManagerHandler) { AudioALSASpeakerMonitor::getInstance()->GetFilterParam(&fc, &bw, &th); ALOGD("%s(), fc %d bw %d, th %d", __FUNCTION__, fc, bw, th); mAudioFilterManagerHandler->setSpkFilterParam(fc, bw, th); } #endif // SRC initBliSrc(); // bit conversion initBitConverter(); // open pcm driver openPcmDriver(pcmindex); //Echo reference path if (mixer_ctl_set_enum_by_string(mixer_get_ctl_by_name(mMixer, "Audio_Dl1_MD_Echo_Ref_Switch"), "On")) { ALOGE("Error: Audio_Dl1_MD_Echo_Ref_Switch invalid value"); } // open codec driver // Don't startoutputDevice here, let speech driver to open. mHardwareResourceManager->startOutputDevice(mStreamAttributeSource->output_devices, mStreamAttributeTarget.sample_rate); ALOGD("-%s()", __FUNCTION__); return NO_ERROR; }
static int adev_open(const hw_module_t* module, const char* name, hw_device_t** device) { #if 0 //TARGET_AUDIO_PRIMARY struct mixer *mixer; struct mixer_ctl *ctl; #endif if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL; struct audio_device *adev = calloc(1, sizeof(struct audio_device)); if (!adev) return -ENOMEM; profile_init(&adev->out_profile, PCM_OUT); profile_init(&adev->in_profile, PCM_IN); adev->hw_device.common.tag = HARDWARE_DEVICE_TAG; adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0; adev->hw_device.common.module = (struct hw_module_t *)module; adev->hw_device.common.close = adev_close; adev->hw_device.init_check = adev_init_check; adev->hw_device.set_voice_volume = adev_set_voice_volume; adev->hw_device.set_master_volume = adev_set_master_volume; adev->hw_device.set_mode = adev_set_mode; adev->hw_device.set_mic_mute = adev_set_mic_mute; adev->hw_device.get_mic_mute = adev_get_mic_mute; adev->hw_device.set_parameters = adev_set_parameters; adev->hw_device.get_parameters = adev_get_parameters; adev->hw_device.get_input_buffer_size = adev_get_input_buffer_size; adev->hw_device.open_output_stream = adev_open_output_stream; adev->hw_device.close_output_stream = adev_close_output_stream; adev->hw_device.open_input_stream = adev_open_input_stream; adev->hw_device.close_input_stream = adev_close_input_stream; adev->hw_device.dump = adev_dump; *device = &adev->hw_device.common; #if 0 //TARGET_AUDIO_PRIMARY mixer = mixer_open(0); if (mixer) { /* setting master volume to value 50 */ adev->master_volume = 50; int ret = 0; ctl = mixer_get_ctl_by_name(mixer, "HP Playback Switch"); ret = mixer_ctl_set_value(ctl,0,1); ret = mixer_ctl_set_value(ctl,1,1); ctl = mixer_get_ctl_by_name(mixer, "HP Playback Volume"); mixer_ctl_set_value(ctl,0,adjust_volume(adev->master_volume)); mixer_ctl_set_value(ctl,1,adjust_volume(adev->master_volume)); ctl = mixer_get_ctl_by_name(mixer, "HPO MIX DAC1 Switch"); mixer_ctl_set_value(ctl,0,1); ctl = mixer_get_ctl_by_name(mixer, "HPO MIX DAC1 Switch"); mixer_ctl_set_value(ctl,0,1); ctl = mixer_get_ctl_by_name(mixer, "OUT MIXR DAC R1 Switch"); mixer_ctl_set_value(ctl,0,1); ctl = mixer_get_ctl_by_name(mixer, "OUT MIXL DAC L1 Switch"); mixer_ctl_set_value(ctl,0,1); ctl = mixer_get_ctl_by_name(mixer, "Stereo DAC MIXR DAC R1 Switch"); mixer_ctl_set_value(ctl,0,1); ctl = mixer_get_ctl_by_name(mixer, "Stereo DAC MIXL DAC L1 Switch"); mixer_ctl_set_value(ctl,0,1); mixer_close(mixer); } #endif return 0; }
bool HDMIAudioCaps::loadCaps(int ALSADeviceID) { bool ret = false; struct mixer* mixer = NULL; struct mixer_ctl* ctrls[kCtrlCount] = {NULL}; int tmp, mode_cnt; Mutex::Autolock _l(mLock); ALOGE("%s: start", __func__); reset_l(); // Open the mixer for the chosen ALSA device if (NULL == (mixer = mixer_open(ALSADeviceID))) { ALOGE("%s: mixer_open(%d) failed", __func__, ALSADeviceID); goto bailout; } // Gather handles to all of the controls we will need in order to enumerate // the audio capabilities of this HDMI link. No need to free/release these // later, they are just pointers into the tinyalsa mixer structure itself. for (size_t i = 0; i < kCtrlCount; ++i) { ctrls[i] = mixer_get_ctl_by_name(mixer, kCtrlNames[i]); if (NULL == ctrls[i]) { ALOGE("%s: mixer_get_ctrl_by_name(%s) failed", __func__, kCtrlNames[i]); goto bailout; } } // Start by checking to see if this HDMI connection supports even basic // audio. If it does not, there is no point in proceeding. if ((tmp = mixer_ctl_get_value(ctrls[kBasicAudNdx], 0)) <= 0) { ALOGI("%s: Basic audio not supported by attached device", __func__); goto bailout; } // Looks like we support basic audio. Get a count of the available // non-basic modes. mBasicAudioSupported = true; if ((mode_cnt = mixer_ctl_get_value(ctrls[kModeCntNdx], 0)) < 0) goto bailout; // Fetch the speaker allocation data block, if available. if ((tmp = mixer_ctl_get_value(ctrls[kSpeakerAlloc], 0)) < 0) goto bailout; mSpeakerAlloc = static_cast<uint16_t>(tmp); ALOGI("%s: Speaker Allocation Map for attached device is: 0x%hx", __func__, mSpeakerAlloc); // If there are no non-basic modes available, then we are done. Be sure to // flag this as a successful operation. if (!mode_cnt) { ret = true; goto bailout; } // Now enumerate the non-basic modes. Any errors at this point in time // should indicate that the HDMI cable was unplugged and we should just // abort with an empty set of audio capabilities. for (int i = 0; i < mode_cnt; ++i) { Mode m; // Pick the mode we want to fetch info for. if (mixer_ctl_set_value(ctrls[kModeSelNdx], 0, i) < 0) goto bailout; // Now fetch the common fields. if ((tmp = mixer_ctl_get_value(ctrls[kFmtNdx], 0)) < 0) goto bailout; m.fmt = static_cast<AudFormat>(tmp); ALOGI("Got mode %d from ALSA driver.", m.fmt); if ((tmp = mixer_ctl_get_value(ctrls[kMaxChCntNdx], 0)) < 0) goto bailout; m.max_ch = static_cast<uint32_t>(tmp); if ((tmp = mixer_ctl_get_value(ctrls[kSampRateNdx], 0)) < 0) goto bailout; m.sr_bitmask = static_cast<uint32_t>(tmp); // Now for the mode dependent fields. Only LPCM has the bits-per-sample // mask. Only AC3 through ATRAC have the compressed bitrate field. m.bps_bitmask = 0; m.comp_bitrate = 0; if (m.fmt == kFmtLPCM) { if ((tmp = mixer_ctl_get_value(ctrls[kBPSNdx], 0)) < 0) goto bailout; m.bps_bitmask = static_cast<uint32_t>(tmp); } else if ((m.fmt >= kFmtAC3) && (m.fmt <= kFmtATRAC)) { // FIXME ATRAC is not last format!? if ((tmp = mixer_ctl_get_value(ctrls[kMaxCompBRNdx], 0)) < 0) goto bailout; m.comp_bitrate = static_cast<uint32_t>(tmp); } // Finally, sanity check the info. If it passes, add it to the vector // of available modes. if (sanityCheckMode(m)) { ALOGI("Passed sanity check for mode %d from ALSA driver.", m.fmt); mModes.add(m); } } // Looks like we managed to enumerate all of the modes before someone // unplugged the HDMI cable. Signal success and get out. ret = true; bailout: if (NULL != mixer) mixer_close(mixer); if (!ret) reset_l(); return ret; }
static void start_tag(void *data, const XML_Char *tag_name, const XML_Char **attr) { const XML_Char *attr_name = NULL; const XML_Char *attr_id = NULL; const XML_Char *attr_value = NULL; struct config_parse_state *state = data; struct audio_route *ar = state->ar; unsigned int i; unsigned int ctl_index; struct mixer_ctl *ctl; int value; unsigned int id; struct mixer_value mixer_value; /* Get name, id and value attributes (these may be empty) */ for (i = 0; attr[i]; i += 2) { if (strcmp(attr[i], "name") == 0) attr_name = attr[i + 1]; if (strcmp(attr[i], "id") == 0) attr_id = attr[i + 1]; else if (strcmp(attr[i], "value") == 0) attr_value = attr[i + 1]; } /* Look at tags */ if (strcmp(tag_name, "path") == 0) { if (attr_name == NULL) { ALOGE("Unnamed path!"); } else { if (state->level == 1) { /* top level path: create and stash the path */ state->path = path_create(ar, (char *)attr_name); } else { /* nested path */ struct mixer_path *sub_path = path_get_by_name(ar, attr_name); path_add_path(ar, state->path, sub_path); } } } else if (strcmp(tag_name, "ctl") == 0) { /* Obtain the mixer ctl and value */ ctl = mixer_get_ctl_by_name(ar->mixer, attr_name); if (ctl == NULL) { ALOGE("Control '%s' doesn't exist - skipping", attr_name); goto done; } switch (mixer_ctl_get_type(ctl)) { case MIXER_CTL_TYPE_BOOL: case MIXER_CTL_TYPE_INT: value = atoi((char *)attr_value); break; case MIXER_CTL_TYPE_ENUM: value = mixer_enum_string_to_value(ctl, (char *)attr_value); break; default: value = 0; break; } /* locate the mixer ctl in the list */ for (ctl_index = 0; ctl_index < ar->num_mixer_ctls; ctl_index++) { if (ar->mixer_state[ctl_index].ctl == ctl) break; } if (state->level == 1) { /* top level ctl (initial setting) */ /* apply the new value */ if (attr_id) { /* set only one value */ id = atoi((char *)attr_id); if (id < ar->mixer_state[ctl_index].num_values) ar->mixer_state[ctl_index].new_value[id] = value; else ALOGE("value id out of range for mixer ctl '%s'", mixer_ctl_get_name(ctl)); } else { /* set all values the same */ for (i = 0; i < ar->mixer_state[ctl_index].num_values; i++) ar->mixer_state[ctl_index].new_value[i] = value; } } else { /* nested ctl (within a path) */ mixer_value.ctl_index = ctl_index; mixer_value.value = value; if (attr_id) mixer_value.index = atoi((char *)attr_id); else mixer_value.index = -1; path_add_value(ar, state->path, &mixer_value); } } done: state->level++; }
static void tinymix_detail_control(struct mixer *mixer, const char *control, int print_all) { struct mixer_ctl *ctl; enum mixer_ctl_type type; unsigned int num_values; unsigned int i; int min, max; int ret; char *buf = NULL; if (isdigit(control[0])) ctl = mixer_get_ctl(mixer, atoi(control)); else ctl = mixer_get_ctl_by_name(mixer, control); if (!ctl) { fprintf(stderr, "Invalid mixer control\n"); return; } type = mixer_ctl_get_type(ctl); num_values = mixer_ctl_get_num_values(ctl); if ((type == MIXER_CTL_TYPE_BYTE) && (num_values > 0)) { buf = calloc(1, num_values); if (buf == NULL) { fprintf(stderr, "Failed to alloc mem for bytes %d\n", num_values); return; } ret = mixer_ctl_get_array(ctl, buf, num_values); if (ret < 0) { fprintf(stderr, "Failed to mixer_ctl_get_array\n"); free(buf); return; } } if (print_all) printf("%s:", mixer_ctl_get_name(ctl)); for (i = 0; i < num_values; i++) { switch (type) { case MIXER_CTL_TYPE_INT: printf(" %d", mixer_ctl_get_value(ctl, i)); break; case MIXER_CTL_TYPE_BOOL: printf(" %s", mixer_ctl_get_value(ctl, i) ? "On" : "Off"); break; case MIXER_CTL_TYPE_ENUM: tinymix_print_enum(ctl, print_all); break; case MIXER_CTL_TYPE_BYTE: printf("%02x", buf[i]); break; default: printf(" unknown"); break; }; } if (print_all) { if (type == MIXER_CTL_TYPE_INT) { min = mixer_ctl_get_range_min(ctl); max = mixer_ctl_get_range_max(ctl); printf(" (range %d->%d)", min, max); } } free(buf); printf("\n"); }
bool TinyAmixerControl::accessHW(bool receive, std::string &error) { CAutoLog autoLog(getConfigurableElement(), "ALSA", isDebugEnabled()); // Mixer handle struct mixer *mixer; // Mixer control handle struct mixer_ctl *mixerControl; uint32_t elementCount; std::string controlName = getControlName(); // Debug conditionnaly enabled in XML logControlInfo(receive); // Check parameter type is ok (deferred error, no exceptions available :-() if (!isTypeSupported()) { error = "Parameter type not supported."; return false; } // Check card number int32_t cardIndex = getCardNumber(); if (cardIndex < 0) { error = "Card " + getCardName() + " not found. Error: " + strerror(-cardIndex); return false; } // Open alsa mixer // getMixerHandle is non-const; we need to forcefully remove the constness // then, we need to cast the generic subsystem into a TinyAlsaSubsystem. mixer = static_cast<TinyAlsaSubsystem *>( const_cast<CSubsystem *>(getSubsystem()))->getMixerHandle(cardIndex); if (!mixer) { error = "Failed to open mixer for card: " + getCardName(); return false; } // Get control handle if (isdigit(controlName[0])) { mixerControl = mixer_get_ctl(mixer, asInteger(controlName)); } else { mixerControl = mixer_get_ctl_by_name(mixer, controlName.c_str()); } // Check control has been found if (!mixerControl) { error = "Failed to open mixer control: " + controlName; return false; } // Get element count elementCount = getNumValues(mixerControl); uint32_t scalarSize = getScalarSize(); // Check available size if (elementCount * scalarSize != getSize()) { error = "ALSA: Control element count (" + asString(elementCount) + ") and configurable scalar element count (" + asString(getSize() / scalarSize) + ") mismatch"; return false; } // Read/Write element bool success; if (receive) { success = readControl(mixerControl, elementCount, error); } else { success = writeControl(mixerControl, elementCount, error); } return success; }
static void start_tag(void *data, const XML_Char *tag_name, const XML_Char **attr) { const XML_Char *attr_name = NULL; const XML_Char *attr_value = NULL; const XML_Char *attr_ignore = NULL; char *sub_attr_value; struct config_parse_state *state = data; struct audio_route *ar = state->ar; unsigned int i; unsigned int j; unsigned int k; struct mixer_ctl *ctl; int values[MAX_CTL_VALS]; unsigned int num_values; unsigned int num_ctl_vals; struct mixer_setting mixer_setting; unsigned ignored = 0; /* Get name, type and value attributes (these may be empty) */ for (i = 0; attr[i]; i += 2) { if (strcmp(attr[i], "name") == 0) attr_name = attr[i + 1]; else if (strcmp(attr[i], "value") == 0) attr_value = attr[i + 1]; else if (strcmp(attr[i], "ignore") == 0) attr_ignore = attr[i + 1]; } if (attr_ignore && strcmp(attr_ignore, "1") == 0) { ignored = 1; } /* Look at tags */ if (strcmp(tag_name, "path") == 0) { if (attr_name == NULL) { ALOGE("Unnamed path!"); } else { if (state->level == 1) { /* top level path: create and stash the path */ state->path = path_create(ar, (char *)attr_name); } else { /* nested path */ struct mixer_path *sub_path = path_get_by_name(ar, attr_name); path_add_path(state->path, sub_path); } } } else if (strcmp(tag_name, "ctl") == 0 && state->level == 1 && ignored) { /* Obtain the mixer ctl and value */ ctl = mixer_get_ctl_by_name(ar->mixer, attr_name); /* locate the mixer ctl in the list */ for (i = 0; i < ar->num_mixer_ctls; i++) { if (ar->mixer_state[i].ctl == ctl) break; } ar->mixer_state[i].ignored = 1; } else if (strcmp(tag_name, "ctl") == 0) { /* Obtain the mixer ctl and value */ ctl = mixer_get_ctl_by_name(ar->mixer, attr_name); switch (mixer_ctl_get_type(ctl)) { case MIXER_CTL_TYPE_BOOL: case MIXER_CTL_TYPE_INT: /* TODO */ num_values = 1; char *sub_attr_value; for (j = 0; j < strlen((char*)attr_value); j++) { if (attr_value[j] == ',') num_values++; } sub_attr_value = (char*)attr_value; k = strlen((char*)attr_value); for (j = 0; j < k; j++) { if (sub_attr_value[j] == ',') sub_attr_value[j] = '\0'; } sub_attr_value = (char*)attr_value; for (j = 0; j < num_values; j++) { values[j] = atoi(sub_attr_value); #if 1 ALOGV("attr='%s' idx=%u str='%s' val=%d", attr_name, j, sub_attr_value, values[j]); #endif sub_attr_value += (strlen(sub_attr_value) + 1); } break; case MIXER_CTL_TYPE_ENUM: num_values = 1; values[0] = mixer_enum_string_to_value(ctl, (char *)attr_value); ALOGV("attr='%s' attr_val='%s' val=%d", attr_name, attr_value, values[0]); break; default: num_values = 1; values[0] = 0; ALOGV("attr='%s' UNKNOWN CTL TYPE", attr_name); break; } if (state->level == 1) { /* top level ctl (initial setting) */ /* locate the mixer ctl in the list */ for (i = 0; i < ar->num_mixer_ctls; i++) { if (ar->mixer_state[i].ctl == ctl) break; } /* apply the new value */ ar->mixer_state[i].ignored = 0; ar->mixer_state[i].ctl_vals = num_values; for (j = 0; j < num_values; j++) { ar->mixer_state[i].new_value[j] = values[j]; } } else { /* nested ctl (within a path) */ mixer_setting.ctl = ctl; mixer_setting.ctl_vals = num_values; for (j = 0; j < num_values; j++) { mixer_setting.value[j] = values[j]; } path_add_setting(state->path, &mixer_setting); } } state->level++; }
static void tinymix_detail_control(struct mixer *mixer, const char *control, int print_all) { struct mixer_ctl *ctl; enum mixer_ctl_type type; unsigned int num_values; unsigned int i; int min, max; int ret; char buf[512] = { 0 }; size_t len; if (isdigit(control[0])) ctl = mixer_get_ctl(mixer, atoi(control)); else ctl = mixer_get_ctl_by_name(mixer, control); if (!ctl) { fprintf(stderr, "Invalid mixer control\n"); return; } type = mixer_ctl_get_type(ctl); num_values = mixer_ctl_get_num_values(ctl); if (type == MIXER_CTL_TYPE_BYTE) { len = num_values; if (len > sizeof(buf)) { fprintf(stderr, "Truncating get to %zu bytes\n", sizeof(buf)); len = sizeof(buf); } ret = mixer_ctl_get_array(ctl, buf, len); if (ret < 0) { fprintf(stderr, "Failed to mixer_ctl_get_array\n"); return; } } if (print_all) printf("%s:", mixer_ctl_get_name(ctl)); for (i = 0; i < num_values; i++) { switch (type) { case MIXER_CTL_TYPE_INT: printf(" %d", mixer_ctl_get_value(ctl, i)); break; case MIXER_CTL_TYPE_BOOL: printf(" %s", mixer_ctl_get_value(ctl, i) ? "On" : "Off"); break; case MIXER_CTL_TYPE_ENUM: tinymix_print_enum(ctl, print_all); break; case MIXER_CTL_TYPE_BYTE: printf("%02x", buf[i]); break; default: printf(" unknown"); break; }; } if (print_all) { if (type == MIXER_CTL_TYPE_INT) { min = mixer_ctl_get_range_min(ctl); max = mixer_ctl_get_range_max(ctl); printf(" (range %d->%d)", min, max); } } printf("\n"); }