summaryrefslogtreecommitdiff
authorlianghu.su <lianghu.su@amlogic.com>2014-08-01 12:10:30 (GMT)
committer tao.dong <tao.dong@amlogic.com>2014-08-08 09:21:54 (GMT)
commit9951409e47b3199673e832f7b0063341bba7a290 (patch)
tree63331571b6aa347342cf504289bb3e2f4f56fb4a
parent9884a76287c8a653d5941c5bca58a652ae5705ac (diff)
downloadaudio-9951409e47b3199673e832f7b0063341bba7a290.zip
audio-9951409e47b3199673e832f7b0063341bba7a290.tar.gz
audio-9951409e47b3199673e832f7b0063341bba7a290.tar.bz2
pd 88784: Add AudioFocus for HDMI IN.
Change-Id: Ie1b9075c45105c50e0611afe0397472d20f15cef
Diffstat
-rwxr-xr-xhdmi_audio_hw.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/hdmi_audio_hw.c b/hdmi_audio_hw.c
index 58518e9..29e068b 100755
--- a/hdmi_audio_hw.c
+++ b/hdmi_audio_hw.c
@@ -176,6 +176,11 @@ struct aml_stream_in {
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;
};
@@ -188,6 +193,111 @@ 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};
+
+struct VolumeCurvePoint
+{
+ int mIndex;
+ float mDBAttenuation;
+};
+
+struct VolumeCurvePoint sSpeakerMediaVolumeCurve[VOLCNT] = {
+ {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;
+};
+
+
+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];
@@ -1760,6 +1870,7 @@ 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_frame_size(&stream->common);
@@ -1835,6 +1946,12 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
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;
@@ -2238,6 +2355,12 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
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;
+
*stream_in = &in->stream;
return 0;