summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChandrashekhar Urkeri2019-11-25 14:12:32 -0600
committerPraneeth Bajjuri2019-12-02 10:40:47 -0600
commitb15dc329df62b17ba4c479b8523dac47000e9517 (patch)
tree51c65abdfb8e80542cf109ffdc597d64ef20bf58
parentfe55d7b090b2ca1c23ba449ad6b07337733a041a (diff)
downloadhardware-ti-j721e-d-pie-core-release.tar.gz
hardware-ti-j721e-d-pie-core-release.tar.xz
hardware-ti-j721e-d-pie-core-release.zip
j721e: audio: Implement the changes required for CDD compliance using 16 bit audio format.d-pie-core-release
As per Android's CDD doc (https://source.android.com/compatibility/9/android-9-cdd), the audio HAL must support audio resampling between 8000, 11025, 16000, 44100 Hz using Linear PCM, 16-bit format.But the Android's speex library cannot handle resampling of 24 bit audio format hence fall back to 16 bit audio format for both playback and recording.
-rw-r--r--audio/primary/audio_hw.c379
-rw-r--r--audio/primary/audio_policy_configuration.xml8
2 files changed, 376 insertions, 11 deletions
diff --git a/audio/primary/audio_hw.c b/audio/primary/audio_hw.c
index 7787ad9..6c9b3cc 100644
--- a/audio/primary/audio_hw.c
+++ b/audio/primary/audio_hw.c
@@ -42,7 +42,18 @@
42/* yet another definition of ARRAY_SIZE macro) */ 42/* yet another definition of ARRAY_SIZE macro) */
43#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) 43#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
44 44
45#define DEFAULT_AUDIO_FORMAT AUDIO_FORMAT_PCM_24_BIT_PACKED 45#define DEFAULT_AUDIO_FORMAT AUDIO_FORMAT_PCM_16_BIT
46/* buffer_remix: functor for doing in-place buffer manipulations.
47 *
48 * NB. When remix_func is called, the memory at `buf` must be at least
49 * as large as frames * sample_size * MAX(in_chans, out_chans).
50 */
51struct buffer_remix {
52 void (*remix_func)(struct buffer_remix *data, void *buf, size_t frames);
53 size_t sample_size; /* size of one audio sample, in bytes */
54 size_t in_chans; /* number of input channels */
55 size_t out_chans; /* number of output channels */
56};
46 57
47struct j7_audio_device { 58struct j7_audio_device {
48 struct audio_hw_device device; 59 struct audio_hw_device device;
@@ -60,7 +71,10 @@ struct j7_stream_in {
60 struct j7_audio_device *dev; 71 struct j7_audio_device *dev;
61 struct pcm_config config; 72 struct pcm_config config;
62 struct pcm *pcm; 73 struct pcm *pcm;
74 struct buffer_remix *remix; /* adapt hw chan count to client */
75 struct resampler_itfe *resampler;
63 struct resampler_buffer_provider buf_provider; 76 struct resampler_buffer_provider buf_provider;
77 int16_t *buffer;
64 size_t frames_in; 78 size_t frames_in;
65 size_t hw_frame_size; 79 size_t hw_frame_size;
66 unsigned int requested_rate; 80 unsigned int requested_rate;
@@ -78,14 +92,17 @@ struct j7_stream_out {
78 struct j7_audio_device *dev; 92 struct j7_audio_device *dev;
79 struct pcm_config config; 93 struct pcm_config config;
80 struct pcm *pcm; 94 struct pcm *pcm;
95 struct resampler_itfe *resampler;
81 struct timespec last; 96 struct timespec last;
82 pthread_mutex_t lock; 97 pthread_mutex_t lock;
98 int16_t *buffer;
83 size_t hw_frame_size; 99 size_t hw_frame_size;
84 unsigned int requested_rate; 100 unsigned int requested_rate;
85 unsigned int requested_channels; 101 unsigned int requested_channels;
86 unsigned int card; 102 unsigned int card;
87 unsigned int port; 103 unsigned int port;
88 audio_devices_t device; 104 audio_devices_t device;
105 bool needs_remix;
89 bool standby; 106 bool standby;
90 int64_t written; /* total frames written, not cleared when entering standby */ 107 int64_t written; /* total frames written, not cleared when entering standby */
91}; 108};
@@ -95,7 +112,7 @@ static const char *supported_media_cards[] = {
95}; 112};
96 113
97#define MAX_CARD_COUNT 1 114#define MAX_CARD_COUNT 1
98#define BYTES_PER_SAMPLE (3) //for 24 bit 3 bytes are required 115#define BYTES_PER_SAMPLE (2) //for 16 bit 2 bytes are required
99 116
100#define SUPPORTED_IN_DEVICES (AUDIO_DEVICE_IN_WIRED_HEADSET | \ 117#define SUPPORTED_IN_DEVICES (AUDIO_DEVICE_IN_WIRED_HEADSET | \
101 AUDIO_DEVICE_IN_DEFAULT) 118 AUDIO_DEVICE_IN_DEFAULT)
@@ -118,7 +135,7 @@ static const char *supported_media_cards[] = {
118struct pcm_config pcm_config_capture = { 135struct pcm_config pcm_config_capture = {
119 .channels = 2,/* Stereo mode */ 136 .channels = 2,/* Stereo mode */
120 .rate = CAPTURE_SAMPLE_RATE,/* 48K Hz*/ 137 .rate = CAPTURE_SAMPLE_RATE,/* 48K Hz*/
121 .format = PCM_FORMAT_S24_3LE, 138 .format = PCM_FORMAT_S16_LE,
122 .period_size = CAPTURE_PERIOD_SIZE, 139 .period_size = CAPTURE_PERIOD_SIZE,
123 .period_count = CAPTURE_PERIOD_COUNT, 140 .period_count = CAPTURE_PERIOD_COUNT,
124 .start_threshold = 1, 141 .start_threshold = 1,
@@ -128,7 +145,7 @@ struct pcm_config pcm_config_capture = {
128struct pcm_config pcm_config_playback = { 145struct pcm_config pcm_config_playback = {
129 .channels = 2,/* Stereo mode */ 146 .channels = 2,/* Stereo mode */
130 .rate = PLAYBACK_SAMPLE_RATE,/* 48K Hz*/ 147 .rate = PLAYBACK_SAMPLE_RATE,/* 48K Hz*/
131 .format = PCM_FORMAT_S24_3LE, 148 .format = PCM_FORMAT_S16_LE,
132 .period_size = PLAYBACK_PERIOD_SIZE, 149 .period_size = PLAYBACK_PERIOD_SIZE,
133 .period_count = PLAYBACK_PERIOD_COUNT, 150 .period_count = PLAYBACK_PERIOD_COUNT,
134 .start_threshold = PLAYBACK_BUFFER_SIZE / 2, 151 .start_threshold = PLAYBACK_BUFFER_SIZE / 2,
@@ -179,6 +196,91 @@ static size_t get_input_buffer_size(uint32_t sample_rate, int format, int channe
179 196
180 return size * channel_count * audio_bytes_per_sample(format); 197 return size * channel_count * audio_bytes_per_sample(format);
181} 198}
199
200/*
201 * Implementation of buffer_remix::remix_func that removes
202 * channels in place without doing any other processing. The
203 * extra channels are truncated.
204 */
205static void remove_channels_from_buf(struct buffer_remix *data, void *buf, size_t frames)
206{
207 size_t samp_size, in_frame, out_frame;
208 size_t N, c;
209 char *s, *d;
210
211 ALOGV("remove_channels_from_buf() remix=%p buf=%p frames=%zu",
212 data, buf, frames);
213
214 if (frames == 0)
215 return;
216
217 samp_size = data->sample_size;
218 in_frame = data->in_chans * samp_size;
219 out_frame = data->out_chans * samp_size;
220
221 if (out_frame >= in_frame) {
222 ALOGE("BUG: remove_channels_from_buf() can not add channels to a buffer.\n");
223 return;
224 }
225
226 N = frames - 1;
227 d = (char*)buf + out_frame;
228 s = (char*)buf + in_frame;
229
230 /* take the first several channels and truncate the rest */
231 while (N--) {
232 for (c = 0; c < out_frame; ++c)
233 d[c] = s[c];
234 d += out_frame;
235 s += in_frame;
236 }
237}
238
239static int setup_stereo_to_mono_input_remix(struct j7_stream_in *in)
240{
241 ALOGV("setup_stereo_to_mono_input_remix() stream=%p", in);
242
243 struct buffer_remix *br = (struct buffer_remix *)calloc(1, sizeof(struct buffer_remix));
244 if (!br)
245 return -ENOMEM;
246
247 br->remix_func = remove_channels_from_buf;
248 br->sample_size = BYTES_PER_SAMPLE;
249 br->in_chans = 2;
250 br->out_chans = 1;
251 in->remix = br;
252
253 return 0;
254}
255
256
257static void mono_to_stereo(void *dst, const void *src, size_t frames, int sample_size)
258{
259 int in_frame, out_frame;
260 int N, c;
261 char *s, *d;
262
263 ALOGV("mono_to_stereo() src=%p dst=%p frames=%zu", src, dst, frames);
264
265 if (frames == 0)
266 return;
267
268 in_frame = sample_size;
269 out_frame = 2 * sample_size;
270
271 N = frames - 1;
272 d = (char *)dst + N * out_frame;
273 s = (char *)src + N * in_frame;
274
275 /* duplicate first channel into the rest of channels in the frame */
276 while (N-- >= 0) {
277 for (c = 0; c < out_frame; ++c)
278 d[c] = s[c % in_frame];
279 d -= out_frame;
280 s -= in_frame;
281 }
282}
283
182/* audio HAL functions */ 284/* audio HAL functions */
183 285
184static uint32_t out_get_sample_rate(const struct audio_stream *stream) 286static uint32_t out_get_sample_rate(const struct audio_stream *stream)
@@ -388,9 +490,23 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
388 490
389 pthread_mutex_unlock(&adev->lock); 491 pthread_mutex_unlock(&adev->lock);
390 492
391 hw_frames = frames; 493 if (out->resampler) {
392 hw_buf = buffer; 494 in_buf = (void *)buffer;
495 hw_frames = out->config.period_size;
496
497 out->resampler->resample_from_input(out->resampler,
498 in_buf, &frames,
499 out->buffer, &hw_frames);
500 hw_buf = out->buffer;
501 } else {
502 hw_frames = frames;
503 hw_buf = buffer;
504 }
393 505
506 if (out->needs_remix) {
507 mono_to_stereo(out->buffer, hw_buf, hw_frames, BYTES_PER_SAMPLE);
508 hw_buf = out->buffer;
509 }
394 ret = pcm_write(out->pcm, hw_buf, hw_frames * out->hw_frame_size); 510 ret = pcm_write(out->pcm, hw_buf, hw_frames * out->hw_frame_size);
395 if (ret) { 511 if (ret) {
396 ALOGE("out_write() failed to write audio data %d", ret); 512 ALOGE("out_write() failed to write audio data %d", ret);
@@ -617,6 +733,115 @@ static int in_set_gain(struct audio_stream_in *stream, float gain)
617 return 0; 733 return 0;
618} 734}
619 735
736static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
737 struct resampler_buffer* buffer)
738{
739 struct j7_stream_in *in;
740 struct buffer_remix *remix;
741
742 if (buffer_provider == NULL || buffer == NULL)
743 return -EINVAL;
744
745 in = (struct j7_stream_in *)((char *)buffer_provider -
746 offsetof(struct j7_stream_in, buf_provider));
747
748 if (in->pcm == NULL) {
749 buffer->raw = NULL;
750 buffer->frame_count = 0;
751 in->read_status = -ENODEV;
752 return -ENODEV;
753 }
754
755 if (in->frames_in == 0) {
756 in->read_status = pcm_read(in->pcm,
757 (void*)in->buffer,
758 buffer->frame_count * in->hw_frame_size);
759 if (in->read_status != 0) {
760 ALOGE("get_next_buffer() pcm_read error %d", in->read_status);
761 buffer->raw = NULL;
762 buffer->frame_count = 0;
763 return in->read_status;
764 }
765 in->frames_in = buffer->frame_count;
766
767 remix = in->remix;
768 if (remix)
769 remix->remix_func(remix, in->buffer, in->frames_in);
770 }
771
772 buffer->frame_count = (buffer->frame_count > in->frames_in) ?
773 in->frames_in : buffer->frame_count;
774 buffer->i16 = in->buffer;
775
776 return in->read_status;
777}
778
779static void release_buffer(struct resampler_buffer_provider *buffer_provider,
780 struct resampler_buffer* buffer)
781{
782 struct j7_stream_in *in;
783
784 if (buffer_provider == NULL || buffer == NULL)
785 return;
786
787 in = (struct j7_stream_in *)((char *)buffer_provider -
788 offsetof(struct j7_stream_in, buf_provider));
789
790 in->frames_in -= buffer->frame_count;
791}
792
793/*
794 * read_frames() reads frames from kernel driver, down samples to capture rate
795 * if necessary and output the number of frames requested to the buffer specified
796 */
797static ssize_t read_frames(struct j7_stream_in *in, void *buffer, ssize_t frames)
798{
799 const struct audio_stream_in *s = (const struct audio_stream_in *)in;
800 ssize_t frames_wr = 0;
801 size_t frame_size;
802
803 ALOGV("read_frames() stream=%p frames=%zu", in, frames);
804
805 if (in->remix)
806 frame_size = audio_stream_in_frame_size(s);
807 else
808 frame_size = in->hw_frame_size;
809
810 while (frames_wr < frames) {
811 size_t frames_rd = frames - frames_wr;
812
813 if (in->resampler) {
814 in->resampler->resample_from_provider(in->resampler,
815 (int16_t *)((char *)buffer + frames_wr * frame_size),
816 &frames_rd);
817 } else {
818 struct resampler_buffer buf = {
819 { .raw = NULL, },
820 .frame_count = frames_rd,
821 };
822
823 get_next_buffer(&in->buf_provider, &buf);
824 if (buf.raw) {
825 memcpy((char *)buffer + frames_wr * frame_size,
826 buf.raw,
827 buf.frame_count * frame_size);
828 frames_rd = buf.frame_count;
829 }
830 release_buffer(&in->buf_provider, &buf);
831 }
832
833 /* in->read_status is updated by getNextBuffer() also called by
834 * in->resampler->resample_from_provider() */
835 if (in->read_status != 0)
836 return in->read_status;
837
838 frames_wr += frames_rd;
839
840 }
841
842 return frames_wr;
843}
844
620static ssize_t in_read(struct audio_stream_in *stream, void* buffer, 845static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
621 size_t bytes) 846 size_t bytes)
622{ 847{
@@ -649,11 +874,22 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
649 pthread_mutex_unlock(&adev->lock); 874 pthread_mutex_unlock(&adev->lock);
650 return -ENODEV; 875 return -ENODEV;
651 } 876 }
877
878 /* if no supported sample rate is available, use the resampler */
879 if (in->resampler) {
880 in->resampler->reset(in->resampler);
881 in->frames_in = 0;
882 }
883
652 in->standby = false; 884 in->standby = false;
653 } 885 }
654 886
655 pthread_mutex_unlock(&adev->lock); 887 pthread_mutex_unlock(&adev->lock);
656 ret = pcm_read(in->pcm, buffer, bytes); 888
889 if (in->resampler || in->remix)
890 ret = read_frames(in, buffer, frames);
891 else
892 ret = pcm_read(in->pcm, buffer, bytes);
657 893
658 if (ret < 0) { 894 if (ret < 0) {
659 ALOGE("in_read() failed to read audio data %d", ret); 895 ALOGE("in_read() failed to read audio data %d", ret);
@@ -745,14 +981,70 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
745 out->requested_rate = config->sample_rate; 981 out->requested_rate = config->sample_rate;
746 out->requested_channels = popcount(config->channel_mask); 982 out->requested_channels = popcount(config->channel_mask);
747 out->hw_frame_size = out->config.channels * BYTES_PER_SAMPLE; 983 out->hw_frame_size = out->config.channels * BYTES_PER_SAMPLE;
984 out->resampler = NULL;
985 out->buffer = NULL;
748 out->written = 0; 986 out->written = 0;
749 out->card = adev->card; 987 out->card = adev->card;
750 out->port = 0; 988 out->port = 0;
751 out->device = devices; 989 out->device = devices;
752 adev->out = out; 990 adev->out = out;
991
992 /* mono-to-stereo remix since playback stream is stereo */
993 if (out->requested_channels == 1) {
994 ALOGV("adev_open_output_stream() mono-to-stereo remix needed");
995 out->needs_remix = true;
996 } else if (out->requested_channels == 2) {
997 out->needs_remix = false;
998 } else {
999 ALOGE("adev_open_output_stream() %d channels is not supported",
1000 out->requested_channels);
1001 ret = -ENOTSUP;
1002 goto err1;
1003 }
1004
1005 if (out->requested_rate != out->config.rate) {
1006 ALOGV("adev_output_output_stream() resample needed, req=%uHz got=%uHz",
1007 out->requested_rate, out->config.rate);
1008
1009 ret = create_resampler(out->requested_rate,
1010 out->config.rate,
1011 out->requested_channels,
1012 RESAMPLER_QUALITY_DEFAULT,
1013 NULL,
1014 &out->resampler);
1015 if (ret) {
1016 ALOGE("adev_open_output_stream() failed to create resampler %d", ret);
1017 goto err1;
1018 }
1019 }
1020
1021 if (out->resampler || out->needs_remix) {
1022 /*
1023 * Supported sampling rates that require resampling are lower than the
1024 * HAL's default sampling rate (44.1kHz) so a buffer as large as the HAL's
1025 * will suffice
1026 */
1027 buffer_size = out->config.period_size * out->hw_frame_size;
1028
1029 if (out->needs_remix)
1030 buffer_size *= 2;
1031
1032 out->buffer = malloc(buffer_size);
1033 if (!out->buffer) {
1034 ret = -ENOMEM;
1035 goto err2;
1036 }
1037 }
1038
753 *stream_out = &out->stream; 1039 *stream_out = &out->stream;
754 1040
755 return 0; 1041 return 0;
1042
1043 err2:
1044 release_resampler(out->resampler);
1045 err1:
1046 free(out);
1047 return ret;
756} 1048}
757 1049
758static void adev_close_output_stream(struct audio_hw_device *dev, 1050static void adev_close_output_stream(struct audio_hw_device *dev,
@@ -765,6 +1057,12 @@ static void adev_close_output_stream(struct audio_hw_device *dev,
765 1057
766 out_standby(&stream->common); 1058 out_standby(&stream->common);
767 1059
1060 if (out->resampler)
1061 release_resampler(out->resampler);
1062
1063 if (out->buffer)
1064 free(out->buffer);
1065
768 free(out); 1066 free(out);
769 adev->out = NULL; 1067 adev->out = NULL;
770} 1068}
@@ -941,13 +1239,71 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
941 in->requested_rate = config->sample_rate; 1239 in->requested_rate = config->sample_rate;
942 in->requested_channels = popcount(config->channel_mask); 1240 in->requested_channels = popcount(config->channel_mask);
943 in->hw_frame_size = in->config.channels * BYTES_PER_SAMPLE; 1241 in->hw_frame_size = in->config.channels * BYTES_PER_SAMPLE;
1242 in->remix = NULL;
1243 in->resampler = NULL;
1244 in->buffer = NULL;
944 in->card = adev->card; 1245 in->card = adev->card;
945 in->port = 1; 1246 in->port = 1;
946 in->device = devices; 1247 in->device = devices;
947 adev->in = in; 1248 adev->in = in;
1249
1250 /* in-place stereo-to-mono remix since capture stream is stereo */
1251 if (in->requested_channels == 1) {
1252 ALOGD("adev_open_input_stream() stereo-to-mono remix needed");
1253 ret = setup_stereo_to_mono_input_remix(in);
1254 if (ret) {
1255 ALOGE("adev_open_input_stream() failed to setup remix %d", ret);
1256 goto err1;
1257 }
1258 }
1259
1260 if (in->requested_rate != in->config.rate) {
1261 ALOGD("adev_open_input_stream() resample needed, req=%uHz got=%uHz",
1262 in->requested_rate, in->config.rate);
1263
1264 in->buf_provider.get_next_buffer = get_next_buffer;
1265 in->buf_provider.release_buffer = release_buffer;
1266 ret = create_resampler(in->config.rate,
1267 in->requested_rate,
1268 in->requested_channels,
1269 RESAMPLER_QUALITY_DEFAULT,
1270 &in->buf_provider,
1271 &in->resampler);
1272 if (ret) {
1273 ALOGE("adev_open_input_stream() failed to create resampler %d", ret);
1274 goto err2;
1275 }
1276 }
1277
1278 /*
1279 * buffer size needs to be enough to allow stereo-to-mono remix
1280 * and resample if needed
1281 */
1282 if (in->resampler || in->remix) {
1283 buffer_size = in->config.period_size * in->hw_frame_size;
1284
1285 if (in->resampler)
1286 buffer_size *= 2;
1287 if (in->remix)
1288 buffer_size *= 2;
1289
1290 in->buffer = malloc(buffer_size);
1291 if (!in->buffer) {
1292 ret = -ENOMEM;
1293 goto err3;
1294 }
1295 }
948 *stream_in = &in->stream; 1296 *stream_in = &in->stream;
949 1297
950 return 0; 1298 return 0;
1299
1300 err3:
1301 release_resampler(in->resampler);
1302 err2:
1303 free(in->remix);
1304 err1:
1305 free(in);
1306 return ret;
951} 1307}
952 1308
953static void adev_close_input_stream(struct audio_hw_device *dev, 1309static void adev_close_input_stream(struct audio_hw_device *dev,
@@ -960,6 +1316,15 @@ static void adev_close_input_stream(struct audio_hw_device *dev,
960 1316
961 in_standby(&stream->common); 1317 in_standby(&stream->common);
962 1318
1319 if (in->resampler)
1320 release_resampler(in->resampler);
1321
1322 if (in->remix)
1323 free(in->remix);
1324
1325 if (in->buffer)
1326 free(in->buffer);
1327
963 free(in); 1328 free(in);
964 adev->in = NULL; 1329 adev->in = NULL;
965} 1330}
diff --git a/audio/primary/audio_policy_configuration.xml b/audio/primary/audio_policy_configuration.xml
index a4fc066..3cd301e 100644
--- a/audio/primary/audio_policy_configuration.xml
+++ b/audio/primary/audio_policy_configuration.xml
@@ -10,13 +10,13 @@
10 10
11 <mixPorts> 11 <mixPorts>
12 <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY"> 12 <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
13 <profile name="" format="AUDIO_FORMAT_PCM_24_BIT_PACKED" 13 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
14 samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> 14 samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
15 </mixPort> 15 </mixPort>
16 <mixPort name="primary input" role="sink"> 16 <mixPort name="primary input" role="sink">
17 <profile name="" format="AUDIO_FORMAT_PCM_24_BIT_PACKED" 17 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
18 samplingRates="48000" 18 samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
19 channelMasks="AUDIO_CHANNEL_IN_STEREO"/> 19 channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
20 </mixPort> 20 </mixPort>
21 </mixPorts> 21 </mixPorts>
22 22