author | Jian Xu <jian.xu@amlogic.com> | 2015-06-25 11:04:45 (GMT) |
---|---|---|
committer | Jian Xu <jian.xu@amlogic.com> | 2015-06-26 05:21:19 (GMT) |
commit | 6c039392cad2c396122cb279b110a09cec820071 (patch) | |
tree | 08bcd3ddbc24834b866f5347d1b3120521caa5c1 | |
parent | 7fdc6cc67b6c8ac7faca8348eca3e768ac083785 (diff) | |
download | audio-6c039392cad2c396122cb279b110a09cec820071.zip audio-6c039392cad2c396122cb279b110a09cec820071.tar.gz audio-6c039392cad2c396122cb279b110a09cec820071.tar.bz2 |
[audio] : fix audio raw data pass through hung up issue
Change-Id: I44efb463614939a9b539f2d5f562ddd881a0b20d
-rw-r--r-- | hdmi_audio_hw.c | 4254 |
1 files changed, 2290 insertions, 1964 deletions
diff --git a/hdmi_audio_hw.c b/hdmi_audio_hw.c index d534e36..e1a6cfd 100644 --- a/hdmi_audio_hw.c +++ b/hdmi_audio_hw.c @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -47,14 +47,14 @@ #include <audio_effects/effect_aec.h> /* ALSA cards for AML */ -#define CARD_AMLOGIC_BOARD 0 +#define CARD_AMLOGIC_BOARD 0 #define CARD_AMLOGIC_USB 1 -#define CARD_AMLOGIC_DEFAULT CARD_AMLOGIC_BOARD +#define CARD_AMLOGIC_DEFAULT CARD_AMLOGIC_BOARD /* ALSA ports for AML */ #define PORT_MM 1 /* number of frames per period */ -#define DEFAULT_PERIOD_SIZE 1024//(1024 * 2) -static unsigned PERIOD_SIZE = DEFAULT_PERIOD_SIZE; +#define DEFAULT_PERIOD_SIZE 1024 //(1024 * 2) +static unsigned PERIOD_SIZE = DEFAULT_PERIOD_SIZE; /* number of periods for low power playback */ #define PLAYBACK_PERIOD_COUNT 4 /* number of periods for capture */ @@ -66,7 +66,7 @@ static unsigned PERIOD_SIZE = DEFAULT_PERIOD_SIZE; #define RESAMPLER_BUFFER_FRAMES (PERIOD_SIZE * 6) #define RESAMPLER_BUFFER_SIZE (4 * RESAMPLER_BUFFER_FRAMES) -static unsigned int DEFAULT_OUT_SAMPLING_RATE = 48000; +static unsigned int DEFAULT_OUT_SAMPLING_RATE = 48000; /* sampling rate when using MM low power port */ #define MM_LOW_POWER_SAMPLING_RATE 44100 @@ -79,2297 +79,2623 @@ static unsigned int first_write_status; struct pcm_config pcm_config_out = { - .channels = 2, - .rate = MM_FULL_POWER_SAMPLING_RATE, - .period_size = DEFAULT_PERIOD_SIZE, - .period_count = PLAYBACK_PERIOD_COUNT, - .format = PCM_FORMAT_S16_LE, + .channels = 2, + .rate = MM_FULL_POWER_SAMPLING_RATE, + .period_size = DEFAULT_PERIOD_SIZE, + .period_count = PLAYBACK_PERIOD_COUNT, + .format = PCM_FORMAT_S16_LE, }; struct pcm_config pcm_config_in = { - .channels = 2, - .rate = MM_FULL_POWER_SAMPLING_RATE, - .period_size = DEFAULT_PERIOD_SIZE, - .period_count = PLAYBACK_PERIOD_COUNT, - .format = PCM_FORMAT_S16_LE, + .channels = 2, + .rate = MM_FULL_POWER_SAMPLING_RATE, + .period_size = DEFAULT_PERIOD_SIZE, + .period_count = PLAYBACK_PERIOD_COUNT, + .format = PCM_FORMAT_S16_LE, }; -struct aml_audio_device { - struct audio_hw_device hw_device; - - pthread_mutex_t lock; /* see note below on mutex acquisition order */ - int mode; - audio_devices_t in_device; - audio_devices_t out_device; - int in_call; - //int cur_devices; - struct pcm *pcm_modem_dl; - struct pcm *pcm_modem_ul; - struct aml_stream_in *active_input; - struct aml_stream_out *active_output; - - bool mic_mute; - struct echo_reference_itfe *echo_reference; - bool bluetooth_nrec; - bool low_power; - /* RIL */ - //struct ril_handle ril; +struct aml_audio_device +{ + struct audio_hw_device hw_device; + + pthread_mutex_t lock; /* see note below on mutex acquisition order */ + int mode; + audio_devices_t in_device; + audio_devices_t out_device; + int in_call; + //int cur_devices; + struct pcm *pcm_modem_dl; + struct pcm *pcm_modem_ul; + struct aml_stream_in *active_input; + struct aml_stream_out *active_output; + + bool mic_mute; + struct echo_reference_itfe *echo_reference; + bool bluetooth_nrec; + bool low_power; + /* RIL */ + //struct ril_handle ril; }; -struct aml_stream_out { - struct audio_stream_out stream; - pthread_mutex_t lock; /* see note below on mutex acquisition order */ - struct pcm_config config; - struct pcm *pcm; - struct resampler_itfe *resampler; - char *buffer; - int standby; - struct echo_reference_itfe *echo_reference; - struct aml_audio_device *dev; - int write_threshold; - bool low_power; - unsigned multich; +struct aml_stream_out +{ + struct audio_stream_out stream; + pthread_mutex_t lock; /* see note below on mutex acquisition order */ + struct pcm_config config; + struct pcm *pcm; + struct resampler_itfe *resampler; + char *buffer; + int standby; + struct echo_reference_itfe *echo_reference; + struct aml_audio_device *dev; + int write_threshold; + bool low_power; + unsigned multich; }; -#define MAX_PREPROCESSORS 3 /* maximum one AGC + one NS + one AEC per input stream */ -struct aml_stream_in { - struct audio_stream_in stream; - pthread_mutex_t lock; /* see note below on mutex acquisition order */ - struct pcm_config config; - struct pcm *pcm; - int device; - struct resampler_itfe *resampler; - struct resampler_itfe *up_resampler;//shuai - struct resampler_buffer_provider buf_provider; - char *up_resampler_buffer; - struct resampler_buffer_provider up_buf_provider; - int16_t *buffer; - size_t frames_in; - unsigned int requested_rate; - int standby; - int source; - struct echo_reference_itfe *echo_reference; - bool need_echo_reference; - effect_handle_t preprocessors[MAX_PREPROCESSORS]; - int num_preprocessors; - int16_t *proc_buf; - size_t proc_buf_size; - size_t proc_frames_in; - int16_t *ref_buf; - size_t ref_buf_size; - size_t ref_frames_in; - int read_status; - int voip_mode; - //hdmi in volume parameters - int volume_index; - float last_volume; - int indexMIn; - int indexMax; - - struct aml_audio_device *dev; +#define MAX_PREPROCESSORS 3 /* maximum one AGC + one NS + one AEC per input stream */ +struct aml_stream_in +{ + struct audio_stream_in stream; + pthread_mutex_t lock; /* see note below on mutex acquisition order */ + struct pcm_config config; + struct pcm *pcm; + int device; + struct resampler_itfe *resampler; + struct resampler_itfe *up_resampler; //shuai + struct resampler_buffer_provider buf_provider; + char *up_resampler_buffer; + struct resampler_buffer_provider up_buf_provider; + int16_t *buffer; + size_t frames_in; + unsigned int requested_rate; + int standby; + int source; + struct echo_reference_itfe *echo_reference; + bool need_echo_reference; + effect_handle_t preprocessors[MAX_PREPROCESSORS]; + int num_preprocessors; + int16_t *proc_buf; + size_t proc_buf_size; + size_t proc_frames_in; + int16_t *ref_buf; + size_t ref_buf_size; + size_t ref_frames_in; + int read_status; + int voip_mode; + //hdmi in volume parameters + int volume_index; + float last_volume; + int indexMIn; + int indexMax; + + struct aml_audio_device *dev; }; static char cache_buffer_bytes[64]; -static uint cached_len=0; -static void select_output_device(struct aml_audio_device *adev); -static void select_input_device(struct aml_audio_device *adev); -static int adev_set_voice_volume(struct audio_hw_device *dev, float volume); -static int do_input_standby(struct aml_stream_in *in); -static int do_output_standby(struct aml_stream_out *out); +static uint cached_len = 0; +static void select_output_device (struct aml_audio_device *adev); +static void select_input_device (struct aml_audio_device *adev); +static int adev_set_voice_volume (struct audio_hw_device *dev, float volume); +static int do_input_standby (struct aml_stream_in *in); +static int do_output_standby (struct aml_stream_out *out); // add compute hdmi in volume function, volume index between 0 and 15 ,this reference AudioPolicyManagerBase -enum { VOLMIN = 0, VOLKNEE1 = 1, VOLKNEE2 = 2, VOLMAX = 3, VOLCNT = 4}; +enum +{ VOLMIN = 0, VOLKNEE1 = 1, VOLKNEE2 = 2, VOLMAX = 3, VOLCNT = 4 }; struct VolumeCurvePoint { - int mIndex; - float mDBAttenuation; + int mIndex; + float mDBAttenuation; }; struct VolumeCurvePoint sSpeakerMediaVolumeCurve[VOLCNT] = { - {1, -56.0f}, {20, -34.0f}, {60, -11.0f}, {100, 0.0f} + {1, -56.0f}, {20, -34.0f}, {60, -11.0f}, {100, 0.0f} }; // stream descriptor used for volume control struct StreamDescriptor { - int mIndexMin; // min volume index - int mIndexMax; // max volume index - int mIndexCur[15]; // current volume index - - struct VolumeCurvePoint *mVolumeCurve; + int mIndexMin; // min volume index + int mIndexMax; // max volume index + int mIndexCur[15]; // current volume index + struct VolumeCurvePoint *mVolumeCurve; }; -float volIndexToAmpl(struct audio_stream_in *stream,int indexInUi) -{ - struct aml_stream_in *in = (struct aml_stream_in *)stream; - struct VolumeCurvePoint *curve=NULL; - struct StreamDescriptor *streamDesc= NULL; - - streamDesc = malloc(sizeof(struct StreamDescriptor)); - streamDesc->mVolumeCurve = sSpeakerMediaVolumeCurve; - - curve = streamDesc->mVolumeCurve; - streamDesc->mIndexMin = in->indexMIn; - streamDesc->mIndexMax = in->indexMax; - // the volume index in the UI is relative to the min and max volume indices for this stream type - int nbSteps = 1 + curve[VOLMAX].mIndex - - curve[VOLMIN].mIndex; - - ALOGD("volIndexToAmpl,nbSteps=%d",nbSteps); - int volIdx = (nbSteps * (indexInUi - streamDesc->mIndexMin)) / - (streamDesc->mIndexMax - streamDesc->mIndexMin); - - // find what part of the curve this index volume belongs to, or if it's out of bounds - int segment = 0; - if (volIdx < curve[VOLMIN].mIndex) { // out of bounds - return 0.0f; - } else if (volIdx < curve[VOLKNEE1].mIndex) { - segment = 0; - } else if (volIdx < curve[VOLKNEE2].mIndex) { - segment = 1; - } else if (volIdx <= curve[VOLMAX].mIndex) { - segment = 2; - } else { // out of bounds - return 1.0f; - } - - // linear interpolation in the attenuation table in dB - float decibels = curve[segment].mDBAttenuation + - ((float)(volIdx - curve[segment].mIndex)) * - ( (curve[segment+1].mDBAttenuation - - curve[segment].mDBAttenuation) / - ((float)(curve[segment+1].mIndex - - curve[segment].mIndex)) ); - - float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 ) - - ALOGD("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f", - curve[segment].mIndex, volIdx, - curve[segment+1].mIndex, - curve[segment].mDBAttenuation, - decibels, - curve[segment+1].mDBAttenuation, - amplification); - - return amplification; -} - -float computeVolume(struct audio_stream_in *stream) -{ - struct aml_stream_in *in = (struct aml_stream_in *)stream; - float volume = 1.0f; - char prop[PROPERTY_VALUE_MAX]; - - property_get("mbx.hdmiin.vol",prop,"15"); - - int indexUI = atoi(prop); - if(indexUI > in->indexMax) - indexUI = in->indexMax; - else if(indexUI < in->indexMIn) - indexUI = in->indexMIn; - - if(in->volume_index !=indexUI){ - in->volume_index = indexUI; - - volume = volIndexToAmpl(stream,indexUI); - in->last_volume = volume; - }else{ - volume = in->last_volume; - } - return volume; -} - -static int getprop_bool(const char * path) -{ - char buf[PROPERTY_VALUE_MAX]; - int ret = -1; - - ret = property_get(path, buf, NULL); - if (ret > 0) { - if(strcasecmp(buf,"true")==0 || strcmp(buf,"1")==0) - return 1; - } - return 0; -} -static int get_codec_type(const char * path) -{ - int val = 0; - int fd = open("/sys/class/audiodsp/digital_codec", O_RDONLY); - if (fd >= 0) { - char bcmd[16]; - read(fd, bcmd, sizeof(bcmd)); - val = strtol(bcmd, NULL, 10); - close(fd); - }else{ - LOGFUNC("[%s]open digital_codec node failed! return 0\n", __FUNCTION__); - } - return val; -} -static void select_output_device(struct aml_audio_device *adev) -{ - LOGFUNC("%s(mode=%d, out_device=%#x)", __FUNCTION__, adev->mode, adev->out_device); -} - -static void select_input_device(struct aml_audio_device *adev) -{ - int mic_in = adev->in_device & AUDIO_DEVICE_IN_BUILTIN_MIC; - int headset_mic = adev->in_device & AUDIO_DEVICE_IN_WIRED_HEADSET; - LOGFUNC("~~~~ %s : in_device(%#x), mic_in(%#x), headset_mic(%#x)", __func__, adev->in_device, mic_in, headset_mic); - return; -} +float +volIndexToAmpl (struct audio_stream_in *stream, int indexInUi) +{ + struct aml_stream_in *in = (struct aml_stream_in *) stream; + struct VolumeCurvePoint *curve = NULL; + struct StreamDescriptor *streamDesc = NULL; -static void force_all_standby(struct aml_audio_device *adev) -{ - struct aml_stream_in *in; - struct aml_stream_out *out; - - LOGFUNC("%s(%p)", __FUNCTION__, adev); - - if (adev->active_output) { - out = adev->active_output; - pthread_mutex_lock(&out->lock); - do_output_standby(out); - pthread_mutex_unlock(&out->lock); - } - - if (adev->active_input) { - in = adev->active_input; - pthread_mutex_lock(&in->lock); - do_input_standby(in); - pthread_mutex_unlock(&in->lock); - } -} -static void select_mode(struct aml_audio_device *adev) -{ - LOGFUNC("%s(out_device=%#x)", __FUNCTION__, adev->out_device); - LOGFUNC("%s(in_device=%#x)", __FUNCTION__, adev->in_device); - return; - force_all_standby(adev); - /* force earpiece route for in call state if speaker is the - only currently selected route. This prevents having to tear - down the modem PCMs to change route from speaker to earpiece - after the ringtone is played, but doesn't cause a route - change if a headset or bt device is already connected. If - speaker is not the only thing active, just remove it from - the route. We'll assume it'll never be used initally during - a call. This works because we're sure that the audio policy - manager will update the output device after the audio mode - change, even if the device selection did not change. */ - if ((adev->out_device & AUDIO_DEVICE_OUT_ALL) == AUDIO_DEVICE_OUT_SPEAKER) - adev->in_device = AUDIO_DEVICE_IN_BUILTIN_MIC & ~AUDIO_DEVICE_BIT_IN; - else - adev->out_device &= ~AUDIO_DEVICE_OUT_SPEAKER; - - select_output_device(adev); - select_input_device(adev); - return; -} + streamDesc = malloc (sizeof (struct StreamDescriptor)); + streamDesc->mVolumeCurve = sSpeakerMediaVolumeCurve; -/* - type : 0 -> playback, 1 -> capture -*/ -#define MAX_CARD_NUM 2 -int get_external_card(int type) -{ - int card_num = 1; // start num, 0 is defualt sound card. - - struct stat card_stat; - char fpath[256]; - int ret; - - - while(card_num <= MAX_CARD_NUM) - { - snprintf(fpath, sizeof(fpath), "/proc/asound/card%d", card_num); - - ret = stat(fpath, &card_stat); - if(ret < 0) - { - ret = -1; - } - else - { - snprintf(fpath, sizeof(fpath), "/dev/snd/pcmC%uD0%c", card_num, - type ? 'c' : 'p'); - ret = stat(fpath, &card_stat); - if(ret == 0) - { - return card_num; - } - } - - card_num++; - } - - return ret; -} - -static int check_output_stream(struct aml_stream_out *out) -{ - int ret = 0; - unsigned int card = CARD_AMLOGIC_DEFAULT; - unsigned int port = PORT_MM; - int ext_card; - ext_card = get_external_card(0); - if(ext_card < 0) - { - card = CARD_AMLOGIC_DEFAULT; - } - else - { - card = ext_card; - } - - out->config.start_threshold = PERIOD_SIZE * 2; - out->config.avail_min = 0;//SHORT_PERIOD_SIZE; - return 0; -} - -static int get_aml_card(){ - int card = -1, err = 0; - int fd = -1; - unsigned fileSize = 512; - char *read_buf = NULL, *pd = NULL; - static const char *const SOUND_CARDS_PATH = "/proc/asound/cards"; - fd = open(SOUND_CARDS_PATH, O_RDONLY); - if (fd < 0) { - ALOGE("ERROR: failed to open config file %s error: %d\n", SOUND_CARDS_PATH, errno); - close(fd); - return -EINVAL; - } - - read_buf = (char *)malloc(fileSize); - if (!read_buf) { - ALOGE("Failed to malloc read_buf"); - close(fd); - return -ENOMEM; - } - memset(read_buf, 0x0, fileSize); - err = read(fd, read_buf, fileSize); - if (fd < 0) { - ALOGE("ERROR: failed to read config file %s error: %d\n", SOUND_CARDS_PATH, errno); - close(fd); - return -EINVAL; - } - pd = strstr(read_buf, "AML"); - card = *(pd - 3) - '0'; + curve = streamDesc->mVolumeCurve; + streamDesc->mIndexMin = in->indexMIn; + streamDesc->mIndexMax = in->indexMax; + // the volume index in the UI is relative to the min and max volume indices for this stream type + int nbSteps = 1 + curve[VOLMAX].mIndex - curve[VOLMIN].mIndex; -OUT: - free(read_buf); - close(fd); - return card; -} -static int get_spdif_port(){ - int port = -1, err = 0; - int fd = -1; - unsigned fileSize = 512; - char *read_buf = NULL, *pd = NULL; - static const char *const SOUND_PCM_PATH = "/proc/asound/pcm"; - fd = open(SOUND_PCM_PATH, O_RDONLY); - if (fd < 0) { - ALOGE("ERROR: failed to open config file %s error: %d\n", SOUND_PCM_PATH, errno); - close(fd); - return -EINVAL; - } - - read_buf = (char *)malloc(fileSize); - if (!read_buf) { - ALOGE("Failed to malloc read_buf"); - close(fd); - return -ENOMEM; - } - memset(read_buf, 0x0, fileSize); - err = read(fd, read_buf, fileSize); - if (fd < 0) { - ALOGE("ERROR: failed to read config file %s error: %d\n", SOUND_PCM_PATH, errno); - close(fd); - return -EINVAL; - } - pd = strstr(read_buf, "SPDIF"); - port = *(pd -3) - '0'; + ALOGD ("volIndexToAmpl,nbSteps=%d", nbSteps); + int volIdx = (nbSteps * (indexInUi - streamDesc->mIndexMin)) / + (streamDesc->mIndexMax - streamDesc->mIndexMin); -OUT: - free(read_buf); - close(fd); - return port; -} -/* must be called with hw device and output stream mutexes locked */ -static int start_output_stream(struct aml_stream_out *out) -{ - struct aml_audio_device *adev = out->dev; - int card = CARD_AMLOGIC_DEFAULT; - int port = PORT_MM; - int ret=0; - - adev->active_output = out; - - if (adev->mode != AUDIO_MODE_IN_CALL) { - /* FIXME: only works if only one output can be active at a time */ - select_output_device(adev); - } - LOGFUNC("%s(adev->out_device=%#x, adev->mode=%d)", __FUNCTION__, adev->out_device, adev->mode); - - card = get_aml_card(); - if(card < 0 ){ - ALOGE("hdmi get aml card id failed \n"); - card = CARD_AMLOGIC_DEFAULT; - } - port = get_spdif_port(); - if(port < 0 ){ - ALOGE("hdmi get aml card port failed \n"); - card = PORT_MM; - } - ALOGI("hdmi sound card id %d,device id %d \n",card,port); - if(out->config.channels == 8){ - port = 0; - out->config.format = PCM_FORMAT_S32_LE; - adev->out_device=AUDIO_DEVICE_OUT_SPEAKER; - ALOGI("[%s %d]8CH format output: set port/0 adev->out_device/%d\n",__FUNCTION__,__LINE__,AUDIO_DEVICE_OUT_SPEAKER); - } - LOGFUNC("------------open on board audio-------"); - if(getprop_bool("media.libplayer.wfd")){ - out->config.period_size = PERIOD_SIZE; - } - /* default to low power: will be corrected in out_write if necessary before first write to - * tinyalsa. - */ - int codec_type=get_codec_type("/sys/class/audiodsp/digital_codec"); - if(codec_type == 4 || codec_type == 5){ - out->config.period_size=PERIOD_SIZE*2; - out->write_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE*2; - out->config.start_threshold = PLAYBACK_PERIOD_COUNT*PERIOD_SIZE*2; - }else if(codec_type == 7||codec_type == 8){ - out->config.period_size=PERIOD_SIZE*4*2; - out->write_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE*4*2; - out->config.start_threshold = PLAYBACK_PERIOD_COUNT*PERIOD_SIZE*4*2; - }else{ - out->config.period_size=PERIOD_SIZE; - out->write_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE; - out->config.start_threshold = PERIOD_SIZE * PLAYBACK_PERIOD_COUNT; - } - out->config.avail_min = 0;//SHORT_PERIOD_SIZE - - if(out->config.rate!=DEFAULT_OUT_SAMPLING_RATE){ - - ret = create_resampler(DEFAULT_OUT_SAMPLING_RATE, - out->config.rate, - 2, - RESAMPLER_QUALITY_DEFAULT, - NULL, - &out->resampler); - if (ret != 0) - { - ALOGE("cannot create resampler for output"); - return ENOMEM; - } - out->buffer = malloc(RESAMPLER_BUFFER_SIZE); /* todo: allow for reallocing */ - if (out->buffer == NULL) - return ENOMEM; - } + // find what part of the curve this index volume belongs to, or if it's out of bounds + int segment = 0; + if (volIdx < curve[VOLMIN].mIndex) + { // out of bounds + return 0.0f; + } + else if (volIdx < curve[VOLKNEE1].mIndex) + { + segment = 0; + } + else if (volIdx < curve[VOLKNEE2].mIndex) + { + segment = 1; + } + else if (volIdx <= curve[VOLMAX].mIndex) + { + segment = 2; + } + else + { // out of bounds + return 1.0f; + } + + // linear interpolation in the attenuation table in dB + float decibels = curve[segment].mDBAttenuation + + ((float) (volIdx - curve[segment].mIndex)) * + ((curve[segment + 1].mDBAttenuation - + curve[segment].mDBAttenuation) / + ((float) (curve[segment + 1].mIndex - curve[segment].mIndex))); + + float amplification = exp (decibels * 0.115129f); // exp( dB * ln(10) / 20 ) - ALOGI("channels=%d---format=%d---period_count%d---period_size%d---rate=%d---", - out->config.channels, out->config.format, out->config.period_count, - out->config.period_size, out->config.rate); - out->pcm = pcm_open(card, port, PCM_OUT /*| PCM_MMAP | PCM_NOIRQ*/, &(out->config)); - if (!pcm_is_ready(out->pcm)) { - ALOGE("cannot open pcm_out driver: %s", pcm_get_error(out->pcm)); - pcm_close(out->pcm); - adev->active_output = NULL; - return -ENOMEM; - } - if (adev->echo_reference != NULL) - out->echo_reference = adev->echo_reference; - if (out->resampler){ - out->resampler->reset(out->resampler); - } + ALOGD ("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f", + curve[segment].mIndex, volIdx,curve[segment + 1].mIndex, + curve[segment].mDBAttenuation, + decibels, curve[segment + 1].mDBAttenuation, amplification); - return 0; + return amplification; } -static int check_input_parameters(uint32_t sample_rate, int format, int channel_count) +float +computeVolume (struct audio_stream_in *stream) { - LOGFUNC("%s(sample_rate=%d, format=%d, channel_count=%d)", __FUNCTION__, sample_rate, format, channel_count); + struct aml_stream_in *in = (struct aml_stream_in *) stream; + float volume = 1.0f; + char prop[PROPERTY_VALUE_MAX]; - if (format != AUDIO_FORMAT_PCM_16_BIT) - return -EINVAL; + property_get ("mbx.hdmiin.vol", prop, "15"); - if ((channel_count < 1) || (channel_count > 2)) - return -EINVAL; + int indexUI = atoi (prop); + if (indexUI > in->indexMax) + indexUI = in->indexMax; + else if (indexUI < in->indexMIn) + indexUI = in->indexMIn; - switch(sample_rate) { - case 8000: - case 11025: - case 16000: - case 22050: - case 24000: - case 32000: - case 44100: - case 48000: - break; - default: - return -EINVAL; - } + if (in->volume_index != indexUI) + { + in->volume_index = indexUI; - return 0; + volume = volIndexToAmpl (stream, indexUI); + in->last_volume = volume; + } + else + { + volume = in->last_volume; + } + return volume; } -static size_t get_input_buffer_size(uint32_t sample_rate, int format, int channel_count) +static int +getprop_bool (const char *path) { - size_t size; - size_t device_rate; + char buf[PROPERTY_VALUE_MAX]; + int ret = -1; - LOGFUNC("%s(sample_rate=%d, format=%d, channel_count=%d)", __FUNCTION__, sample_rate, format, channel_count); - - if (check_input_parameters(sample_rate, format, channel_count) != 0) - return 0; + ret = property_get (path, buf, NULL); + if (ret > 0) + { + if (strcasecmp (buf, "true") == 0 || strcmp (buf, "1") == 0) + return 1; + } + return 0; +} - /* take resampling into account and return the closest majoring - multiple of 16 frames, as audioflinger expects audio buffers to - be a multiple of 16 frames */ - size = (pcm_config_in.period_size * sample_rate) / pcm_config_in.rate; - size = ((size + 15) / 16) * 16; +static int +get_codec_type (const char *path) +{ + int val = 0; + int fd = open ("/sys/class/audiodsp/digital_codec", O_RDONLY); + if (fd >= 0) + { + char bcmd[16]; + read (fd, bcmd, sizeof (bcmd)); + val = strtol (bcmd, NULL, 10); + close (fd); + } + else + { + LOGFUNC ("[%s]open digital_codec node failed! return 0\n", + __FUNCTION__); + } + return val; +} - return size * channel_count * sizeof(short); +static void +select_output_device (struct aml_audio_device *adev) +{ + LOGFUNC ("%s(mode=%d, out_device=%#x)", __FUNCTION__, adev->mode, + adev->out_device); } -static void add_echo_reference(struct aml_stream_out *out, - struct echo_reference_itfe *reference) +static void +select_input_device (struct aml_audio_device *adev) { - pthread_mutex_lock(&out->lock); - out->echo_reference = reference; - pthread_mutex_unlock(&out->lock); + int mic_in = adev->in_device & AUDIO_DEVICE_IN_BUILTIN_MIC; + int headset_mic = adev->in_device & AUDIO_DEVICE_IN_WIRED_HEADSET; + LOGFUNC ("~~~~ %s : in_device(%#x), mic_in(%#x), headset_mic(%#x)", + __func__, adev->in_device, mic_in, headset_mic); + return; } -static void remove_echo_reference(struct aml_stream_out *out, - struct echo_reference_itfe *reference) +static void +force_all_standby (struct aml_audio_device *adev) { - pthread_mutex_lock(&out->lock); - if (out->echo_reference == reference) { - /* stop writing to echo reference */ - reference->write(reference, NULL); - out->echo_reference = NULL; - } - pthread_mutex_unlock(&out->lock); + struct aml_stream_in *in; + struct aml_stream_out *out; + + LOGFUNC ("%s(%p)", __FUNCTION__, adev); + + if (adev->active_output) + { + out = adev->active_output; + pthread_mutex_lock (&out->lock); + do_output_standby (out); + pthread_mutex_unlock (&out->lock); + } + + if (adev->active_input) + { + in = adev->active_input; + pthread_mutex_lock (&in->lock); + do_input_standby (in); + pthread_mutex_unlock (&in->lock); + } } -static void put_echo_reference(struct aml_audio_device *adev, - struct echo_reference_itfe *reference) +static void +select_mode (struct aml_audio_device *adev) +{ + LOGFUNC ("%s(out_device=%#x)", __FUNCTION__, adev->out_device); + LOGFUNC ("%s(in_device=%#x)", __FUNCTION__, adev->in_device); + return; + force_all_standby (adev); + /* force earpiece route for in call state if speaker is the + only currently selected route. This prevents having to tear + down the modem PCMs to change route from speaker to earpiece + after the ringtone is played, but doesn't cause a route + change if a headset or bt device is already connected. If + speaker is not the only thing active, just remove it from + the route. We'll assume it'll never be used initally during + a call. This works because we're sure that the audio policy + manager will update the output device after the audio mode + change, even if the device selection did not change. */ + if ((adev->out_device & AUDIO_DEVICE_OUT_ALL) == AUDIO_DEVICE_OUT_SPEAKER) + adev->in_device = AUDIO_DEVICE_IN_BUILTIN_MIC & ~AUDIO_DEVICE_BIT_IN; + else + adev->out_device &= ~AUDIO_DEVICE_OUT_SPEAKER; + + select_output_device (adev); + select_input_device (adev); + return; +} + +/* + type : 0 -> playback, 1 -> capture +*/ +#define MAX_CARD_NUM 2 +int +get_external_card (int type) { - if (adev->echo_reference != NULL && - reference == adev->echo_reference) { - if (adev->active_output != NULL) - remove_echo_reference(adev->active_output, reference); - release_echo_reference(reference); - adev->echo_reference = NULL; - } + int card_num = 1; // start num, 0 is defualt sound card. + + struct stat card_stat; + char fpath[256]; + int ret; + + + while (card_num <= MAX_CARD_NUM) + { + snprintf (fpath, sizeof (fpath), "/proc/asound/card%d", card_num); + + ret = stat (fpath, &card_stat); + if (ret < 0) + { + ret = -1; + } + else + { + snprintf (fpath, sizeof (fpath), "/dev/snd/pcmC%uD0%c", card_num, + type ? 'c' : 'p'); + ret = stat (fpath, &card_stat); + if (ret == 0) + { + return card_num; + } + } + + card_num++; + } + + return ret; } -static struct echo_reference_itfe *get_echo_reference(struct aml_audio_device *adev, - audio_format_t format, - uint32_t channel_count, - uint32_t sampling_rate) +static int +check_output_stream (struct aml_stream_out *out) { - put_echo_reference(adev, adev->echo_reference); - if (adev->active_output != NULL) { - struct audio_stream *stream = &adev->active_output->stream.common; - uint32_t wr_channel_count = popcount(stream->get_channels(stream)); - uint32_t wr_sampling_rate = stream->get_sample_rate(stream); + int ret = 0; + unsigned int card = CARD_AMLOGIC_DEFAULT; + unsigned int port = PORT_MM; + int ext_card; + ext_card = get_external_card (0); + if (ext_card < 0) + { + card = CARD_AMLOGIC_DEFAULT; + } + else + { + card = ext_card; + } - int status = create_echo_reference(AUDIO_FORMAT_PCM_16_BIT, - channel_count, - sampling_rate, - AUDIO_FORMAT_PCM_16_BIT, - wr_channel_count, - wr_sampling_rate, - &adev->echo_reference); - if (status == 0) - add_echo_reference(adev->active_output, adev->echo_reference); - } - return adev->echo_reference; + out->config.start_threshold = PERIOD_SIZE * 2; + out->config.avail_min = 0; //SHORT_PERIOD_SIZE; + return 0; +} + +static int +get_aml_card () +{ + int card = -1, err = 0; + int fd = -1; + unsigned fileSize = 512; + char *read_buf = NULL, *pd = NULL; + static const char *const SOUND_CARDS_PATH = "/proc/asound/cards"; + fd = open (SOUND_CARDS_PATH, O_RDONLY); + if (fd < 0) + { + ALOGE ("ERROR: failed to open config file %s error: %d\n", + SOUND_CARDS_PATH, errno); + close (fd); + return -EINVAL; + } + + read_buf = (char *) malloc (fileSize); + if (!read_buf) + { + ALOGE ("Failed to malloc read_buf"); + close (fd); + return -ENOMEM; + } + memset (read_buf, 0x0, fileSize); + err = read (fd, read_buf, fileSize); + if (fd < 0) + { + ALOGE ("ERROR: failed to read config file %s error: %d\n", + SOUND_CARDS_PATH, errno); + close (fd); + return -EINVAL; + } + pd = strstr (read_buf, "AML"); + card = *(pd - 3) - '0'; + +OUT: + free (read_buf); + close (fd); + return card; +} + +static int +get_spdif_port () +{ + int port = -1, err = 0; + int fd = -1; + unsigned fileSize = 512; + char *read_buf = NULL, *pd = NULL; + static const char *const SOUND_PCM_PATH = "/proc/asound/pcm"; + fd = open (SOUND_PCM_PATH, O_RDONLY); + if (fd < 0) + { + ALOGE ("ERROR: failed to open config file %s error: %d\n", + SOUND_PCM_PATH, errno); + close (fd); + return -EINVAL; + } + + read_buf = (char *) malloc (fileSize); + if (!read_buf) + { + ALOGE ("Failed to malloc read_buf"); + close (fd); + return -ENOMEM; + } + memset (read_buf, 0x0, fileSize); + err = read (fd, read_buf, fileSize); + if (fd < 0) + { + ALOGE ("ERROR: failed to read config file %s error: %d\n", + SOUND_PCM_PATH, errno); + close (fd); + return -EINVAL; + } + pd = strstr (read_buf, "SPDIF"); + port = *(pd - 3) - '0'; + +OUT: + free (read_buf); + close (fd); + return port; } -static int get_playback_delay(struct aml_stream_out *out, - size_t frames, - struct echo_reference_buffer *buffer) +/* must be called with hw device and output stream mutexes locked */ +static int +start_output_stream (struct aml_stream_out *out) { + struct aml_audio_device *adev = out->dev; + int card = CARD_AMLOGIC_DEFAULT; + int port = PORT_MM; + int ret = 0; + + adev->active_output = out; + + if (adev->mode != AUDIO_MODE_IN_CALL) + { + /* FIXME: only works if only one output can be active at a time */ + select_output_device (adev); + } + LOGFUNC ("%s(adev->out_device=%#x, adev->mode=%d)", __FUNCTION__, + adev->out_device, adev->mode); + + card = get_aml_card (); + if (card < 0) + { + ALOGE ("hdmi get aml card id failed \n"); + card = CARD_AMLOGIC_DEFAULT; + } + port = get_spdif_port (); + if (port < 0) + { + ALOGE ("hdmi get aml card port failed \n"); + card = PORT_MM; + } + ALOGI ("hdmi sound card id %d,device id %d \n", card, port); + if (out->config.channels == 8) + { + port = 0; + out->config.format = PCM_FORMAT_S32_LE; + adev->out_device = AUDIO_DEVICE_OUT_SPEAKER; + ALOGI ("[%s %d]8CH format output: set port/0 adev->out_device/%d\n", + __FUNCTION__, __LINE__, AUDIO_DEVICE_OUT_SPEAKER); + } + LOGFUNC ("------------open on board audio-------"); + if (getprop_bool ("media.libplayer.wfd")) + { + out->config.period_size = PERIOD_SIZE; + } + /* default to low power: will be corrected in out_write if necessary before first write to + * tinyalsa. + */ + int codec_type = get_codec_type ("/sys/class/audiodsp/digital_codec"); + if (codec_type == 4 || codec_type == 5) + { + out->config.period_size = PERIOD_SIZE * 2; + out->write_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE * 2; + out->config.start_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE * 2; + } + else if (codec_type == 7 || codec_type == 8) + { + out->config.period_size = PERIOD_SIZE * 4 * 2; + out->write_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE * 4 * 2; + out->config.start_threshold = + PLAYBACK_PERIOD_COUNT * PERIOD_SIZE * 4 * 2; + } + else + { + out->config.period_size = PERIOD_SIZE; + out->write_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE; + out->config.start_threshold = PERIOD_SIZE * PLAYBACK_PERIOD_COUNT; + } + out->config.avail_min = 0; //SHORT_PERIOD_SIZE + + if (out->config.rate != DEFAULT_OUT_SAMPLING_RATE) + { + + ret = create_resampler (DEFAULT_OUT_SAMPLING_RATE, + out->config.rate, + 2, + RESAMPLER_QUALITY_DEFAULT, + NULL, &out->resampler); + if (ret != 0) + { + ALOGE ("cannot create resampler for output"); + return ENOMEM; + } + out->buffer = malloc (RESAMPLER_BUFFER_SIZE); /* todo: allow for reallocing */ + if (out->buffer == NULL) + return ENOMEM; + } - size_t kernel_frames; - int status; - status = pcm_get_htimestamp(out->pcm, &kernel_frames, &buffer->time_stamp); - if (status < 0) { - buffer->time_stamp.tv_sec = 0; - buffer->time_stamp.tv_nsec = 0; - buffer->delay_ns = 0; - ALOGV("get_playback_delay(): pcm_get_htimestamp error," - "setting playbackTimestamp to 0"); - return status; - } - kernel_frames = pcm_get_buffer_size(out->pcm) - kernel_frames; - ALOGV("~~pcm_get_buffer_size(out->pcm)=%d",pcm_get_buffer_size(out->pcm)); - /* adjust render time stamp with delay added by current driver buffer. - * Add the duration of current frame as we want the render time of the last - * sample being written. */ - buffer->delay_ns = (long)(((int64_t)(kernel_frames + frames)* 1000000000)/ - DEFAULT_OUT_SAMPLING_RATE); + ALOGI + ("channels=%d---format=%d---period_count%d---period_size%d---rate=%d---", + out->config.channels, out->config.format, out->config.period_count, + out->config.period_size, out->config.rate); + out->pcm = + pcm_open (card, port, PCM_OUT /*| PCM_MMAP | PCM_NOIRQ */ , + &(out->config)); + if (!pcm_is_ready (out->pcm)) + { + ALOGE ("cannot open pcm_out driver: %s", pcm_get_error (out->pcm)); + pcm_close (out->pcm); + adev->active_output = NULL; + return -ENOMEM; + } + if (adev->echo_reference != NULL) + out->echo_reference = adev->echo_reference; + if (out->resampler) + { + out->resampler->reset (out->resampler); + } - ALOGV("get_playback_delay time_stamp = [%ld].[%ld], delay_ns: [%d]," - "kernel_frames:[%d]", - buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, buffer->delay_ns, - kernel_frames); - return 0; + return 0; } -static uint32_t out_get_sample_rate(const struct audio_stream *stream) +static int +check_input_parameters (uint32_t sample_rate, int format, int channel_count) { - return DEFAULT_OUT_SAMPLING_RATE; + LOGFUNC ("%s(sample_rate=%d, format=%d, channel_count=%d)", __FUNCTION__, + sample_rate, format, channel_count); + + if (format != AUDIO_FORMAT_PCM_16_BIT) + return -EINVAL; + + if ((channel_count < 1) || (channel_count > 2)) + return -EINVAL; + + switch (sample_rate) + { + case 8000: + case 11025: + case 16000: + case 22050: + case 24000: + case 32000: + case 44100: + case 48000: + break; + default: + return -EINVAL; + } + + return 0; } -static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate) +static size_t +get_input_buffer_size (uint32_t sample_rate, int format, int channel_count) { - LOGFUNC("%s(%p, %d)", __FUNCTION__, stream, rate); + size_t size; + size_t device_rate; + + LOGFUNC ("%s(sample_rate=%d, format=%d, channel_count=%d)", __FUNCTION__, + sample_rate, format, channel_count); + + if (check_input_parameters (sample_rate, format, channel_count) != 0) + return 0; + + /* take resampling into account and return the closest majoring + multiple of 16 frames, as audioflinger expects audio buffers to + be a multiple of 16 frames */ + size = (pcm_config_in.period_size * sample_rate) / pcm_config_in.rate; + size = ((size + 15) / 16) * 16; + + return size * channel_count * sizeof (short); +} - return 0; +static void +add_echo_reference (struct aml_stream_out *out, + struct echo_reference_itfe *reference) +{ + pthread_mutex_lock (&out->lock); + out->echo_reference = reference; + pthread_mutex_unlock (&out->lock); } -static size_t out_get_buffer_size(const struct audio_stream *stream) +static void +remove_echo_reference (struct aml_stream_out *out, + struct echo_reference_itfe *reference) { - struct aml_stream_out *out = (struct aml_stream_out *)stream; + pthread_mutex_lock (&out->lock); + if (out->echo_reference == reference) + { + /* stop writing to echo reference */ + reference->write (reference, NULL); + out->echo_reference = NULL; + } + pthread_mutex_unlock (&out->lock); +} - LOGFUNC("%s(out->config.rate=%d)", __FUNCTION__, out->config.rate); +static void +put_echo_reference (struct aml_audio_device *adev, + struct echo_reference_itfe *reference) +{ + if (adev->echo_reference != NULL && reference == adev->echo_reference) + { + if (adev->active_output != NULL) + remove_echo_reference (adev->active_output, reference); + release_echo_reference (reference); + adev->echo_reference = NULL; + } +} - /* take resampling into account and return the closest majoring - * multiple of 16 frames, as audioflinger expects audio buffers to - * be a multiple of 16 frames - */ - size_t size; - int codec_type=get_codec_type("/sys/class/audiodsp/digital_codec"); - if(codec_type == 4 || codec_type == 5)//dd+ - size = (PERIOD_SIZE*2* PLAYBACK_PERIOD_COUNT * (int64_t)DEFAULT_OUT_SAMPLING_RATE) / out->config.rate; - else if(codec_type == 7) - size = (PERIOD_SIZE*2 * 4* PLAYBACK_PERIOD_COUNT * (int64_t)DEFAULT_OUT_SAMPLING_RATE) / out->config.rate; - else if(codec_type>0 && codec_type<4 ) //dd/dts - size = (PERIOD_SIZE*4*(int64_t)DEFAULT_OUT_SAMPLING_RATE) / out->config.rate; - else//pcm - size = (PERIOD_SIZE * (int64_t)DEFAULT_OUT_SAMPLING_RATE) / out->config.rate; - - size = ((size + 15) / 16) * 16; - return size * audio_stream_out_frame_size(&out->stream); +static struct echo_reference_itfe * +get_echo_reference (struct aml_audio_device *adev, + audio_format_t format, + uint32_t channel_count, uint32_t sampling_rate) +{ + put_echo_reference (adev, adev->echo_reference); + if (adev->active_output != NULL) + { + struct audio_stream *stream = &adev->active_output->stream.common; + uint32_t wr_channel_count = popcount (stream->get_channels (stream)); + uint32_t wr_sampling_rate = stream->get_sample_rate (stream); + + int status = create_echo_reference (AUDIO_FORMAT_PCM_16_BIT, + channel_count, + sampling_rate, + AUDIO_FORMAT_PCM_16_BIT, + wr_channel_count, + wr_sampling_rate, + &adev->echo_reference); + if (status == 0) + add_echo_reference (adev->active_output, adev->echo_reference); + } + return adev->echo_reference; } -static audio_channel_mask_t out_get_channels(const struct audio_stream *stream) +static int +get_playback_delay (struct aml_stream_out *out, + size_t frames, struct echo_reference_buffer *buffer) { - struct aml_stream_out *out = (struct aml_stream_out *)stream; - if(out->multich > 2){ - if(out->multich == 6) - return AUDIO_CHANNEL_OUT_5POINT1; - else if(out->multich == 8) - return AUDIO_CHANNEL_OUT_7POINT1; - } - if (out->config.channels == 1) { - return AUDIO_CHANNEL_OUT_MONO; - } else { - return AUDIO_CHANNEL_OUT_STEREO; - } + + size_t kernel_frames; + int status; + status = pcm_get_htimestamp (out->pcm, &kernel_frames, &buffer->time_stamp); + if (status < 0) + { + buffer->time_stamp.tv_sec = 0; + buffer->time_stamp.tv_nsec = 0; + buffer->delay_ns = 0; + ALOGV ("get_playback_delay(): pcm_get_htimestamp error," + "setting playbackTimestamp to 0"); + return status; + } + kernel_frames = pcm_get_buffer_size (out->pcm) - kernel_frames; + ALOGV ("~~pcm_get_buffer_size(out->pcm)=%d", + pcm_get_buffer_size (out->pcm)); + /* adjust render time stamp with delay added by current driver buffer. + * Add the duration of current frame as we want the render time of the last + * sample being written. */ + buffer->delay_ns = + (long) (((int64_t) (kernel_frames + frames) * 1000000000) / + DEFAULT_OUT_SAMPLING_RATE); + + ALOGV ("get_playback_delay time_stamp = [%ld].[%ld], delay_ns: [%d]," + "kernel_frames:[%d]", + buffer->time_stamp.tv_sec, buffer->time_stamp.tv_nsec, + buffer->delay_ns, kernel_frames); + return 0; +} + +static uint32_t +out_get_sample_rate (const struct audio_stream *stream) +{ + return DEFAULT_OUT_SAMPLING_RATE; +} + +static int +out_set_sample_rate (struct audio_stream *stream, uint32_t rate) +{ + LOGFUNC ("%s(%p, %d)", __FUNCTION__, stream, rate); + + return 0; +} + +static size_t +out_get_buffer_size (const struct audio_stream *stream) +{ + struct aml_stream_out *out = (struct aml_stream_out *) stream; + + LOGFUNC ("%s(out->config.rate=%d)", __FUNCTION__, out->config.rate); + + /* take resampling into account and return the closest majoring + * multiple of 16 frames, as audioflinger expects audio buffers to + * be a multiple of 16 frames + */ + size_t size; + int codec_type = get_codec_type ("/sys/class/audiodsp/digital_codec"); + if (codec_type == 4 || codec_type == 5) //dd+ + size = + (PERIOD_SIZE * 2 * PLAYBACK_PERIOD_COUNT * + (int64_t) DEFAULT_OUT_SAMPLING_RATE) / out->config.rate; + else if (codec_type == 7) + size = + (PERIOD_SIZE * 4 * 4 * PLAYBACK_PERIOD_COUNT * + (int64_t) DEFAULT_OUT_SAMPLING_RATE) / out->config.rate; + else if (codec_type > 0 && codec_type < 4) //dd/dts + size = + (PERIOD_SIZE * 4 * (int64_t) DEFAULT_OUT_SAMPLING_RATE) / + out->config.rate; + else //pcm + size = + (PERIOD_SIZE * (int64_t) DEFAULT_OUT_SAMPLING_RATE) / out->config.rate; + + size = ((size + 15) / 16) * 16; + return size * audio_stream_out_frame_size (&out->stream); +} + +static audio_channel_mask_t +out_get_channels (const struct audio_stream *stream) +{ + struct aml_stream_out *out = (struct aml_stream_out *) stream; + if (out->multich > 2) + { + if (out->multich == 6) + return AUDIO_CHANNEL_OUT_5POINT1; + else if (out->multich == 8) + return AUDIO_CHANNEL_OUT_7POINT1; + } + if (out->config.channels == 1) + { + return AUDIO_CHANNEL_OUT_MONO; + } + else + { + return AUDIO_CHANNEL_OUT_STEREO; + } } -static audio_format_t out_get_format(const struct audio_stream *stream) +static audio_format_t +out_get_format (const struct audio_stream *stream) { - return AUDIO_FORMAT_PCM_16_BIT; + return AUDIO_FORMAT_PCM_16_BIT; } -static int out_set_format(struct audio_stream *stream, int format) +static int +out_set_format (struct audio_stream *stream, int format) { - LOGFUNC("%s(%p)", __FUNCTION__, stream); + LOGFUNC ("%s(%p)", __FUNCTION__, stream); - return 0; + return 0; } /* must be called with hw device and output stream mutexes locked */ -static int do_output_standby(struct aml_stream_out *out) -{ - struct aml_audio_device *adev = out->dev; - if (!out->standby) { - pcm_close(out->pcm); - out->pcm = NULL; - - adev->active_output = 0; - - /* if in call, don't turn off the output stage. This will - be done when the call is ended */ - if (adev->mode != AUDIO_MODE_IN_CALL) { - /* FIXME: only works if only one output can be active at a time */ - - //reset_mixer_state(adev->ar); - } - - /* stop writing to echo reference */ - if (out->echo_reference != NULL) { - out->echo_reference->write(out->echo_reference, NULL); - out->echo_reference = NULL; - } - - out->standby = 1; - first_write_status = 0; - } - - return 0; -} - -static int out_standby(struct audio_stream *stream) -{ - struct aml_stream_out *out = (struct aml_stream_out *)stream; - int status; - - LOGFUNC("%s(%p)", __FUNCTION__, stream); - - pthread_mutex_lock(&out->dev->lock); - pthread_mutex_lock(&out->lock); - status = do_output_standby(out); - pthread_mutex_unlock(&out->lock); - pthread_mutex_unlock(&out->dev->lock); - return status; -} - -static int out_dump(const struct audio_stream *stream, int fd) -{ - LOGFUNC("%s(%p, %d)", __FUNCTION__, stream, fd); - return 0; -} - -static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) -{ - struct aml_stream_out *out = (struct aml_stream_out *)stream; - struct aml_audio_device *adev = out->dev; - struct aml_stream_in *in; - struct str_parms *parms; - char *str; - char value[32]; - int ret, val = 0; - bool force_input_standby = false; - - LOGFUNC("%s(kvpairs(%s), out_device=%#x)", __FUNCTION__, kvpairs, adev->out_device); - parms = str_parms_create_str(kvpairs); - - ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value)); - if (ret >= 0) { - val = atoi(value); - pthread_mutex_lock(&adev->lock); - pthread_mutex_lock(&out->lock); - if (((adev->out_device & AUDIO_DEVICE_OUT_ALL) != val) && (val != 0)) { - if (out == adev->active_output) { - do_output_standby(out); - /* a change in output device may change the microphone selection */ - if (adev->active_input && - adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) { - force_input_standby = true; - } - /* force standby if moving to/from HDMI */ - if (((val & AUDIO_DEVICE_OUT_AUX_DIGITAL) ^ - (adev->out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) || - ((val & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) ^ - (adev->out_device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET))) - do_output_standby(out); - } - adev->out_device &= ~AUDIO_DEVICE_OUT_ALL; - adev->out_device |= val; - select_output_device(adev); - } - pthread_mutex_unlock(&out->lock); - if (force_input_standby) { - in = adev->active_input; - pthread_mutex_lock(&in->lock); - do_input_standby(in); - pthread_mutex_unlock(&in->lock); - } - pthread_mutex_unlock(&adev->lock); - goto exit; - } - int sr = 0; - ret = str_parms_get_int(parms, AUDIO_PARAMETER_STREAM_SAMPLING_RATE, &sr); - if (ret >= 0) { - if(sr > 0){ - ALOGI("audio hw sampling_rate change from %d to %d \n",DEFAULT_OUT_SAMPLING_RATE,sr); - DEFAULT_OUT_SAMPLING_RATE = sr; - pcm_config_out.rate = DEFAULT_OUT_SAMPLING_RATE; - out->config.rate = DEFAULT_OUT_SAMPLING_RATE; - pthread_mutex_lock(&adev->lock); - pthread_mutex_lock(&out->lock); - if(!out->standby && (out == adev->active_output)){ - do_output_standby(out); - start_output_stream(out); - out->standby = 0; - } - pthread_mutex_unlock(&adev->lock); - pthread_mutex_unlock(&out->lock); - - } - goto exit; - } - int frame_size = 0; - ret = str_parms_get_int(parms, AUDIO_PARAMETER_STREAM_FRAME_COUNT, &frame_size); - if (ret >= 0) { - if(frame_size > 0){ - ALOGI("audio hw frame size change from %d to %d \n",PERIOD_SIZE,frame_size); - PERIOD_SIZE = frame_size; - pcm_config_out.period_size = PERIOD_SIZE; - out->config.period_size = PERIOD_SIZE; - pthread_mutex_lock(&adev->lock); - pthread_mutex_lock(&out->lock); - if(!out->standby && (out == adev->active_output)){ - do_output_standby(out); - start_output_stream(out); - out->standby = 0; - } - pthread_mutex_unlock(&adev->lock); - pthread_mutex_unlock(&out->lock); - +static int +do_output_standby (struct aml_stream_out *out) +{ + struct aml_audio_device *adev = out->dev; + if (!out->standby) + { + pcm_close (out->pcm); + out->pcm = NULL; + + adev->active_output = 0; + + /* if in call, don't turn off the output stage. This will + be done when the call is ended */ + if (adev->mode != AUDIO_MODE_IN_CALL) + { + /* FIXME: only works if only one output can be active at a time */ + + //reset_mixer_state(adev->ar); + } + + /* stop writing to echo reference */ + if (out->echo_reference != NULL) + { + out->echo_reference->write (out->echo_reference, NULL); + out->echo_reference = NULL; + } + + out->standby = 1; + first_write_status = 0; + } + + return 0; +} + +static int +out_standby (struct audio_stream *stream) +{ + struct aml_stream_out *out = (struct aml_stream_out *) stream; + int status; + + LOGFUNC ("%s(%p)", __FUNCTION__, stream); + + pthread_mutex_lock (&out->dev->lock); + pthread_mutex_lock (&out->lock); + status = do_output_standby (out); + pthread_mutex_unlock (&out->lock); + pthread_mutex_unlock (&out->dev->lock); + return status; +} + +static int +out_dump (const struct audio_stream *stream, int fd) +{ + LOGFUNC ("%s(%p, %d)", __FUNCTION__, stream, fd); + return 0; +} + +static int +out_set_parameters (struct audio_stream *stream, const char *kvpairs) +{ + struct aml_stream_out *out = (struct aml_stream_out *) stream; + struct aml_audio_device *adev = out->dev; + struct aml_stream_in *in; + struct str_parms *parms; + char *str; + char value[32]; + int ret, val = 0; + bool force_input_standby = false; + + LOGFUNC ("%s(kvpairs(%s), out_device=%#x)", __FUNCTION__, kvpairs, + adev->out_device); + parms = str_parms_create_str (kvpairs); + + ret = + str_parms_get_str (parms, AUDIO_PARAMETER_STREAM_ROUTING, value, + sizeof (value)); + if (ret >= 0) + { + val = atoi (value); + pthread_mutex_lock (&adev->lock); + pthread_mutex_lock (&out->lock); + if (((adev->out_device & AUDIO_DEVICE_OUT_ALL) != val) && (val != 0)) + { + if (out == adev->active_output) + { + do_output_standby (out); + /* a change in output device may change the microphone selection */ + if (adev->active_input && + adev->active_input->source == + AUDIO_SOURCE_VOICE_COMMUNICATION) + { + force_input_standby = true; } - } -exit: - str_parms_destroy(parms); - return ret; + /* force standby if moving to/from HDMI */ + if (((val & AUDIO_DEVICE_OUT_AUX_DIGITAL) ^ + (adev->out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) || + ((val & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) ^ + (adev->out_device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET))) + do_output_standby (out); + } + adev->out_device &= ~AUDIO_DEVICE_OUT_ALL; + adev->out_device |= val; + select_output_device (adev); + } + pthread_mutex_unlock (&out->lock); + if (force_input_standby) + { + in = adev->active_input; + pthread_mutex_lock (&in->lock); + do_input_standby (in); + pthread_mutex_unlock (&in->lock); + } + pthread_mutex_unlock (&adev->lock); + goto exit; + } + int sr = 0; + ret = str_parms_get_int (parms, AUDIO_PARAMETER_STREAM_SAMPLING_RATE, &sr); + if (ret >= 0) + { + if (sr > 0) + { + ALOGI ("audio hw sampling_rate change from %d to %d \n", + DEFAULT_OUT_SAMPLING_RATE, sr); + DEFAULT_OUT_SAMPLING_RATE = sr; + pcm_config_out.rate = DEFAULT_OUT_SAMPLING_RATE; + out->config.rate = DEFAULT_OUT_SAMPLING_RATE; + pthread_mutex_lock (&adev->lock); + pthread_mutex_lock (&out->lock); + if (!out->standby && (out == adev->active_output)) + { + do_output_standby (out); + start_output_stream (out); + out->standby = 0; + } + pthread_mutex_unlock (&adev->lock); + pthread_mutex_unlock (&out->lock); + + } + goto exit; + } + int frame_size = 0; + ret = + str_parms_get_int (parms, AUDIO_PARAMETER_STREAM_FRAME_COUNT, + &frame_size); + if (ret >= 0) + { + if (frame_size > 0) + { + ALOGI ("audio hw frame size change from %d to %d \n", PERIOD_SIZE, + frame_size); + PERIOD_SIZE = frame_size; + pcm_config_out.period_size = PERIOD_SIZE; + out->config.period_size = PERIOD_SIZE; + pthread_mutex_lock (&adev->lock); + pthread_mutex_lock (&out->lock); + if (!out->standby && (out == adev->active_output)) + { + do_output_standby (out); + start_output_stream (out); + out->standby = 0; + } + pthread_mutex_unlock (&adev->lock); + pthread_mutex_unlock (&out->lock); + + } + } +exit: + str_parms_destroy (parms); + return ret; } -static char * out_get_parameters(const struct audio_stream *stream, const char *keys) +static char * +out_get_parameters (const struct audio_stream *stream, const char *keys) { - return strdup(""); + return strdup (""); } + #if 0 -static uint32_t out_get_latency(const struct audio_stream_out *stream) -{ - struct aml_stream_out *out = (struct aml_stream_out *)stream; - uint32_t whole_latency; - uint32_t ret; - whole_latency = (out->config.period_size * out->config.period_count * 1000) / out->config.rate; - if (!out->pcm || !pcm_is_ready(out->pcm)) - return whole_latency; - ret = pcm_get_latency(out->pcm); - if(ret == -1){ - return whole_latency; - } - return ret; +static uint32_t +out_get_latency (const struct audio_stream_out *stream) +{ + struct aml_stream_out *out = (struct aml_stream_out *) stream; + uint32_t whole_latency; + uint32_t ret; + whole_latency = + (out->config.period_size * out->config.period_count * 1000) / + out->config.rate; + if (!out->pcm || !pcm_is_ready (out->pcm)) + return whole_latency; + ret = pcm_get_latency (out->pcm); + if (ret == -1) + { + return whole_latency; + } + return ret; } #else -static uint32_t out_get_latency(const struct audio_stream_out *stream) +static uint32_t +out_get_latency (const struct audio_stream_out *stream) { - struct aml_stream_out *out = (struct aml_stream_out *)stream; - return (out->config.period_size * out->config.period_count * 1000) / out->config.rate; + struct aml_stream_out *out = (struct aml_stream_out *) stream; + return (out->config.period_size * out->config.period_count * 1000) / + out->config.rate; } #endif -static int out_set_volume(struct audio_stream_out *stream, float left, - float right) -{ - return -ENOSYS; -} - -static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, - size_t bytes) -{ - - int ret=0; - struct aml_stream_out *out = (struct aml_stream_out *)stream; - struct aml_audio_device *adev = out->dev; - size_t frame_size = audio_stream_out_frame_size(stream); - size_t in_frames = bytes / frame_size; - size_t out_frames = RESAMPLER_BUFFER_SIZE / frame_size; - bool force_input_standby = false; - struct aml_stream_in *in; - bool low_power; - int kernel_frames; - void *buf; - char output_buffer_bytes[RESAMPLER_BUFFER_SIZE+128]; - uint ouput_len; - char *data, *data_dst; - volatile char *data_src; - short *dataprint; - uint i, total_len; - char prop[PROPERTY_VALUE_MAX]; - - /* acquiring hw device mutex systematically is useful if a low priority thread is waiting - * on the output stream mutex - e.g. executing select_mode() while holding the hw device - * mutex - */ - - - pthread_mutex_lock(&adev->lock); - pthread_mutex_lock(&out->lock); - - if (out->standby) { - ret = start_output_stream(out); - if (ret != 0) { - pthread_mutex_unlock(&adev->lock); - goto exit; - } - out->standby = 0; - first_write_status = 0; - /* a change in output device may change the microphone selection */ - if (adev->active_input && - adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) - force_input_standby = true; - } - pthread_mutex_unlock(&adev->lock); - - /* only use resampler if required */ - if (out->config.rate != DEFAULT_OUT_SAMPLING_RATE) { - if (!out->resampler) { - - ret = create_resampler(DEFAULT_OUT_SAMPLING_RATE, - out->config.rate, - 2, - RESAMPLER_QUALITY_DEFAULT, - NULL, - &out->resampler); - if (ret != 0) - goto exit; - out->buffer = malloc(RESAMPLER_BUFFER_SIZE); /* todo: allow for reallocing */ - if (!out->buffer) { - ret = -ENOMEM; - goto exit; - } - } - out->resampler->resample_from_input(out->resampler, - (int16_t *)buffer, - &in_frames, - (int16_t *)out->buffer, - &out_frames); - buf = out->buffer; - } else { - out_frames = in_frames; - buf = (void *)buffer; - } - if (out->echo_reference != NULL) { - struct echo_reference_buffer b; - b.raw = (void *)buffer; - b.frame_count = in_frames; - get_playback_delay(out, out_frames, &b); - out->echo_reference->write(out->echo_reference, &b); - } - -#if 0 - FILE *fp=fopen("/data/audio_out.pcm","a+"); - if(fp){ - int flen=fwrite((char *)buffer,1,out_frames * frame_size,fp); - LOGFUNC("flen = %d---outlen=%d ", flen, out_frames * frame_size); - fclose(fp); - }else{ - LOGFUNC("could not open file:audio_out"); - } +static int +out_set_volume (struct audio_stream_out *stream, float left, float right) +{ + return -ENOSYS; +} + +static int +get_sysfs_int (const char *path) +{ + int val = 0; + int fd = open (path, O_RDONLY); + if (fd >= 0) + { + char bcmd[16]; + read (fd, bcmd, sizeof (bcmd)); + val = strtol (bcmd, NULL, 10); + close (fd); + } + else + { + LOGFUNC ("[%s]open %s node failed! return 0\n", path, __FUNCTION__); + } + return val; +} + +static int last_codec_type = -1; +static ssize_t +out_write (struct audio_stream_out *stream, const void *buffer, size_t bytes) +{ + + int ret = 0; + struct aml_stream_out *out = (struct aml_stream_out *) stream; + struct aml_audio_device *adev = out->dev; + size_t frame_size = audio_stream_out_frame_size (stream); + size_t in_frames = bytes / frame_size; + size_t out_frames = RESAMPLER_BUFFER_SIZE / frame_size; + bool force_input_standby = false; + struct aml_stream_in *in; + bool low_power; + int kernel_frames; + void *buf; + char output_buffer_bytes[RESAMPLER_BUFFER_SIZE + 128]; + uint ouput_len; + char *data, *data_dst; + volatile char *data_src; + short *dataprint; + uint i, total_len; + char prop[PROPERTY_VALUE_MAX]; + int codec_type = 0; + int samesource_flag = 0; + /* acquiring hw device mutex systematically is useful if a low priority thread is waiting + * on the output stream mutex - e.g. executing select_mode() while holding the hw device + * mutex + */ + + + pthread_mutex_lock (&adev->lock); + pthread_mutex_lock (&out->lock); + if (out->standby) + { + ret = start_output_stream (out); + if (ret != 0) + { + pthread_mutex_unlock (&adev->lock); + goto exit; + } + out->standby = 0; + first_write_status = 0; + /* a change in output device may change the microphone selection */ + if (adev->active_input && + adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) + force_input_standby = true; + } + pthread_mutex_unlock (&adev->lock); + + /* only use resampler if required */ + if (out->config.rate != DEFAULT_OUT_SAMPLING_RATE) + { + if (!out->resampler) + { + + ret = create_resampler (DEFAULT_OUT_SAMPLING_RATE, + out->config.rate, + 2, + RESAMPLER_QUALITY_DEFAULT, + NULL, &out->resampler); + if (ret != 0) + goto exit; + out->buffer = malloc (RESAMPLER_BUFFER_SIZE); /* todo: allow for reallocing */ + if (!out->buffer) + { + ret = -ENOMEM; + goto exit; + } + } + out->resampler->resample_from_input (out->resampler, + (int16_t *) buffer, + &in_frames, + (int16_t *) out->buffer, + &out_frames); + buf = out->buffer; + } + else + { + out_frames = in_frames; + buf = (void *) buffer; + } + if (out->echo_reference != NULL) + { + struct echo_reference_buffer b; + b.raw = (void *) buffer; + b.frame_count = in_frames; + get_playback_delay (out, out_frames, &b); + out->echo_reference->write (out->echo_reference, &b); + } + +#if 0 + FILE *fp = fopen ("/data/audio_out.pcm", "a+"); + if (fp) + { + int flen = fwrite ((char *) buffer, 1, out_frames * frame_size, fp); + LOGFUNC ("flen = %d---outlen=%d ", flen, out_frames * frame_size); + fclose (fp); + } + else + { + LOGFUNC ("could not open file:audio_out"); + } #endif - if(out->config.rate != DEFAULT_OUT_SAMPLING_RATE) { - total_len = out_frames*frame_size + cached_len; + if (out->config.rate != DEFAULT_OUT_SAMPLING_RATE) + { + total_len = out_frames * frame_size + cached_len; - LOGFUNC("total_len(%d) = resampler_out_len(%d) + cached_len111(%d)", total_len, out_frames*frame_size, cached_len); + LOGFUNC ("total_len(%d) = resampler_out_len(%d) + cached_len111(%d)", + total_len, out_frames * frame_size, cached_len); - data_src = (char *)cache_buffer_bytes; - data_dst = (char *)output_buffer_bytes; + data_src = (char *) cache_buffer_bytes; + data_dst = (char *) output_buffer_bytes; - - /*write_back data from cached_buffer*/ - if(cached_len){ - memcpy((void *)data_dst, (void *)data_src, cached_len); - data_dst += cached_len; + + /*write_back data from cached_buffer */ + if (cached_len) + { + memcpy ((void *) data_dst, (void *) data_src, cached_len); + data_dst += cached_len; + } + + ouput_len = total_len & (~0x3f); + data = (char *) buf; + + memcpy ((void *) data_dst, (void *) data, ouput_len - cached_len); + data += (ouput_len - cached_len); + cached_len = total_len & 0x3f; + data_src = (char *) cache_buffer_bytes; + + /*save data to cached_buffer */ + if (cached_len) + { + memcpy ((void *) data_src, (void *) data, cached_len); + } + if (!out->standby) + ret = pcm_write (out->pcm, (void *) output_buffer_bytes, ouput_len); + } + else + { + if (!out->standby) + { + property_get ("sys.hdmiIn.Capture", prop, "false"); + // ALOGD("****first_write_status=%d***",first_write_status); + if (!strcmp (prop, "true")) + { + if (first_write_status < 20) + { + first_write_status = first_write_status + 1; + memset ((char *) buf, 0, bytes); } - - ouput_len = total_len &(~0x3f); - data = (char*)buf; - - memcpy((void *)data_dst, (void *)data, ouput_len-cached_len); - data += (ouput_len-cached_len); - cached_len = total_len & 0x3f; - data_src = (char *)cache_buffer_bytes; - - /*save data to cached_buffer*/ - if(cached_len){ - memcpy((void *)data_src, (void *)data, cached_len); + } + else + { + first_write_status = 0; + } + if (out->config.channels == 8) + { + int *p32 = NULL; + short *p16 = (short *) buf; + int i, NumSamps; + NumSamps = out_frames * frame_size / sizeof (short); + p32 = malloc (NumSamps * sizeof (int)); + if (p32 != NULL) + { + for (i = 0; i < NumSamps; i++) //suppose 16bit/8ch PCM + { + p32[i] = p16[i] << 16; + } + ret = pcm_write (out->pcm, (void *) p32, NumSamps * 4); + free (p32); } - if(!out->standby) - ret = pcm_write(out->pcm, (void *)output_buffer_bytes, ouput_len); - }else{ - if(!out->standby){ - property_get("sys.hdmiIn.Capture",prop,"false"); - // ALOGD("****first_write_status=%d***",first_write_status); - if(!strcmp(prop,"true")){ - if(first_write_status < 20){ - first_write_status = first_write_status + 1; - memset((char*)buf,0,bytes); - } - }else{ - first_write_status = 0; - } - if(out->config.channels==8){ - int *p32=NULL; - short *p16=(short*)buf; - int i,NumSamps; - NumSamps=out_frames*frame_size/sizeof(short); - p32=malloc(NumSamps*sizeof(int)); - if(p32!=NULL) - { - for(i=0;i<NumSamps;i++)//suppose 16bit/8ch PCM - { - p32[i]=p16[i]<<16; - } - ret=pcm_write(out->pcm, (void *)p32, NumSamps*4); - free(p32); - } - } - else - ret = pcm_write(out->pcm, (void *)buf, out_frames * frame_size); - //ret = pcm_mmap_write(out->pcm, (void *)buf, out_frames * frame_size); - } - } - - - exit: - pthread_mutex_unlock(&out->lock); - if (ret != 0) { - usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) / - out_get_sample_rate(&stream->common)); + } + else + { + codec_type = + get_sysfs_int ("/sys/class/audiodsp/digital_codec"); + samesource_flag = + get_sysfs_int ("/sys/class/audiodsp/audio_samesource"); + if (last_codec_type > 0 && codec_type != last_codec_type) + { + samesource_flag = 1; } - - if (force_input_standby) { - pthread_mutex_lock(&adev->lock); - if (adev->active_input) { - in = adev->active_input; - pthread_mutex_lock(&in->lock); - do_input_standby(in); - pthread_mutex_unlock(&in->lock); - } - pthread_mutex_unlock(&adev->lock); + if (samesource_flag == 1 && codec_type) + { + ALOGI + ("to disable same source,need reset alsa,last %d,type %d,same source flag %d ,\n", + last_codec_type, codec_type, samesource_flag); + last_codec_type = codec_type; + pcm_stop (out->pcm); } - - - return bytes; + ret = + pcm_write (out->pcm, (void *) buf, out_frames * frame_size); + } + //ret = pcm_mmap_write(out->pcm, (void *)buf, out_frames * frame_size); + } + } + + +exit: + pthread_mutex_unlock (&out->lock); + if (ret != 0) + { + usleep (bytes * 1000000 / audio_stream_out_frame_size (stream) / + out_get_sample_rate (&stream->common)); + } + + if (force_input_standby) + { + pthread_mutex_lock (&adev->lock); + if (adev->active_input) + { + in = adev->active_input; + pthread_mutex_lock (&in->lock); + do_input_standby (in); + pthread_mutex_unlock (&in->lock); + } + pthread_mutex_unlock (&adev->lock); + } + + + return bytes; } -static int out_get_render_position(const struct audio_stream_out *stream, - uint32_t *dsp_frames) +static int +out_get_render_position (const struct audio_stream_out *stream, + uint32_t * dsp_frames) { - LOGFUNC("%s(%p, %p)", __FUNCTION__, stream, dsp_frames); - return -EINVAL; + LOGFUNC ("%s(%p, %p)", __FUNCTION__, stream, dsp_frames); + return -EINVAL; } -static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) +static int +out_add_audio_effect (const struct audio_stream *stream, + effect_handle_t effect) { - LOGFUNC("%s(%p, %p)", __FUNCTION__, stream, effect); - return 0; + LOGFUNC ("%s(%p, %p)", __FUNCTION__, stream, effect); + return 0; } -static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect) +static int +out_remove_audio_effect (const struct audio_stream *stream, + effect_handle_t effect) { - return 0; + return 0; } -static int out_get_next_write_timestamp(const struct audio_stream_out *stream, - int64_t *timestamp) + +static int +out_get_next_write_timestamp (const struct audio_stream_out *stream, + int64_t * timestamp) { - return -EINVAL; + return -EINVAL; } -static int get_next_buffer(struct resampler_buffer_provider *buffer_provider, - struct resampler_buffer* buffer); -static void release_buffer(struct resampler_buffer_provider *buffer_provider, - struct resampler_buffer* buffer); +static int get_next_buffer (struct resampler_buffer_provider *buffer_provider, + struct resampler_buffer *buffer); +static void release_buffer (struct resampler_buffer_provider *buffer_provider, + struct resampler_buffer *buffer); /** audio_stream_in implementation **/ /* must be called with hw device and input stream mutexes locked */ -static int start_input_stream(struct aml_stream_in *in) -{ - int ret = 0; - unsigned int card = CARD_AMLOGIC_DEFAULT; - unsigned int port = PORT_MM; - - struct aml_audio_device *adev = in->dev; - LOGFUNC("%s(need_echo_reference=%d, channels=%d, rate=%d, requested_rate=%d, mode= %d)", - __FUNCTION__, in->need_echo_reference, in->config.channels, in->config.rate, in->requested_rate, adev->mode); - adev->active_input = in; - - if (adev->mode != AUDIO_MODE_IN_CALL) { - adev->in_device &= ~AUDIO_DEVICE_IN_ALL; - adev->in_device |= in->device; - select_input_device(adev); - } - - ALOGV("%s(in->requested_rate=%d, in->config.rate=%d)", - __FUNCTION__, in->requested_rate, in->config.rate); - - if(getprop_bool("media.libplayer.wfd")){ - PERIOD_SIZE = DEFAULT_PERIOD_SIZE/2; - in->config.period_size = PERIOD_SIZE; - } - else - { - PERIOD_SIZE = DEFAULT_PERIOD_SIZE; - in->config.period_size = PERIOD_SIZE; - } - if (in->need_echo_reference && in->echo_reference == NULL) { - in->echo_reference = get_echo_reference(adev, - AUDIO_FORMAT_PCM_16_BIT, - in->config.channels, - VX_NB_SAMPLING_RATE); - //in->requested_rate); - LOGFUNC("%s(after get_echo_ref.... now in->echo_reference = %p)", __FUNCTION__, in->echo_reference); - - if (in->echo_reference != NULL){ - in->buf_provider.get_next_buffer = get_next_buffer; - in->buf_provider.release_buffer = release_buffer; - ret = create_resampler(in->config.rate, - VX_NB_SAMPLING_RATE, - in->config.channels, - RESAMPLER_QUALITY_DEFAULT, - &in->buf_provider, - &in->resampler); - - if (ret != 0) { - ret = -EINVAL; - return ret; - } - ret = create_resampler(VX_NB_SAMPLING_RATE, - in->config.rate, - in->config.channels, - RESAMPLER_QUALITY_DEFAULT, - NULL,//&in->up_buf_provider, - &in->up_resampler); - - if (ret != 0) { - ret = -EINVAL; - return ret; - } - in->up_resampler_buffer = malloc(RESAMPLER_BUFFER_SIZE); /* todo: allow for reallocing */ - if (in->up_resampler_buffer == NULL) - return ENOMEM; - } - } - /* this assumes routing is done previously */ - in->pcm = pcm_open(card, port, PCM_IN, &in->config); - if (!pcm_is_ready(in->pcm)) { - ALOGE("cannot open pcm_in driver: %s", pcm_get_error(in->pcm)); - pcm_close(in->pcm); - adev->active_input = NULL; - return -ENOMEM; - } - ALOGD("pcm_open in: card(%d), port(%d)", card, port); - - /* if no supported sample rate is available, use the resampler */ - if (in->resampler) { - in->resampler->reset(in->resampler); - in->frames_in = 0; - } - return 0; -} - -static int check_input_stream(struct aml_stream_in *in) -{ - int ret = 0; - unsigned int card = CARD_AMLOGIC_BOARD; - unsigned int port = 0; - int ext_card; - - ext_card = get_external_card(1); - if(ext_card < 0) - { - card = CARD_AMLOGIC_BOARD; - } - else - { - card = ext_card; - } - - /* this assumes routing is done previously */ - in->pcm = pcm_open(card, port, PCM_IN, &in->config); - if (!pcm_is_ready(in->pcm)) { - ALOGE("check_input_stream:cannot open pcm_in driver: %s", pcm_get_error(in->pcm)); - pcm_close(in->pcm); - return -ENOMEM; - } - - pcm_close(in->pcm); - - return 0; -} -static uint32_t in_get_sample_rate(const struct audio_stream *stream) -{ - struct aml_stream_in *in = (struct aml_stream_in *)stream; - - LOGFUNC("%s(%p)", __FUNCTION__, stream); - return in->requested_rate; -} - -static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate) -{ - LOGFUNC("%s(%p, %d)", __FUNCTION__, stream, rate); - return 0; -} - -static size_t in_get_buffer_size(const struct audio_stream *stream) -{ - struct aml_stream_in *in = (struct aml_stream_in *)stream; - - LOGFUNC("%s(%p)", __FUNCTION__, stream); - return get_input_buffer_size(in->config.rate, - AUDIO_FORMAT_PCM_16_BIT, - in->config.channels); -} - -static audio_channel_mask_t in_get_channels(const struct audio_stream *stream) -{ - struct aml_stream_in *in = (struct aml_stream_in *)stream; - if (in->config.channels == 1) { - return AUDIO_CHANNEL_IN_MONO; - } else { - return AUDIO_CHANNEL_IN_STEREO; - } -} - -static audio_format_t in_get_format(const struct audio_stream *stream) -{ - return AUDIO_FORMAT_PCM_16_BIT; -} - -static int in_set_format(struct audio_stream *stream, audio_format_t format) -{ - LOGFUNC("%s(%p, %d)", __FUNCTION__, stream, format); - return 0; +static int +start_input_stream (struct aml_stream_in *in) +{ + int ret = 0; + unsigned int card = CARD_AMLOGIC_DEFAULT; + unsigned int port = PORT_MM; + + struct aml_audio_device *adev = in->dev; + LOGFUNC + ("%s(need_echo_reference=%d, channels=%d, rate=%d, requested_rate=%d, mode= %d)", + __FUNCTION__, in->need_echo_reference, in->config.channels, + in->config.rate, in->requested_rate, adev->mode); + adev->active_input = in; + + if (adev->mode != AUDIO_MODE_IN_CALL) + { + adev->in_device &= ~AUDIO_DEVICE_IN_ALL; + adev->in_device |= in->device; + select_input_device (adev); + } + + ALOGV ("%s(in->requested_rate=%d, in->config.rate=%d)", + __FUNCTION__, in->requested_rate, in->config.rate); + + if (getprop_bool ("media.libplayer.wfd")) + { + PERIOD_SIZE = DEFAULT_PERIOD_SIZE / 2; + in->config.period_size = PERIOD_SIZE; + } + else + { + PERIOD_SIZE = DEFAULT_PERIOD_SIZE; + in->config.period_size = PERIOD_SIZE; + } + if (in->need_echo_reference && in->echo_reference == NULL) + { + in->echo_reference = get_echo_reference (adev, + AUDIO_FORMAT_PCM_16_BIT, + in->config.channels, + VX_NB_SAMPLING_RATE); + //in->requested_rate); + LOGFUNC ("%s(after get_echo_ref.... now in->echo_reference = %p)", + __FUNCTION__, in->echo_reference); + + if (in->echo_reference != NULL) + { + in->buf_provider.get_next_buffer = get_next_buffer; + in->buf_provider.release_buffer = release_buffer; + ret = create_resampler (in->config.rate, + VX_NB_SAMPLING_RATE, + in->config.channels, + RESAMPLER_QUALITY_DEFAULT, + &in->buf_provider, &in->resampler); + + if (ret != 0) + { + ret = -EINVAL; + return ret; + } + ret = create_resampler (VX_NB_SAMPLING_RATE, in->config.rate, in->config.channels, RESAMPLER_QUALITY_DEFAULT, NULL, //&in->up_buf_provider, + &in->up_resampler); + + if (ret != 0) + { + ret = -EINVAL; + return ret; + } + in->up_resampler_buffer = malloc (RESAMPLER_BUFFER_SIZE); /* todo: allow for reallocing */ + if (in->up_resampler_buffer == NULL) + return ENOMEM; + } + } + /* this assumes routing is done previously */ + in->pcm = pcm_open (card, port, PCM_IN, &in->config); + if (!pcm_is_ready (in->pcm)) + { + ALOGE ("cannot open pcm_in driver: %s", pcm_get_error (in->pcm)); + pcm_close (in->pcm); + adev->active_input = NULL; + return -ENOMEM; + } + ALOGD ("pcm_open in: card(%d), port(%d)", card, port); + + /* if no supported sample rate is available, use the resampler */ + if (in->resampler) + { + in->resampler->reset (in->resampler); + in->frames_in = 0; + } + return 0; } -/* must be called with hw device and input stream mutexes locked */ -static int do_input_standby(struct aml_stream_in *in) +static int +check_input_stream (struct aml_stream_in *in) +{ + int ret = 0; + unsigned int card = CARD_AMLOGIC_BOARD; + unsigned int port = 0; + int ext_card; + + ext_card = get_external_card (1); + if (ext_card < 0) + { + card = CARD_AMLOGIC_BOARD; + } + else + { + card = ext_card; + } + + /* this assumes routing is done previously */ + in->pcm = pcm_open (card, port, PCM_IN, &in->config); + if (!pcm_is_ready (in->pcm)) + { + ALOGE ("check_input_stream:cannot open pcm_in driver: %s", + pcm_get_error (in->pcm)); + pcm_close (in->pcm); + return -ENOMEM; + } + + pcm_close (in->pcm); + + return 0; +} + +static uint32_t +in_get_sample_rate (const struct audio_stream *stream) +{ + struct aml_stream_in *in = (struct aml_stream_in *) stream; + + LOGFUNC ("%s(%p)", __FUNCTION__, stream); + return in->requested_rate; +} + +static int +in_set_sample_rate (struct audio_stream *stream, uint32_t rate) +{ + LOGFUNC ("%s(%p, %d)", __FUNCTION__, stream, rate); + return 0; +} + +static size_t +in_get_buffer_size (const struct audio_stream *stream) +{ + struct aml_stream_in *in = (struct aml_stream_in *) stream; + + LOGFUNC ("%s(%p)", __FUNCTION__, stream); + return get_input_buffer_size (in->config.rate, + AUDIO_FORMAT_PCM_16_BIT, in->config.channels); +} + +static audio_channel_mask_t +in_get_channels (const struct audio_stream *stream) +{ + struct aml_stream_in *in = (struct aml_stream_in *) stream; + if (in->config.channels == 1) + { + return AUDIO_CHANNEL_IN_MONO; + } + else + { + return AUDIO_CHANNEL_IN_STEREO; + } +} + +static audio_format_t +in_get_format (const struct audio_stream *stream) { - struct aml_audio_device *adev = in->dev; + return AUDIO_FORMAT_PCM_16_BIT; +} - LOGFUNC("%s(%p)", __FUNCTION__, in); - if (!in->standby) { - pcm_close(in->pcm); - in->pcm = NULL; +static int +in_set_format (struct audio_stream *stream, audio_format_t format) +{ + LOGFUNC ("%s(%p, %d)", __FUNCTION__, stream, format); + return 0; +} - adev->active_input = 0; - if (adev->mode != AUDIO_MODE_IN_CALL) { - adev->in_device &= ~AUDIO_DEVICE_IN_ALL; - select_input_device(adev); - } +/* must be called with hw device and input stream mutexes locked */ +static int +do_input_standby (struct aml_stream_in *in) +{ + struct aml_audio_device *adev = in->dev; + + LOGFUNC ("%s(%p)", __FUNCTION__, in); + if (!in->standby) + { + pcm_close (in->pcm); + in->pcm = NULL; + + adev->active_input = 0; + if (adev->mode != AUDIO_MODE_IN_CALL) + { + adev->in_device &= ~AUDIO_DEVICE_IN_ALL; + select_input_device (adev); + } - if (in->echo_reference != NULL) { - /* stop reading from echo reference */ - in->echo_reference->read(in->echo_reference, NULL); - put_echo_reference(adev, in->echo_reference); - in->echo_reference = NULL; - } + if (in->echo_reference != NULL) + { + /* stop reading from echo reference */ + in->echo_reference->read (in->echo_reference, NULL); + put_echo_reference (adev, in->echo_reference); + in->echo_reference = NULL; + } - in->standby = 1; - } - return 0; + in->standby = 1; + } + return 0; } -static int in_standby(struct audio_stream *stream) + +static int +in_standby (struct audio_stream *stream) { - struct aml_stream_in *in = (struct aml_stream_in *)stream; - int status; - LOGFUNC("%s(%p)", __FUNCTION__, stream); + struct aml_stream_in *in = (struct aml_stream_in *) stream; + int status; + LOGFUNC ("%s(%p)", __FUNCTION__, stream); - pthread_mutex_lock(&in->dev->lock); - pthread_mutex_lock(&in->lock); - status = do_input_standby(in); - pthread_mutex_unlock(&in->lock); - pthread_mutex_unlock(&in->dev->lock); - return status; + pthread_mutex_lock (&in->dev->lock); + pthread_mutex_lock (&in->lock); + status = do_input_standby (in); + pthread_mutex_unlock (&in->lock); + pthread_mutex_unlock (&in->dev->lock); + return status; } -static int in_dump(const struct audio_stream *stream, int fd) +static int +in_dump (const struct audio_stream *stream, int fd) { - LOGFUNC("%s(%p, %d)", __FUNCTION__, stream, fd); - return 0; + LOGFUNC ("%s(%p, %d)", __FUNCTION__, stream, fd); + return 0; } -static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) +static int +in_set_parameters (struct audio_stream *stream, const char *kvpairs) { - struct aml_stream_in *in = (struct aml_stream_in *)stream; - struct aml_audio_device *adev = in->dev; - struct str_parms *parms; - char *str; - char value[32]; - int ret, val = 0; - bool do_standby = false; + struct aml_stream_in *in = (struct aml_stream_in *) stream; + struct aml_audio_device *adev = in->dev; + struct str_parms *parms; + char *str; + char value[32]; + int ret, val = 0; + bool do_standby = false; - LOGFUNC("%s(%p, %s)", __FUNCTION__, stream, kvpairs); - parms = str_parms_create_str(kvpairs); + LOGFUNC ("%s(%p, %s)", __FUNCTION__, stream, kvpairs); + parms = str_parms_create_str (kvpairs); - ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value)); + ret = + str_parms_get_str (parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, + sizeof (value)); - pthread_mutex_lock(&adev->lock); - pthread_mutex_lock(&in->lock); - if (ret >= 0) { - val = atoi(value); - /* no audio source uses val == 0 */ - if ((in->source != val) && (val != 0)) { - in->source = val; - do_standby = true; - } - } + pthread_mutex_lock (&adev->lock); + pthread_mutex_lock (&in->lock); + if (ret >= 0) + { + val = atoi (value); + /* no audio source uses val == 0 */ + if ((in->source != val) && (val != 0)) + { + in->source = val; + do_standby = true; + } + } - ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value)); - if (ret >= 0) { - val = atoi(value) & ~AUDIO_DEVICE_BIT_IN; - if ((in->device != val) && (val != 0)) { - in->device = val; - do_standby = true; - } - } + ret = + str_parms_get_str (parms, AUDIO_PARAMETER_STREAM_ROUTING, value, + sizeof (value)); + if (ret >= 0) + { + val = atoi (value) & ~AUDIO_DEVICE_BIT_IN; + if ((in->device != val) && (val != 0)) + { + in->device = val; + do_standby = true; + } + } - if (do_standby) - do_input_standby(in); - pthread_mutex_unlock(&in->lock); - pthread_mutex_unlock(&adev->lock); + if (do_standby) + do_input_standby (in); + pthread_mutex_unlock (&in->lock); + pthread_mutex_unlock (&adev->lock); - str_parms_destroy(parms); - return ret; + str_parms_destroy (parms); + return ret; } -static char * in_get_parameters(const struct audio_stream *stream, - const char *keys) +static char * +in_get_parameters (const struct audio_stream *stream, const char *keys) { - return strdup(""); + return strdup (""); } -static int in_set_gain(struct audio_stream_in *stream, float gain) +static int +in_set_gain (struct audio_stream_in *stream, float gain) { - LOGFUNC("%s(%p, %f)", __FUNCTION__, stream, gain); - return 0; + LOGFUNC ("%s(%p, %f)", __FUNCTION__, stream, gain); + return 0; } -static void get_capture_delay(struct aml_stream_in *in, - size_t frames, - struct echo_reference_buffer *buffer) +static void +get_capture_delay (struct aml_stream_in *in, + size_t frames, struct echo_reference_buffer *buffer) { - /* read frames available in kernel driver buffer */ - size_t kernel_frames; - struct timespec tstamp; - long buf_delay; - long rsmp_delay; - long kernel_delay; - long delay_ns; - int rsmp_mul = in->config.rate/VX_NB_SAMPLING_RATE; - if (pcm_get_htimestamp(in->pcm, &kernel_frames, &tstamp) < 0) { - buffer->time_stamp.tv_sec = 0; - buffer->time_stamp.tv_nsec = 0; - buffer->delay_ns = 0; - ALOGW("read get_capture_delay(): pcm_htimestamp error"); - return; - } + /* read frames available in kernel driver buffer */ + size_t kernel_frames; + struct timespec tstamp; + long buf_delay; + long rsmp_delay; + long kernel_delay; + long delay_ns; + int rsmp_mul = in->config.rate / VX_NB_SAMPLING_RATE; + if (pcm_get_htimestamp (in->pcm, &kernel_frames, &tstamp) < 0) + { + buffer->time_stamp.tv_sec = 0; + buffer->time_stamp.tv_nsec = 0; + buffer->delay_ns = 0; + ALOGW ("read get_capture_delay(): pcm_htimestamp error"); + return; + } - /* read frames available in audio HAL input buffer - * add number of frames being read as we want the capture time of first sample - * in current buffer */ - buf_delay = (long)(((int64_t)(in->frames_in + in->proc_frames_in * rsmp_mul) * 1000000000) - / in->config.rate); - /* add delay introduced by resampler */ - rsmp_delay = 0; - if (in->resampler) { - rsmp_delay = in->resampler->delay_ns(in->resampler); - } + /* read frames available in audio HAL input buffer + * add number of frames being read as we want the capture time of first sample + * in current buffer */ + buf_delay = + (long) (((int64_t) (in->frames_in + in->proc_frames_in * rsmp_mul) * + 1000000000) / in->config.rate); + /* add delay introduced by resampler */ + rsmp_delay = 0; + if (in->resampler) + { + rsmp_delay = in->resampler->delay_ns (in->resampler); + } - kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / in->config.rate); + kernel_delay = + (long) (((int64_t) kernel_frames * 1000000000) / in->config.rate); - delay_ns = kernel_delay + buf_delay + rsmp_delay; + delay_ns = kernel_delay + buf_delay + rsmp_delay; - buffer->time_stamp = tstamp; - buffer->delay_ns = delay_ns; - ALOGV("get_capture_delay time_stamp = [%ld].[%ld], delay_ns: [%d]," - " kernel_delay:[%ld], buf_delay:[%ld], rsmp_delay:[%ld], kernel_frames:[%d], " - "in->frames_in:[%d], in->proc_frames_in:[%d], frames:[%d]", - buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, buffer->delay_ns, - kernel_delay, buf_delay, rsmp_delay, kernel_frames, - in->frames_in, in->proc_frames_in, frames); + buffer->time_stamp = tstamp; + buffer->delay_ns = delay_ns; + ALOGV ("get_capture_delay time_stamp = [%ld].[%ld], delay_ns: [%d]," + " kernel_delay:[%ld], buf_delay:[%ld], rsmp_delay:[%ld], kernel_frames:[%d], " + "in->frames_in:[%d], in->proc_frames_in:[%d], frames:[%d]", + buffer->time_stamp.tv_sec, buffer->time_stamp.tv_nsec, + buffer->delay_ns, kernel_delay, buf_delay, rsmp_delay, kernel_frames, + in->frames_in, in->proc_frames_in, frames); } -static int32_t update_echo_reference(struct aml_stream_in *in, size_t frames) +static int32_t +update_echo_reference (struct aml_stream_in *in, size_t frames) { - struct echo_reference_buffer b; - b.delay_ns = 0; + struct echo_reference_buffer b; + b.delay_ns = 0; - ALOGV("update_echo_reference, frames = [%d], in->ref_frames_in = [%d], " - "b.frame_count = [%d]", - frames, in->ref_frames_in, frames - in->ref_frames_in); - if (in->ref_frames_in < frames) { - if (in->ref_buf_size < frames) { - in->ref_buf_size = frames; - in->ref_buf = (int16_t *)realloc(in->ref_buf, - in->ref_buf_size * - in->config.channels * sizeof(int16_t)); - } + ALOGV ("update_echo_reference, frames = [%d], in->ref_frames_in = [%d], " + "b.frame_count = [%d]", + frames, in->ref_frames_in, frames - in->ref_frames_in); + if (in->ref_frames_in < frames) + { + if (in->ref_buf_size < frames) + { + in->ref_buf_size = frames; + in->ref_buf = (int16_t *) realloc (in->ref_buf, + in->ref_buf_size * + in->config.channels * + sizeof (int16_t)); + } - b.frame_count = frames - in->ref_frames_in; - b.raw = (void *)(in->ref_buf + in->ref_frames_in * in->config.channels); + b.frame_count = frames - in->ref_frames_in; + b.raw = + (void *) (in->ref_buf + in->ref_frames_in * in->config.channels); - get_capture_delay(in, frames, &b); - LOGFUNC("update_echo_reference return ::b.delay_ns=%d", b.delay_ns); + get_capture_delay (in, frames, &b); + LOGFUNC ("update_echo_reference return ::b.delay_ns=%d", b.delay_ns); - if (in->echo_reference->read(in->echo_reference, &b) == 0) - { - in->ref_frames_in += b.frame_count; - ALOGV("update_echo_reference: in->ref_frames_in:[%d], " - "in->ref_buf_size:[%d], frames:[%d], b.frame_count:[%d]", - in->ref_frames_in, in->ref_buf_size, frames, b.frame_count); - } - } else - ALOGW("update_echo_reference: NOT enough frames to read ref buffer"); - return b.delay_ns; + if (in->echo_reference->read (in->echo_reference, &b) == 0) + { + in->ref_frames_in += b.frame_count; + ALOGV ("update_echo_reference: in->ref_frames_in:[%d], " + "in->ref_buf_size:[%d], frames:[%d], b.frame_count:[%d]", + in->ref_frames_in, in->ref_buf_size, frames, b.frame_count); + } + } + else + ALOGW ("update_echo_reference: NOT enough frames to read ref buffer"); + return b.delay_ns; } -static int set_preprocessor_param(effect_handle_t handle, - effect_param_t *param) +static int +set_preprocessor_param (effect_handle_t handle, effect_param_t * param) { - uint32_t size = sizeof(int); - uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + - param->vsize; + uint32_t size = sizeof (int); + uint32_t psize = ((param->psize - 1) / sizeof (int) + 1) * sizeof (int) + + param->vsize; - int status = (*handle)->command(handle, - EFFECT_CMD_SET_PARAM, - sizeof (effect_param_t) + psize, - param, - &size, - ¶m->status); - if (status == 0) - status = param->status; + int status = (*handle)->command (handle, + EFFECT_CMD_SET_PARAM, + sizeof (effect_param_t) + psize, + param, + &size, + ¶m->status); + if (status == 0) + status = param->status; - return status; + return status; } -static int set_preprocessor_echo_delay(effect_handle_t handle, - int32_t delay_us) +static int +set_preprocessor_echo_delay (effect_handle_t handle, int32_t delay_us) { - uint32_t buf[sizeof(effect_param_t) / sizeof(uint32_t) + 2]; - effect_param_t *param = (effect_param_t *)buf; - LOGFUNC("%s(%p, %d)", __FUNCTION__, handle, delay_us); + uint32_t buf[sizeof (effect_param_t) / sizeof (uint32_t) + 2]; + effect_param_t *param = (effect_param_t *) buf; + LOGFUNC ("%s(%p, %d)", __FUNCTION__, handle, delay_us); - param->psize = sizeof(uint32_t); - param->vsize = sizeof(uint32_t); - *(uint32_t *)param->data = AEC_PARAM_ECHO_DELAY; - *((int32_t *)param->data + 1) = delay_us; + param->psize = sizeof (uint32_t); + param->vsize = sizeof (uint32_t); + *(uint32_t *) param->data = AEC_PARAM_ECHO_DELAY; + *((int32_t *) param->data + 1) = delay_us; - return set_preprocessor_param(handle, param); + return set_preprocessor_param (handle, param); } -static void push_echo_reference(struct aml_stream_in *in, size_t frames) +static void +push_echo_reference (struct aml_stream_in *in, size_t frames) { - /* read frames from echo reference buffer and update echo delay - * in->ref_frames_in is updated with frames available in in->ref_buf */ - int32_t delay_us = update_echo_reference(in, frames)/1000; - int i; - audio_buffer_t buf; + /* read frames from echo reference buffer and update echo delay + * in->ref_frames_in is updated with frames available in in->ref_buf */ + int32_t delay_us = update_echo_reference (in, frames) / 1000; + int i; + audio_buffer_t buf; - if (in->ref_frames_in < frames) - frames = in->ref_frames_in; + if (in->ref_frames_in < frames) + frames = in->ref_frames_in; - buf.frameCount = frames; - buf.raw = in->ref_buf; + buf.frameCount = frames; + buf.raw = in->ref_buf; - for (i = 0; i < in->num_preprocessors; i++) { - if ((*in->preprocessors[i])->process_reverse == NULL) - continue; + for (i = 0; i < in->num_preprocessors; i++) + { + if ((*in->preprocessors[i])->process_reverse == NULL) + continue; - (*in->preprocessors[i])->process_reverse(in->preprocessors[i], - &buf, - NULL); - set_preprocessor_echo_delay(in->preprocessors[i], delay_us); - } + (*in->preprocessors[i])->process_reverse (in->preprocessors[i], + &buf, NULL); + set_preprocessor_echo_delay (in->preprocessors[i], delay_us); + } - in->ref_frames_in -= buf.frameCount; - if (in->ref_frames_in) { - memcpy(in->ref_buf, - in->ref_buf + buf.frameCount * in->config.channels, - in->ref_frames_in * in->config.channels * sizeof(int16_t)); - } + in->ref_frames_in -= buf.frameCount; + if (in->ref_frames_in) + { + memcpy (in->ref_buf, + in->ref_buf + buf.frameCount * in->config.channels, + in->ref_frames_in * in->config.channels * sizeof (int16_t)); + } } -static int get_next_buffer(struct resampler_buffer_provider *buffer_provider, - struct resampler_buffer* buffer) +static int +get_next_buffer (struct resampler_buffer_provider *buffer_provider, + struct resampler_buffer *buffer) { - struct aml_stream_in *in; + struct aml_stream_in *in; - if (buffer_provider == NULL || buffer == NULL) - return -EINVAL; + if (buffer_provider == NULL || buffer == NULL) + return -EINVAL; - in = (struct aml_stream_in *)((char *)buffer_provider - - offsetof(struct aml_stream_in, buf_provider)); + in = (struct aml_stream_in *) ((char *) buffer_provider - + offsetof (struct aml_stream_in, + buf_provider)); - if (in->pcm == NULL) { - buffer->raw = NULL; - buffer->frame_count = 0; - in->read_status = -ENODEV; - return -ENODEV; - } + if (in->pcm == NULL) + { + buffer->raw = NULL; + buffer->frame_count = 0; + in->read_status = -ENODEV; + return -ENODEV; + } - if (in->frames_in == 0) { - in->read_status = pcm_read(in->pcm, - (void*)in->buffer, - in->config.period_size * - audio_stream_in_frame_size(&in->stream)); - if (in->read_status != 0) { - ALOGE("get_next_buffer() pcm_read error %d", in->read_status); - buffer->raw = NULL; - buffer->frame_count = 0; - return in->read_status; - } - in->frames_in = in->config.period_size; - } + if (in->frames_in == 0) + { + in->read_status = pcm_read (in->pcm, + (void *) in->buffer, + in->config.period_size * + audio_stream_in_frame_size (&in->stream)); + if (in->read_status != 0) + { + ALOGE ("get_next_buffer() pcm_read error %d", in->read_status); + buffer->raw = NULL; + buffer->frame_count = 0; + return in->read_status; + } + in->frames_in = in->config.period_size; + } - buffer->frame_count = (buffer->frame_count > in->frames_in) ? - in->frames_in : buffer->frame_count; - buffer->i16 = in->buffer + (in->config.period_size - in->frames_in) * - in->config.channels; + buffer->frame_count = (buffer->frame_count > in->frames_in) ? + in->frames_in : buffer->frame_count; + buffer->i16 = in->buffer + (in->config.period_size - in->frames_in) * + in->config.channels; - return in->read_status; + return in->read_status; } -static void release_buffer(struct resampler_buffer_provider *buffer_provider, - struct resampler_buffer* buffer) +static void +release_buffer (struct resampler_buffer_provider *buffer_provider, + struct resampler_buffer *buffer) { - struct aml_stream_in *in; - if (buffer_provider == NULL || buffer == NULL) - return; + struct aml_stream_in *in; + if (buffer_provider == NULL || buffer == NULL) + return; - in = (struct aml_stream_in *)((char *)buffer_provider - - offsetof(struct aml_stream_in, buf_provider)); + in = (struct aml_stream_in *) ((char *) buffer_provider - + offsetof (struct aml_stream_in, + buf_provider)); - in->frames_in -= buffer->frame_count; + in->frames_in -= buffer->frame_count; } /* read_frames() reads frames from kernel driver, down samples to capture rate * if necessary and output the number of frames requested to the buffer specified */ -static ssize_t read_frames(struct aml_stream_in *in, void *buffer, ssize_t frames) -{ - ssize_t frames_wr = 0; - while (frames_wr < frames) { - size_t frames_rd = frames - frames_wr; - if (in->resampler != NULL) { - in->resampler->resample_from_provider(in->resampler, - (int16_t *)((char *)buffer + - frames_wr * audio_stream_in_frame_size(&in->stream)), - &frames_rd); - } else { - struct resampler_buffer buf = { - { raw : NULL, }, - frame_count : frames_rd, - }; - get_next_buffer(&in->buf_provider, &buf); - if (buf.raw != NULL) { - memcpy((char *)buffer + - frames_wr * audio_stream_in_frame_size(&in->stream), - buf.raw, - buf.frame_count * audio_stream_in_frame_size(&in->stream)); - frames_rd = buf.frame_count; - } - release_buffer(&in->buf_provider, &buf); - } - /* in->read_status is updated by getNextBuffer() also called by - * in->resampler->resample_from_provider() */ - if (in->read_status != 0) - return in->read_status; - - frames_wr += frames_rd; - } - return frames_wr; +static ssize_t +read_frames (struct aml_stream_in *in, void *buffer, ssize_t frames) +{ + ssize_t frames_wr = 0; + while (frames_wr < frames) + { + size_t frames_rd = frames - frames_wr; + if (in->resampler != NULL) + { + in->resampler->resample_from_provider (in->resampler, + (int16_t *) ((char *) buffer + + + frames_wr * + audio_stream_in_frame_size + (&in->stream)), + &frames_rd); + } + else + { + struct resampler_buffer buf = { + {raw:NULL,}, + frame_count:frames_rd, + }; + get_next_buffer (&in->buf_provider, &buf); + if (buf.raw != NULL) + { + memcpy ((char *) buffer + + frames_wr * audio_stream_in_frame_size (&in->stream), + buf.raw, + buf.frame_count * + audio_stream_in_frame_size (&in->stream)); + frames_rd = buf.frame_count; + } + release_buffer (&in->buf_provider, &buf); + } + /* in->read_status is updated by getNextBuffer() also called by + * in->resampler->resample_from_provider() */ + if (in->read_status != 0) + return in->read_status; + + frames_wr += frames_rd; + } + return frames_wr; } /* process_frames() reads frames from kernel driver (via read_frames()), * calls the active audio pre processings and output the number of frames requested * to the buffer specified */ -static ssize_t process_frames(struct aml_stream_in *in, void* buffer, ssize_t frames) -{ - ssize_t frames_wr = 0; - ssize_t proc_frames; - audio_buffer_t in_buf; - audio_buffer_t proc_buf; - audio_buffer_t out_buf; - int i, resp_mul; - resp_mul = in->requested_rate/VX_NB_SAMPLING_RATE; - - proc_frames = frames/resp_mul ; - - while (frames_wr < proc_frames) { - /* first reload enough frames at the end of process input buffer */ - if (in->proc_frames_in < (size_t)proc_frames) { - ssize_t frames_rd; - - if (in->proc_buf_size < (size_t)proc_frames) { - in->proc_buf_size = (size_t)proc_frames; - in->proc_buf = (int16_t *)realloc(in->proc_buf, - in->proc_buf_size * - in->config.channels * sizeof(int16_t)); - ALOGV("process_frames(): in->proc_buf %p size extended to %d frames", - in->proc_buf, in->proc_buf_size); - } - frames_rd = read_frames(in, - in->proc_buf + - in->proc_frames_in * in->config.channels, - proc_frames - in->proc_frames_in); - if (frames_rd < 0) { - frames_wr = frames_rd; - break; - } - in->proc_frames_in += frames_rd; - } - - if (in->echo_reference != NULL) - push_echo_reference(in, in->proc_frames_in); - - /* in_buf.frameCount and out_buf.frameCount indicate respectively - * the maximum number of frames to be consumed and produced by process() */ - in_buf.frameCount = in->proc_frames_in; - in_buf.s16 = in->proc_buf; - proc_buf.frameCount = proc_frames - frames_wr; - proc_buf.s16 = (int16_t *)in->up_resampler_buffer+ frames_wr * in->config.channels; - out_buf.frameCount = (proc_frames - frames_wr) * resp_mul; - out_buf.s16 = (int16_t *)buffer + resp_mul * frames_wr * in->config.channels; - ALOGV("first**in_buf.frameCount=%d***\n**proc_buf.frameCount=%d\n**out_buf.frameCount=%d***", in_buf.frameCount, proc_buf.frameCount, out_buf.frameCount); - - for (i = 0; i < in->num_preprocessors; i++) - (*in->preprocessors[i])->process(in->preprocessors[i], - &in_buf, - &proc_buf);//&out_buf); - if (in->up_resampler != NULL) { - in->up_resampler->resample_from_input(in->up_resampler, - proc_buf.s16, - &(proc_buf.frameCount), - out_buf.s16, - &(out_buf.frameCount)); - } - ALOGV("after**in_buf.frameCount=%d***\n**proc_buf.frameCount=%d\n**out_buf.frameCount=%d***", in_buf.frameCount, proc_buf.frameCount, out_buf.frameCount); - - /* process() has updated the number of frames consumed and produced in - * in_buf.frameCount and out_buf.frameCount respectively - * move remaining frames to the beginning of in->proc_buf */ - in->proc_frames_in -= in_buf.frameCount; - if (in->proc_frames_in) { - memcpy(in->proc_buf, - in->proc_buf + in_buf.frameCount * in->config.channels, - in->proc_frames_in * in->config.channels * sizeof(int16_t)); - } - - /* if not enough frames were passed to process(), read more and retry. */ - if (out_buf.frameCount == 0) - continue; - - frames_wr += out_buf.frameCount/resp_mul;//out_buf.frameCount * VX_NB_SAMPLING_RATE/in->requested_rate; - ALOGV("***last*****frames_wr=%ld***********", frames_wr); - } - return frames_wr; -} - -static ssize_t in_read(struct audio_stream_in *stream, void* buffer, - size_t bytes) -{ - int ret = 0; - int i =0; - struct aml_stream_in *in = (struct aml_stream_in *)stream; - struct aml_audio_device *adev = in->dev; - size_t frames_rq = bytes / audio_stream_in_frame_size(stream); - if(in->voip_mode) - { - int sleepTime; - - sleepTime = 1000*bytes/(in->config.channels * in->config.rate*2); - usleep(sleepTime*1000); - return bytes; - } - /* acquiring hw device mutex systematically is useful if a low priority thread is waiting - * on the input stream mutex - e.g. executing select_mode() while holding the hw device - * mutex - */ - pthread_mutex_lock(&adev->lock); - pthread_mutex_lock(&in->lock); - if (in->standby) { - ret = start_input_stream(in); - if (ret == 0) - in->standby = 0; - } - pthread_mutex_unlock(&adev->lock); - - if (ret < 0) - goto exit; -////////////////////////////////////////////////////////////////// - if (in->need_echo_reference && in->echo_reference == NULL) { - in->echo_reference = get_echo_reference(adev, - AUDIO_FORMAT_PCM_16_BIT, - in->config.channels, - VX_NB_SAMPLING_RATE); - //in->requested_rate); - LOGFUNC("%s(after get_echo_ref.... now in->echo_reference = %p)", __FUNCTION__, in->echo_reference); +static ssize_t +process_frames (struct aml_stream_in *in, void *buffer, ssize_t frames) +{ + ssize_t frames_wr = 0; + ssize_t proc_frames; + audio_buffer_t in_buf; + audio_buffer_t proc_buf; + audio_buffer_t out_buf; + int i, resp_mul; + resp_mul = in->requested_rate / VX_NB_SAMPLING_RATE; + + proc_frames = frames / resp_mul; + + while (frames_wr < proc_frames) + { + /* first reload enough frames at the end of process input buffer */ + if (in->proc_frames_in < (size_t) proc_frames) + { + ssize_t frames_rd; + + if (in->proc_buf_size < (size_t) proc_frames) + { + in->proc_buf_size = (size_t) proc_frames; + in->proc_buf = (int16_t *) realloc (in->proc_buf, + in->proc_buf_size * + in->config.channels * + sizeof (int16_t)); + ALOGV + ("process_frames(): in->proc_buf %p size extended to %d frames", + in->proc_buf, in->proc_buf_size); + } + frames_rd = read_frames (in, + in->proc_buf + + in->proc_frames_in * in->config.channels, + proc_frames - in->proc_frames_in); + if (frames_rd < 0) + { + frames_wr = frames_rd; + break; + } + in->proc_frames_in += frames_rd; + } + + if (in->echo_reference != NULL) + push_echo_reference (in, in->proc_frames_in); + + /* in_buf.frameCount and out_buf.frameCount indicate respectively + * the maximum number of frames to be consumed and produced by process() */ + in_buf.frameCount = in->proc_frames_in; + in_buf.s16 = in->proc_buf; + proc_buf.frameCount = proc_frames - frames_wr; + proc_buf.s16 = + (int16_t *) in->up_resampler_buffer + frames_wr * in->config.channels; + out_buf.frameCount = (proc_frames - frames_wr) * resp_mul; + out_buf.s16 = + (int16_t *) buffer + resp_mul * frames_wr * in->config.channels; + ALOGV + ("first**in_buf.frameCount=%d***\n**proc_buf.frameCount=%d\n**out_buf.frameCount=%d***", + in_buf.frameCount, proc_buf.frameCount, out_buf.frameCount); + + for (i = 0; i < in->num_preprocessors; i++) + (*in->preprocessors[i])->process (in->preprocessors[i], &in_buf, &proc_buf); //&out_buf); + if (in->up_resampler != NULL) + { + in->up_resampler->resample_from_input (in->up_resampler, + proc_buf.s16, + &(proc_buf.frameCount), + out_buf.s16, + &(out_buf.frameCount)); + } + ALOGV + ("after**in_buf.frameCount=%d***\n**proc_buf.frameCount=%d\n**out_buf.frameCount=%d***", + in_buf.frameCount, proc_buf.frameCount, out_buf.frameCount); + + /* process() has updated the number of frames consumed and produced in + * in_buf.frameCount and out_buf.frameCount respectively + * move remaining frames to the beginning of in->proc_buf */ + in->proc_frames_in -= in_buf.frameCount; + if (in->proc_frames_in) + { + memcpy (in->proc_buf, + in->proc_buf + in_buf.frameCount * in->config.channels, + in->proc_frames_in * in->config.channels * + sizeof (int16_t)); + } + + /* if not enough frames were passed to process(), read more and retry. */ + if (out_buf.frameCount == 0) + continue; + + frames_wr += out_buf.frameCount / resp_mul; //out_buf.frameCount * VX_NB_SAMPLING_RATE/in->requested_rate; + ALOGV ("***last*****frames_wr=%ld***********", frames_wr); + } + return frames_wr; +} + +static ssize_t +in_read (struct audio_stream_in *stream, void *buffer, size_t bytes) +{ + int ret = 0; + int i = 0; + struct aml_stream_in *in = (struct aml_stream_in *) stream; + struct aml_audio_device *adev = in->dev; + size_t frames_rq = bytes / audio_stream_in_frame_size (stream); + if (in->voip_mode) + { + int sleepTime; + + sleepTime = 1000 * bytes / (in->config.channels * in->config.rate * 2); + usleep (sleepTime * 1000); + return bytes; + } + /* acquiring hw device mutex systematically is useful if a low priority thread is waiting + * on the input stream mutex - e.g. executing select_mode() while holding the hw device + * mutex + */ + pthread_mutex_lock (&adev->lock); + pthread_mutex_lock (&in->lock); + if (in->standby) + { + ret = start_input_stream (in); + if (ret == 0) + in->standby = 0; + } + pthread_mutex_unlock (&adev->lock); + + if (ret < 0) + goto exit; + if (in->need_echo_reference && in->echo_reference == NULL) + { + in->echo_reference = get_echo_reference (adev, + AUDIO_FORMAT_PCM_16_BIT, + in->config.channels, + VX_NB_SAMPLING_RATE); + //in->requested_rate); + LOGFUNC ("%s(after get_echo_ref.... now in->echo_reference = %p)", + __FUNCTION__, in->echo_reference); #if 1 - if (in->echo_reference != NULL){ - in->buf_provider.get_next_buffer = get_next_buffer; - in->buf_provider.release_buffer = release_buffer; - ret = create_resampler(in->config.rate, - VX_NB_SAMPLING_RATE, - in->config.channels, - RESAMPLER_QUALITY_DEFAULT, - &in->buf_provider, - &in->resampler); - - if (ret != 0) { - ret = -EINVAL; - return ret; - } - ret = create_resampler(VX_NB_SAMPLING_RATE, - in->config.rate, - in->config.channels, - RESAMPLER_QUALITY_DEFAULT, - NULL,//&in->up_buf_provider, - &in->up_resampler); - - if (ret != 0) { - ret = -EINVAL; - return ret; - } - in->up_resampler_buffer = malloc(RESAMPLER_BUFFER_SIZE); /* todo: allow for reallocing */ - if (in->up_resampler_buffer == NULL) - return ENOMEM; - } + if (in->echo_reference != NULL) + { + in->buf_provider.get_next_buffer = get_next_buffer; + in->buf_provider.release_buffer = release_buffer; + ret = create_resampler (in->config.rate, + VX_NB_SAMPLING_RATE, + in->config.channels, + RESAMPLER_QUALITY_DEFAULT, + &in->buf_provider, &in->resampler); + + if (ret != 0) + { + ret = -EINVAL; + return ret; + } + ret = create_resampler (VX_NB_SAMPLING_RATE, in->config.rate, in->config.channels, RESAMPLER_QUALITY_DEFAULT, NULL, //&in->up_buf_provider, + &in->up_resampler); + + if (ret != 0) + { + ret = -EINVAL; + return ret; + } + in->up_resampler_buffer = malloc (RESAMPLER_BUFFER_SIZE); /* todo: allow for reallocing */ + if (in->up_resampler_buffer == NULL) + return ENOMEM; + } #endif - } - + } + ///////////////////////////////////////////////////////////////////// - if (in->num_preprocessors != 0 && in->echo_reference != NULL) - //if (in->num_preprocessors != 0) - ret = process_frames(in, buffer, frames_rq); - else if (in->resampler != NULL) - ret = read_frames(in, buffer, frames_rq); - else - ret = pcm_read(in->pcm, buffer, bytes); - - float volume = computeVolume(stream); - int16_t *hdmi_buf = (int16_t *)buffer; - for(i=0;i<bytes/2;i++){ - hdmi_buf[i] = (int16_t)(((float)hdmi_buf[i])*volume); - } - - if (ret > 0) - ret = 0; - - if (ret == 0 && adev->mic_mute){ - LOGFUNC("%s(adev->mic_mute = %d)", __FUNCTION__, adev->mic_mute); - memset(buffer, 0, bytes); - } - exit: - if (ret < 0) - usleep(bytes * 1000000 / audio_stream_in_frame_size(stream) / - in_get_sample_rate(&stream->common)); - - pthread_mutex_unlock(&in->lock); - return bytes; + if (in->num_preprocessors != 0 && in->echo_reference != NULL) + //if (in->num_preprocessors != 0) + ret = process_frames (in, buffer, frames_rq); + else if (in->resampler != NULL) + ret = read_frames (in, buffer, frames_rq); + else + ret = pcm_read (in->pcm, buffer, bytes); + + float volume = computeVolume (stream); + int16_t *hdmi_buf = (int16_t *) buffer; + for (i = 0; i < bytes / 2; i++) + { + hdmi_buf[i] = (int16_t) (((float) hdmi_buf[i]) * volume); + } + + if (ret > 0) + ret = 0; + + if (ret == 0 && adev->mic_mute) + { + LOGFUNC ("%s(adev->mic_mute = %d)", __FUNCTION__, adev->mic_mute); + memset (buffer, 0, bytes); + } +exit: + if (ret < 0) + usleep (bytes * 1000000 / audio_stream_in_frame_size (stream) / + in_get_sample_rate (&stream->common)); + + pthread_mutex_unlock (&in->lock); + return bytes; } -static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream) +static uint32_t +in_get_input_frames_lost (struct audio_stream_in *stream) { - return 0; + return 0; } -static int in_add_audio_effect(const struct audio_stream *stream, - effect_handle_t effect) +static int +in_add_audio_effect (const struct audio_stream *stream, + effect_handle_t effect) { - struct aml_stream_in *in = (struct aml_stream_in *)stream; - int status; - effect_descriptor_t desc; - LOGFUNC("*********%s", __FUNCTION__); + struct aml_stream_in *in = (struct aml_stream_in *) stream; + int status; + effect_descriptor_t desc; + LOGFUNC ("*********%s", __FUNCTION__); - pthread_mutex_lock(&in->dev->lock); - pthread_mutex_lock(&in->lock); - if (in->num_preprocessors >= MAX_PREPROCESSORS) { - status = -ENOSYS; - goto exit; - } + pthread_mutex_lock (&in->dev->lock); + pthread_mutex_lock (&in->lock); + if (in->num_preprocessors >= MAX_PREPROCESSORS) + { + status = -ENOSYS; + goto exit; + } - status = (*effect)->get_descriptor(effect, &desc); - if (status != 0) - goto exit; + status = (*effect)->get_descriptor (effect, &desc); + if (status != 0) + goto exit; - in->preprocessors[in->num_preprocessors++] = effect; + in->preprocessors[in->num_preprocessors++] = effect; - if (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) { - in->need_echo_reference = true; - do_input_standby(in); - } + if (memcmp (&desc.type, FX_IID_AEC, sizeof (effect_uuid_t)) == 0) + { + in->need_echo_reference = true; + do_input_standby (in); + } exit: - pthread_mutex_unlock(&in->lock); - pthread_mutex_unlock(&in->dev->lock); - return status; -} - -static int in_remove_audio_effect(const struct audio_stream *stream, - effect_handle_t effect) -{ - struct aml_stream_in *in = (struct aml_stream_in *)stream; - int i; - int status = -EINVAL; - bool found = false; - effect_descriptor_t desc; - - pthread_mutex_lock(&in->dev->lock); - pthread_mutex_lock(&in->lock); - if (in->num_preprocessors <= 0) { - status = -ENOSYS; - goto exit; - } - - for (i = 0; i < in->num_preprocessors; i++) { - if (found) { - in->preprocessors[i - 1] = in->preprocessors[i]; - continue; - } - if (in->preprocessors[i] == effect) { - in->preprocessors[i] = NULL; - status = 0; - found = true; - } - } - - if (status != 0) - goto exit; - - in->num_preprocessors--; - - status = (*effect)->get_descriptor(effect, &desc); - if (status != 0) - goto exit; - if (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) { - in->need_echo_reference = false; - do_input_standby(in); - } + pthread_mutex_unlock (&in->lock); + pthread_mutex_unlock (&in->dev->lock); + return status; +} + +static int +in_remove_audio_effect (const struct audio_stream *stream, + effect_handle_t effect) +{ + struct aml_stream_in *in = (struct aml_stream_in *) stream; + int i; + int status = -EINVAL; + bool found = false; + effect_descriptor_t desc; + + pthread_mutex_lock (&in->dev->lock); + pthread_mutex_lock (&in->lock); + if (in->num_preprocessors <= 0) + { + status = -ENOSYS; + goto exit; + } + + for (i = 0; i < in->num_preprocessors; i++) + { + if (found) + { + in->preprocessors[i - 1] = in->preprocessors[i]; + continue; + } + if (in->preprocessors[i] == effect) + { + in->preprocessors[i] = NULL; + status = 0; + found = true; + } + } + + if (status != 0) + goto exit; + + in->num_preprocessors--; + + status = (*effect)->get_descriptor (effect, &desc); + if (status != 0) + goto exit; + if (memcmp (&desc.type, FX_IID_AEC, sizeof (effect_uuid_t)) == 0) + { + in->need_echo_reference = false; + do_input_standby (in); + } exit: - pthread_mutex_unlock(&in->lock); - pthread_mutex_unlock(&in->dev->lock); - return status; -} -static int adev_open_output_stream(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - audio_output_flags_t flags, - struct audio_config *config, - struct audio_stream_out **stream_out) -{ - struct aml_audio_device *ladev = (struct aml_audio_device *)dev; - struct aml_stream_out *out; - int channel_count = popcount(config->channel_mask); - int ret; - int dc;//digital_codec - - LOGFUNC("%s(devices=0x%04x,format=%d, chnum=0x%04x, SR=%d,io handle %d )", __FUNCTION__, devices, - config->format, channel_count, config->sample_rate,handle); - - out = (struct aml_stream_out *)calloc(1, sizeof(struct aml_stream_out)); - if (!out) - return -ENOMEM; - - out->stream.common.get_sample_rate = out_get_sample_rate; - out->stream.common.set_sample_rate = out_set_sample_rate; - out->stream.common.get_buffer_size = out_get_buffer_size; - out->stream.common.get_channels = out_get_channels; - out->stream.common.get_format = out_get_format; - out->stream.common.set_format = out_set_format; - out->stream.common.standby = out_standby; - out->stream.common.dump = out_dump; - out->stream.common.set_parameters = out_set_parameters; - out->stream.common.get_parameters = out_get_parameters; - out->stream.common.add_audio_effect = out_add_audio_effect; - out->stream.common.remove_audio_effect = out_remove_audio_effect; - //out->stream.common.set_voip_mode = out_set_voip_mode; - out->stream.get_latency = out_get_latency; - out->stream.set_volume = out_set_volume; - out->stream.write = out_write; - out->stream.get_render_position = out_get_render_position; - out->stream.get_next_write_timestamp = out_get_next_write_timestamp; - out->config = pcm_config_out; - dc = get_codec_type("/sys/class/audiodsp/digital_codec"); - if(dc == 4 || dc == 5) - out->config.period_size=pcm_config_out.period_size*2; - else if(dc == 7) - out->config.period_size=pcm_config_out.period_size*4*2; - if(channel_count > 2){ - ALOGI("[adev_open_output_stream]: out/%p channel/%d\n",out,channel_count); - out->multich = channel_count; - out->config.channels = channel_count; - } - out->dev = ladev; - out->standby = 1; - - /* FIXME: when we support multiple output devices, we will want to - * do the following: - * adev->devices &= ~AUDIO_DEVICE_OUT_ALL; - * adev->devices |= out->device; - * select_output_device(adev); - * This is because out_set_parameters() with a route is not - * guaranteed to be called after an output stream is opened. - */ - - //config->format = out_get_format(&out->stream.common); - //config->channel_mask = out_get_channels(&out->stream.common); - //config->sample_rate = out_get_sample_rate(&out->stream.common); - LOGFUNC("%s(devices=0x%04x,format=0x%x, chmask=0x%04x, SR=%d)", __FUNCTION__, devices, - config->format, config->channel_mask, config->sample_rate); - - - - *stream_out = &out->stream; - return 0; + pthread_mutex_unlock (&in->lock); + pthread_mutex_unlock (&in->dev->lock); + return status; +} + +static int +adev_open_output_stream (struct audio_hw_device *dev, + audio_io_handle_t handle, + audio_devices_t devices, + audio_output_flags_t flags, + struct audio_config *config, + struct audio_stream_out **stream_out) +{ + struct aml_audio_device *ladev = (struct aml_audio_device *) dev; + struct aml_stream_out *out; + int channel_count = popcount (config->channel_mask); + int ret; + int dc; //digital_codec + + LOGFUNC ("%s(devices=0x%04x,format=%d, chnum=0x%04x, SR=%d,io handle %d )", + __FUNCTION__, devices, config->format, channel_count, + config->sample_rate, handle); + + out = (struct aml_stream_out *) calloc (1, sizeof (struct aml_stream_out)); + if (!out) + return -ENOMEM; + + out->stream.common.get_sample_rate = out_get_sample_rate; + out->stream.common.set_sample_rate = out_set_sample_rate; + out->stream.common.get_buffer_size = out_get_buffer_size; + out->stream.common.get_channels = out_get_channels; + out->stream.common.get_format = out_get_format; + out->stream.common.set_format = out_set_format; + out->stream.common.standby = out_standby; + out->stream.common.dump = out_dump; + out->stream.common.set_parameters = out_set_parameters; + out->stream.common.get_parameters = out_get_parameters; + out->stream.common.add_audio_effect = out_add_audio_effect; + out->stream.common.remove_audio_effect = out_remove_audio_effect; + //out->stream.common.set_voip_mode = out_set_voip_mode; + out->stream.get_latency = out_get_latency; + out->stream.set_volume = out_set_volume; + out->stream.write = out_write; + out->stream.get_render_position = out_get_render_position; + out->stream.get_next_write_timestamp = out_get_next_write_timestamp; + out->config = pcm_config_out; + dc = get_codec_type ("/sys/class/audiodsp/digital_codec"); + if (dc == 4 || dc == 5) + out->config.period_size = pcm_config_out.period_size * 2; + else if (dc == 7) + out->config.period_size = pcm_config_out.period_size * 4 * 2; + if (channel_count > 2) + { + ALOGI ("[adev_open_output_stream]: out/%p channel/%d\n", out, + channel_count); + out->multich = channel_count; + out->config.channels = channel_count; + } + out->dev = ladev; + out->standby = 1; + + /* FIXME: when we support multiple output devices, we will want to + * do the following: + * adev->devices &= ~AUDIO_DEVICE_OUT_ALL; + * adev->devices |= out->device; + * select_output_device(adev); + * This is because out_set_parameters() with a route is not + * guaranteed to be called after an output stream is opened. + */ + + //config->format = out_get_format(&out->stream.common); + //config->channel_mask = out_get_channels(&out->stream.common); + //config->sample_rate = out_get_sample_rate(&out->stream.common); + LOGFUNC ("%s(devices=0x%04x,format=0x%x, chmask=0x%04x, SR=%d)", + __FUNCTION__, devices, config->format, config->channel_mask, + config->sample_rate); + + + + *stream_out = &out->stream; + return 0; err_open: - free(out); - *stream_out = NULL; - return ret; + free (out); + *stream_out = NULL; + return ret; } -static void adev_close_output_stream(struct audio_hw_device *dev, - struct audio_stream_out *stream) +static void +adev_close_output_stream (struct audio_hw_device *dev, + struct audio_stream_out *stream) { - struct aml_stream_out *out = (struct aml_stream_out *)stream; - LOGFUNC("%s(%p, %p)", __FUNCTION__, dev, stream); - out_standby(&stream->common); - if (out->buffer) - free(out->buffer); - if (out->resampler) - release_resampler(out->resampler); + struct aml_stream_out *out = (struct aml_stream_out *) stream; + LOGFUNC ("%s(%p, %p)", __FUNCTION__, dev, stream); + out_standby (&stream->common); + if (out->buffer) + free (out->buffer); + if (out->resampler) + release_resampler (out->resampler); - free(stream); + free (stream); } -static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) +static int +adev_set_parameters (struct audio_hw_device *dev, const char *kvpairs) { - LOGFUNC("%s(%p, %s)", __FUNCTION__, dev, kvpairs); - - struct aml_audio_device *adev = (struct aml_audio_device *)dev; - struct str_parms *parms; - char *str; - char value[32]; - int ret; + LOGFUNC ("%s(%p, %s)", __FUNCTION__, dev, kvpairs); - parms = str_parms_create_str(kvpairs); - ret = str_parms_get_str(parms, "screen_state", value, sizeof(value)); - if (ret >= 0) { - if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) - adev->low_power = false; - else - adev->low_power = true; - } + struct aml_audio_device *adev = (struct aml_audio_device *) dev; + struct str_parms *parms; + char *str; + char value[32]; + int ret; - str_parms_destroy(parms); - return ret; + parms = str_parms_create_str (kvpairs); + ret = str_parms_get_str (parms, "screen_state", value, sizeof (value)); + if (ret >= 0) + { + if (strcmp (value, AUDIO_PARAMETER_VALUE_ON) == 0) + adev->low_power = false; + else + adev->low_power = true; + } + + str_parms_destroy (parms); + return ret; } -static char * adev_get_parameters(const struct audio_hw_device *dev, - const char *keys) +static char * +adev_get_parameters (const struct audio_hw_device *dev, const char *keys) { - LOGFUNC("%s(%p, %s)", __FUNCTION__, dev, keys); - return strdup(""); + LOGFUNC ("%s(%p, %s)", __FUNCTION__, dev, keys); + return strdup (""); } -static int adev_init_check(const struct audio_hw_device *dev) +static int +adev_init_check (const struct audio_hw_device *dev) { - LOGFUNC("%s(%p)", __FUNCTION__, dev); - return 0; + LOGFUNC ("%s(%p)", __FUNCTION__, dev); + return 0; } -static int adev_set_voice_volume(struct audio_hw_device *dev, float volume) +static int +adev_set_voice_volume (struct audio_hw_device *dev, float volume) { - struct aml_audio_device *adev = (struct aml_audio_device *)dev; - LOGFUNC("%s(%p, %f)", __FUNCTION__, dev, volume); - return 0; + struct aml_audio_device *adev = (struct aml_audio_device *) dev; + LOGFUNC ("%s(%p, %f)", __FUNCTION__, dev, volume); + return 0; } -static int adev_set_master_volume(struct audio_hw_device *dev, float volume) +static int +adev_set_master_volume (struct audio_hw_device *dev, float volume) { - LOGFUNC("%s(%p, %f)", __FUNCTION__, dev, volume); - return -ENOSYS; + LOGFUNC ("%s(%p, %f)", __FUNCTION__, dev, volume); + return -ENOSYS; } -static int adev_get_master_volume(struct audio_hw_device *dev, - float *volume) +static int +adev_get_master_volume (struct audio_hw_device *dev, float *volume) { - return -ENOSYS; + return -ENOSYS; } -static int adev_set_master_mute(struct audio_hw_device *dev, bool muted) +static int +adev_set_master_mute (struct audio_hw_device *dev, bool muted) { - return -ENOSYS; + return -ENOSYS; } -static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted) +static int +adev_get_master_mute (struct audio_hw_device *dev, bool * muted) { - return -ENOSYS; + return -ENOSYS; } -static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode) + +static int +adev_set_mode (struct audio_hw_device *dev, audio_mode_t mode) { - struct aml_audio_device *adev = (struct aml_audio_device *)dev; - LOGFUNC("%s(%p, %d)", __FUNCTION__, dev, mode); + struct aml_audio_device *adev = (struct aml_audio_device *) dev; + LOGFUNC ("%s(%p, %d)", __FUNCTION__, dev, mode); - pthread_mutex_lock(&adev->lock); - if (adev->mode != mode) { - adev->mode = mode; - select_mode(adev); - } - pthread_mutex_unlock(&adev->lock); + pthread_mutex_lock (&adev->lock); + if (adev->mode != mode) + { + adev->mode = mode; + select_mode (adev); + } + pthread_mutex_unlock (&adev->lock); - return 0; + return 0; } -static int adev_set_mic_mute(struct audio_hw_device *dev, bool state) +static int +adev_set_mic_mute (struct audio_hw_device *dev, bool state) { - struct aml_audio_device *adev = (struct aml_audio_device *)dev; + struct aml_audio_device *adev = (struct aml_audio_device *) dev; - LOGFUNC("%s(%p, %d)", __FUNCTION__, dev, state); - adev->mic_mute = state; + LOGFUNC ("%s(%p, %d)", __FUNCTION__, dev, state); + adev->mic_mute = state; - return 0; + return 0; } -static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state) +static int +adev_get_mic_mute (const struct audio_hw_device *dev, bool * state) { - struct aml_audio_device *adev = (struct aml_audio_device *)dev; + struct aml_audio_device *adev = (struct aml_audio_device *) dev; - LOGFUNC("%s(%p, %p)", __FUNCTION__, dev, state); - *state = adev->mic_mute; + LOGFUNC ("%s(%p, %p)", __FUNCTION__, dev, state); + *state = adev->mic_mute; - return 0; + return 0; } -static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev, - const struct audio_config *config) +static size_t +adev_get_input_buffer_size (const struct audio_hw_device *dev, + const struct audio_config *config) { - size_t size; - int channel_count = popcount(config->channel_mask); + size_t size; + int channel_count = popcount (config->channel_mask); - LOGFUNC("%s(%p, %d, %d, %d)", __FUNCTION__, dev, config->sample_rate, - config->format, channel_count); - if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0) - return 0; + LOGFUNC ("%s(%p, %d, %d, %d)", __FUNCTION__, dev, config->sample_rate, + config->format, channel_count); + if (check_input_parameters + (config->sample_rate, config->format, channel_count) != 0) + return 0; - return get_input_buffer_size(config->sample_rate, - config->format, channel_count); + return get_input_buffer_size (config->sample_rate, + config->format, channel_count); } -static int adev_open_input_stream(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - struct audio_config *config, - struct audio_stream_in **stream_in) +static int +adev_open_input_stream (struct audio_hw_device *dev, + audio_io_handle_t handle, + audio_devices_t devices, + struct audio_config *config, + struct audio_stream_in **stream_in) { - struct aml_audio_device *ladev = (struct aml_audio_device *)dev; - struct aml_stream_in *in; - int ret; - int channel_count = popcount(config->channel_mask); - LOGFUNC("**********%s(%#x, %d, 0x%04x, %d)", __FUNCTION__, - devices, config->format, config->channel_mask, config->sample_rate); - if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0) - return -EINVAL; - - in = (struct aml_stream_in *)calloc(1, sizeof(struct aml_stream_in)); - if (!in) - return -ENOMEM; + struct aml_audio_device *ladev = (struct aml_audio_device *) dev; + struct aml_stream_in *in; + int ret; + int channel_count = popcount (config->channel_mask); + LOGFUNC ("**********%s(%#x, %d, 0x%04x, %d)", __FUNCTION__, + devices, config->format, config->channel_mask, + config->sample_rate); + if (check_input_parameters + (config->sample_rate, config->format, channel_count) != 0) + return -EINVAL; - in->stream.common.get_sample_rate = in_get_sample_rate; - in->stream.common.set_sample_rate = in_set_sample_rate; - in->stream.common.get_buffer_size = in_get_buffer_size; - in->stream.common.get_channels = in_get_channels; - in->stream.common.get_format = in_get_format; - in->stream.common.set_format = in_set_format; - in->stream.common.standby = in_standby; - in->stream.common.dump = in_dump; - in->stream.common.set_parameters = in_set_parameters; - in->stream.common.get_parameters = in_get_parameters; - in->stream.common.add_audio_effect = in_add_audio_effect; - in->stream.common.remove_audio_effect = in_remove_audio_effect; - //in->stream.common.set_voip_mode = in_set_voip_mode; - in->stream.set_gain = in_set_gain; - in->stream.read = in_read; - in->stream.get_input_frames_lost = in_get_input_frames_lost; + in = (struct aml_stream_in *) calloc (1, sizeof (struct aml_stream_in)); + if (!in) + return -ENOMEM; - in->requested_rate = config->sample_rate; + in->stream.common.get_sample_rate = in_get_sample_rate; + in->stream.common.set_sample_rate = in_set_sample_rate; + in->stream.common.get_buffer_size = in_get_buffer_size; + in->stream.common.get_channels = in_get_channels; + in->stream.common.get_format = in_get_format; + in->stream.common.set_format = in_set_format; + in->stream.common.standby = in_standby; + in->stream.common.dump = in_dump; + in->stream.common.set_parameters = in_set_parameters; + in->stream.common.get_parameters = in_get_parameters; + in->stream.common.add_audio_effect = in_add_audio_effect; + in->stream.common.remove_audio_effect = in_remove_audio_effect; + //in->stream.common.set_voip_mode = in_set_voip_mode; + in->stream.set_gain = in_set_gain; + in->stream.read = in_read; + in->stream.get_input_frames_lost = in_get_input_frames_lost; - memcpy(&in->config, &pcm_config_in, sizeof(pcm_config_in)); - ret = check_input_stream(in); - if(ret < 0) - { - ALOGE("fail to open input stream, change channel count from %d to %d", in->config.channels, channel_count); - in->config.channels = channel_count; - } + in->requested_rate = config->sample_rate; - if(in->config.channels == 1) - { - config->channel_mask = AUDIO_CHANNEL_IN_MONO; - } - else if(in->config.channels == 2) - { - config->channel_mask = AUDIO_CHANNEL_IN_STEREO; - } - else - { - ALOGE("Bad value of channel count : %d", in->config.channels); - } - in->buffer = malloc(in->config.period_size * - audio_stream_in_frame_size(&in->stream)); - if (!in->buffer) { - ret = -ENOMEM; - goto err_open; - } + memcpy (&in->config, &pcm_config_in, sizeof (pcm_config_in)); + ret = check_input_stream (in); + if (ret < 0) + { + ALOGE ("fail to open input stream, change channel count from %d to %d", + in->config.channels, channel_count); + in->config.channels = channel_count; + } - if (in->requested_rate != in->config.rate) { - LOGFUNC("%s(in->requested_rate=%d, in->config.rate=%d)", - __FUNCTION__, in->requested_rate, in->config.rate); - in->buf_provider.get_next_buffer = get_next_buffer; - in->buf_provider.release_buffer = release_buffer; - ret = create_resampler(in->config.rate, - in->requested_rate, - in->config.channels, - RESAMPLER_QUALITY_DEFAULT, - &in->buf_provider, - &in->resampler); + if (in->config.channels == 1) + { + config->channel_mask = AUDIO_CHANNEL_IN_MONO; + } + else if (in->config.channels == 2) + { + config->channel_mask = AUDIO_CHANNEL_IN_STEREO; + } + else + { + ALOGE ("Bad value of channel count : %d", in->config.channels); + } + in->buffer = malloc (in->config.period_size * + audio_stream_in_frame_size (&in->stream)); + if (!in->buffer) + { + ret = -ENOMEM; + goto err_open; + } - if (ret != 0) { - ret = -EINVAL; - goto err_open; - } - } + if (in->requested_rate != in->config.rate) + { + LOGFUNC ("%s(in->requested_rate=%d, in->config.rate=%d)", + __FUNCTION__, in->requested_rate, in->config.rate); + in->buf_provider.get_next_buffer = get_next_buffer; + in->buf_provider.release_buffer = release_buffer; + ret = create_resampler (in->config.rate, + in->requested_rate, + in->config.channels, + RESAMPLER_QUALITY_DEFAULT, + &in->buf_provider, &in->resampler); + + if (ret != 0) + { + ret = -EINVAL; + goto err_open; + } + } - in->dev = ladev; - in->standby = 1; - in->device = devices & ~AUDIO_DEVICE_BIT_IN; + in->dev = ladev; + in->standby = 1; + in->device = devices & ~AUDIO_DEVICE_BIT_IN; - // init hdmi in volume parameters - in->volume_index = 0; - in->last_volume = 0.0f; - in->indexMIn = 0; - in->indexMax = 15; + // init hdmi in volume parameters + in->volume_index = 0; + in->last_volume = 0.0f; + in->indexMIn = 0; + in->indexMax = 15; - *stream_in = &in->stream; - return 0; + *stream_in = &in->stream; + return 0; err_open: - if (in->resampler) - release_resampler(in->resampler); + if (in->resampler) + release_resampler (in->resampler); - free(in); - *stream_in = NULL; - return ret; + free (in); + *stream_in = NULL; + return ret; } -static void adev_close_input_stream(struct audio_hw_device *dev, - struct audio_stream_in *stream) +static void +adev_close_input_stream (struct audio_hw_device *dev, + struct audio_stream_in *stream) { - struct aml_stream_in *in = (struct aml_stream_in *)stream; + struct aml_stream_in *in = (struct aml_stream_in *) stream; - LOGFUNC("%s(%p, %p)", __FUNCTION__, dev, stream); - in_standby(&stream->common); + LOGFUNC ("%s(%p, %p)", __FUNCTION__, dev, stream); + in_standby (&stream->common); - if (in->resampler) { - free(in->buffer); - release_resampler(in->resampler); - } - if (in->up_resampler) { - free(in->up_resampler_buffer); - release_resampler(in->up_resampler); + if (in->resampler) + { + free (in->buffer); + release_resampler (in->resampler); } - if (in->proc_buf) - free(in->proc_buf); - if (in->ref_buf) - free(in->ref_buf); + if (in->up_resampler) + { + free (in->up_resampler_buffer); + release_resampler (in->up_resampler); + } + if (in->proc_buf) + free (in->proc_buf); + if (in->ref_buf) + free (in->ref_buf); - free(stream); + free (stream); - return; + return; } -static int adev_dump(const audio_hw_device_t *device, int fd) +static int +adev_dump (const audio_hw_device_t * device, int fd) { - LOGFUNC("%s(%p, %d)", __FUNCTION__, device, fd); - return 0; + LOGFUNC ("%s(%p, %d)", __FUNCTION__, device, fd); + return 0; } -static int adev_close(hw_device_t *device) +static int +adev_close (hw_device_t * device) { - struct aml_audio_device *adev = (struct aml_audio_device *)device; + struct aml_audio_device *adev = (struct aml_audio_device *) device; - LOGFUNC("%s(%p)", __FUNCTION__, device); - /* RIL */ - //ril_close(&adev->ril); - //audio_route_free(adev->ar); - free(device); - return 0; + LOGFUNC ("%s(%p)", __FUNCTION__, device); + /* RIL */ + //ril_close(&adev->ril); + //audio_route_free(adev->ar); + free (device); + return 0; } -static int adev_open(const hw_module_t* module, const char* name, - hw_device_t** device) +static int +adev_open (const hw_module_t * module, const char *name, + hw_device_t ** device) { - struct aml_audio_device *adev; - int ret; - LOGFUNC("%s(%p, %s, %p)", __FUNCTION__, module, name, device); - if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) - return -EINVAL; + struct aml_audio_device *adev; + int ret; + LOGFUNC ("%s(%p, %s, %p)", __FUNCTION__, module, name, device); + if (strcmp (name, AUDIO_HARDWARE_INTERFACE) != 0) + return -EINVAL; - adev = calloc(1, sizeof(struct aml_audio_device)); - if (!adev) - return -ENOMEM; + adev = calloc (1, sizeof (struct aml_audio_device)); + if (!adev) + return -ENOMEM; - 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.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.get_supported_devices = adev_get_supported_devices; - 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.get_master_volume = adev_get_master_volume; - adev->hw_device.set_master_mute = adev_set_master_mute; - adev->hw_device.get_master_mute = adev_get_master_mute; - 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; + //adev->hw_device.get_supported_devices = adev_get_supported_devices; + 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.get_master_volume = adev_get_master_volume; + adev->hw_device.set_master_mute = adev_set_master_mute; + adev->hw_device.get_master_mute = adev_get_master_mute; + 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; - /* Set the default route before the PCM stream is opened */ - adev->mode = AUDIO_MODE_NORMAL; - adev->out_device = AUDIO_DEVICE_OUT_AUX_DIGITAL; - adev->in_device = AUDIO_DEVICE_IN_BUILTIN_MIC & ~AUDIO_DEVICE_BIT_IN; + /* Set the default route before the PCM stream is opened */ + adev->mode = AUDIO_MODE_NORMAL; + adev->out_device = AUDIO_DEVICE_OUT_AUX_DIGITAL; + adev->in_device = AUDIO_DEVICE_IN_BUILTIN_MIC & ~AUDIO_DEVICE_BIT_IN; - select_output_device(adev); + select_output_device (adev); - *device = &adev->hw_device.common; - return 0; + *device = &adev->hw_device.common; + return 0; } static struct hw_module_methods_t hal_module_methods = { - .open = adev_open, + .open = adev_open, }; struct audio_module HAL_MODULE_INFO_SYM = { - .common = { - .tag = HARDWARE_MODULE_TAG, - .module_api_version = AUDIO_MODULE_API_VERSION_0_1, - .hal_api_version = HARDWARE_HAL_API_VERSION, - .id = AUDIO_HARDWARE_MODULE_ID, - .name = "aml HDMI audio HW HAL", - .author = "amlogic, Corp.", - .methods = &hal_module_methods, - }, + .common = { + .tag = HARDWARE_MODULE_TAG, + .module_api_version = AUDIO_MODULE_API_VERSION_0_1, + .hal_api_version = HARDWARE_HAL_API_VERSION, + .id = AUDIO_HARDWARE_MODULE_ID, + .name = "aml HDMI audio HW HAL", + .author = "amlogic, Corp.", + .methods = &hal_module_methods, + }, }; |