author | zhenggang.luo <zhenggang.luo@amlogic.com> | 2014-05-27 02:34:42 (GMT) |
---|---|---|
committer | tao.dong <tao.dong@amlogic.com> | 2014-06-03 07:16:13 (GMT) |
commit | 86b08ad0f3f662ff7e648acbbd48a15b73593e80 (patch) | |
tree | ca92f3e02c11dffe7d47e32c086aabd1510efe7d | |
parent | 18e36ecadc19ae9696061580e1fed7aa72321fd0 (diff) | |
download | audio-86b08ad0f3f662ff7e648acbbd48a15b73593e80.zip audio-86b08ad0f3f662ff7e648acbbd48a15b73593e80.tar.gz audio-86b08ad0f3f662ff7e648acbbd48a15b73593e80.tar.bz2 |
PD #89864: part of modification for suppport muti_channel pcm output
-rwxr-xr-x | audio_hw.c | 25 | ||||
-rwxr-xr-x | hdmi_audio_hw.c | 149 |
2 files changed, 120 insertions, 54 deletions
@@ -916,7 +916,7 @@ static int out_set_volume(struct audio_stream_out *stream, float left, static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, size_t bytes) { - int ret; + 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_frame_size(&out->stream.common); @@ -938,6 +938,29 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, */ pthread_mutex_lock(&adev->lock); pthread_mutex_lock(&out->lock); + #if 1 + #define DOLBY_SYSTEM_CHANNEL "ds1.audio.multichannel.support" + char value[128]={0}; + property_get(DOLBY_SYSTEM_CHANNEL,value,NULL); + if((!strcmp(value,"true") ||!strcmp(value,"1")) && out->config.channels!=8) + { + if (!out->standby) { + ALOGI("[%s %d]8ch PCM output,standby other outputs/%p...\n",__FUNCTION__,__LINE__,out); + pcm_close(out->pcm); + out->pcm = NULL; + out->frame_count = 0; + adev->active_output = 0; + if (out->echo_reference != NULL) {/* stop writing to echo reference */ + out->echo_reference->write(out->echo_reference, NULL); + out->echo_reference = NULL; + } + out->standby = 1; + output_standby = 1; + } + pthread_mutex_unlock(&adev->lock); + goto exit; + } + #endif if (out->standby) { ret = start_output_stream(out); if (ret != 0) { diff --git a/hdmi_audio_hw.c b/hdmi_audio_hw.c index e8c53a2..7069066 100755 --- a/hdmi_audio_hw.c +++ b/hdmi_audio_hw.c @@ -133,13 +133,13 @@ struct aml_stream_out { }; typedef struct hdmi_stream_state{ - struct aml_stream_out *pCurStreamOut; - struct aml_stream_out *pLastStreamOut; + void *pLastStreamOut; int LastStreamDirectFlag; int CurStreamDirectFlag; int LastStreamInUse; int CurStreamInUse; int init_flag; + int N8ch_out_flag; pthread_mutex_t hdmi_state_mutex; }hdmi_stream_state_t; @@ -429,6 +429,12 @@ static int start_output_stream(struct aml_stream_out *out) 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; @@ -437,7 +443,7 @@ static int start_output_stream(struct aml_stream_out *out) * tinyalsa. */ int codec_type=get_codec_type("/sys/class/audiodsp/digital_codec"); - if(codec_type==4){ + 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; @@ -446,45 +452,43 @@ static int start_output_stream(struct aml_stream_out *out) out->config.start_threshold = PERIOD_SIZE * PLAYBACK_PERIOD_COUNT; } out->config.avail_min = 0;//SHORT_PERIOD_SIZE; - if(HdmiStreamState.LastStreamInUse) { - if(HdmiStreamState.LastStreamDirectFlag){ - ALOGI("LatsStream/%p still inUse for Direct output!\n",HdmiStreamState.pLastStreamOut); + if(HdmiStreamState.LastStreamDirectFlag|| HdmiStreamState.N8ch_out_flag){ + ALOGI("LatsStream/%p still inUse for Direct output/8ch output!\n",HdmiStreamState.pLastStreamOut); return -1; }else{ - if(HdmiStreamState.pLastStreamOut!=NULL){ - if(HdmiStreamState.pLastStreamOut!=out){ - ALOGI("Force standy LastStream/%p\n",HdmiStreamState.pLastStreamOut); - //------------------------------------------------------------ - //do_output_standby(HdmiStreamState.pLastStreamOut); - struct aml_audio_device *adev_local = HdmiStreamState.pLastStreamOut->dev; - if (!HdmiStreamState.pLastStreamOut->standby) - { - ALOGI("[%s %d]pcm_opened/%d\n",__FUNCTION__,__LINE__,pcm_opened); - pcm_close(HdmiStreamState.pLastStreamOut->pcm); - pcm_opened=0; - HdmiStreamState.pLastStreamOut->pcm = NULL; - adev_local->active_output = 0; - if (HdmiStreamState.pLastStreamOut->echo_reference != NULL) { - HdmiStreamState.pLastStreamOut->echo_reference->write(HdmiStreamState.pLastStreamOut->echo_reference, NULL); - HdmiStreamState.pLastStreamOut->echo_reference = NULL; - } - HdmiStreamState.pLastStreamOut->standby = 1; - } + struct aml_stream_out *pLastStreamOut=(struct aml_stream_out *)HdmiStreamState.pLastStreamOut; + if(pLastStreamOut!=NULL && pLastStreamOut!=out && (codec_type||out->config.channels==8))//corruent output mode:digital_raw + { + ALOGI("[%s %d]Force standy LastStream/%p\n",pLastStreamOut); + //------------------------------------------------------------ + //do_output_standby(HdmiStreamState.pLastStreamOut); + struct aml_audio_device *adev_local =pLastStreamOut->dev; + if (!pLastStreamOut->standby) + { + pcm_close(pLastStreamOut->pcm); + pLastStreamOut->pcm = NULL; + adev_local->active_output = 0; + if (pLastStreamOut->echo_reference != NULL) { + pLastStreamOut->echo_reference->write(pLastStreamOut->echo_reference, NULL); + pLastStreamOut->echo_reference = NULL; + } + pLastStreamOut->standby = 1; + } //-------------------------------------- } - }else{ - ALOGI("[%s %d]ERR pLastStreamOut should not NULL here ",__FUNCTION__,__LINE__); - HdmiStreamState.LastStreamInUse=0; - HdmiStreamState.LastStreamDirectFlag=0; - return -1; - } } } + HdmiStreamState.pLastStreamOut=out; HdmiStreamState.LastStreamInUse=1; HdmiStreamState.LastStreamDirectFlag=codec_type; + HdmiStreamState.N8ch_out_flag=0; + if(out->config.channels==8) + { + HdmiStreamState.N8ch_out_flag=1; + } if(out->config.rate!=DEFAULT_OUT_SAMPLING_RATE){ @@ -507,14 +511,10 @@ static int start_output_stream(struct aml_stream_out *out) 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); - ALOGI("[%s %d]pcm_opened/%d\n",__FUNCTION__,__LINE__,pcm_opened); out->pcm = pcm_open(card, port, PCM_OUT /*| PCM_MMAP | PCM_NOIRQ*/, &(out->config)); - pcm_opened=1; if (!pcm_is_ready(out->pcm)) { ALOGE("cannot open pcm_out driver: %s", pcm_get_error(out->pcm)); - ALOGI("[%s %d]pcm_opened/%d\n",__FUNCTION__,__LINE__,pcm_opened); pcm_close(out->pcm); - pcm_opened=0; adev->active_output = NULL; return -ENOMEM; } @@ -684,7 +684,7 @@ static size_t out_get_buffer_size(const struct audio_stream *stream) */ size_t size; int codec_type=get_codec_type("/sys/class/audiodsp/digital_codec"); - if(codec_type==4)//dd+ + if(codec_type == 4 || codec_type == 5)//dd+ size = (PERIOD_SIZE*2* PLAYBACK_PERIOD_COUNT * DEFAULT_OUT_SAMPLING_RATE) / out->config.rate; else if(codec_type>0 && codec_type<4 ) //dd/dts size = (PERIOD_SIZE*4*DEFAULT_OUT_SAMPLING_RATE) / out->config.rate; @@ -728,16 +728,16 @@ static int do_output_standby(struct aml_stream_out *out) { struct aml_audio_device *adev = out->dev; pthread_mutex_lock(&HdmiStreamState.hdmi_state_mutex); + if(HdmiStreamState.pLastStreamOut==out){ + ALOGI("[%s %d]Clear LastStream/%p \n",__FUNCTION__,__LINE__,HdmiStreamState.pLastStreamOut); + HdmiStreamState.pLastStreamOut=NULL; + HdmiStreamState.LastStreamInUse=0; + HdmiStreamState.LastStreamDirectFlag=0; + HdmiStreamState.N8ch_out_flag=0; + } + pthread_mutex_unlock(&HdmiStreamState.hdmi_state_mutex); if (!out->standby) { - if(HdmiStreamState.pLastStreamOut==out){ - ALOGI("[%s %d]Clear LastStream/%p\n",__FUNCTION__,__LINE__,HdmiStreamState.pLastStreamOut); - HdmiStreamState.pLastStreamOut=NULL; - HdmiStreamState.LastStreamInUse=0; - HdmiStreamState.LastStreamDirectFlag=0; - } - ALOGI("[%s %d]pcm_opened/%d\n",__FUNCTION__,__LINE__,pcm_opened); pcm_close(out->pcm); - pcm_opened=0; out->pcm = NULL; adev->active_output = 0; @@ -759,7 +759,7 @@ static int do_output_standby(struct aml_stream_out *out) out->standby = 1; first_write_status = 0; } - pthread_mutex_unlock(&HdmiStreamState.hdmi_state_mutex); + return 0; } @@ -900,7 +900,7 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, size_t bytes) { - int ret; + 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_frame_size(&out->stream.common); @@ -943,6 +943,29 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, pthread_mutex_unlock(&adev->lock); goto exit; } + //-----------8CH PCM judge----------- + #if 1 + #define DOLBY_SYSTEM_CHANNEL "ds1.audio.multichannel.support" + char value[128]={0}; + property_get(DOLBY_SYSTEM_CHANNEL,value,NULL); + if((!strcmp(value,"true") ||!strcmp(value,"1")) && out->config.channels!=8) + { + if (!out->standby) { + ALOGI("[%s %d]8ch PCM output,standby other outputs/%p...\n",__FUNCTION__,__LINE__,out); + pcm_close(out->pcm); + out->pcm = NULL; + adev->active_output = 0; + if (out->echo_reference != NULL) {/* stop writing to echo reference */ + out->echo_reference->write(out->echo_reference, NULL); + out->echo_reference = NULL; + } + out->standby = 1; + } + pthread_mutex_unlock(&adev->lock); + goto exit; + } + #endif + //-------------------------------- if (out->standby) { ret = start_output_stream(out); if (ret != 0) { @@ -1048,8 +1071,25 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, }else{ first_write_status = 0; } - ret = pcm_write(out->pcm, (void *)buf, out_frames * frame_size); - //ret = pcm_mmap_write(out->pcm, (void *)buf, out_frames * frame_size); + 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); } } @@ -1886,6 +1926,7 @@ static int adev_open_output_stream(struct audio_hw_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); @@ -1913,11 +1954,13 @@ static int adev_open_output_stream(struct audio_hw_device *dev, 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; - if(get_codec_type("/sys/class/audiodsp/digital_codec")==4) - out->config.period_size=pcm_config_out.period_size*2;; - if(channel_count > 2){ - ALOGI("adev_open_output_stream channel :%d\n",channel_count); - out->multich = channel_count; + dc = get_codec_type("/sys/class/audiodsp/digital_codec"); + if(dc == 4 || dc == 5) + out->config.period_size=pcm_config_out.period_size*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; |