summaryrefslogtreecommitdiff
path: root/libTVaudio/audio/android_out.cpp (plain)
blob: 4d9c9dd495891b47608503113a4d76d8b31bad92
1#define LOG_TAG "android_out"
2
3#include <stdio.h>
4#include <string.h>
5#include <stdlib.h>
6#include <pthread.h>
7#include <fcntl.h>
8#include <errno.h>
9#include <strings.h>
10#include <sys/ioctl.h>
11#include <cutils/properties.h>
12#include <media/AudioTrack.h>
13#include <utils/Log.h>
14#include "audio_usb_check.h"
15#include "android_out.h"
16#include "aml_audio.h"
17//#include "DDP_media_source.h"
18
19using namespace android;
20
21static AudioTrack *glpTracker = NULL;
22static AudioTrack *glpTracker_raw = NULL;
23
24static sp<AudioTrack> gmpAudioTracker;
25static sp<AudioTrack> gmpAudioTracker_raw;
26
27extern struct circle_buffer android_out_buffer;
28extern struct circle_buffer DDP_out_buffer;
29extern struct circle_buffer DD_out_buffer;
30extern int output_record_enable;
31extern int spdif_audio_type;
32
33int I2S_state = 0;
34static int raw_start_flag = 0;
35static int mute_raw_data_size = 0;
36static audio_format_t last_aformat = AUDIO_FORMAT_AC3;
37//static int last_raw_flag = 0;
38static int RawAudioTrackRelease(void);
39static int RawAudioTrackInit(audio_format_t aformat,int sr);
40static int amsysfs_set_sysfs_int(const char *path, int val) {
41 int fd;
42 int bytes;
43 char bcmd[16];
44 fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0644);
45 if (fd >= 0) {
46 sprintf(bcmd, "%d", val);
47 bytes = write(fd, bcmd, strlen(bcmd));
48 close(fd);
49 return 0;
50 } else {
51 ALOGE("unable to open file %s,err: %s", path, strerror(errno));
52 }
53 return -1;
54}
55
56int amsysfs_get_sysfs_int(const char *path) {
57 int fd;
58 int val = 0;
59 char bcmd[16];
60 fd = open(path, O_RDONLY);
61 if (fd >= 0) {
62 read(fd, bcmd, sizeof(bcmd));
63 val = strtol(bcmd, NULL, 10);
64 close(fd);
65 }else {
66 ALOGE("unable to open file %s,err: %s", path, strerror(errno));
67 }
68 return val;
69}
70static void RawAudioTrackCallback(int event, void* user, void *info) {
71 AudioTrack::Buffer *buffer = static_cast<AudioTrack::Buffer *>(info);
72 int bytes_raw = 0;
73 if (event != AudioTrack::EVENT_MORE_DATA) {
74 ALOGD("%s, audio track envent = %d!\n", __FUNCTION__, event);
75 return;
76 }
77 if (buffer == NULL || buffer->size == 0) {
78 return;
79 }
80 bytes_raw = buffer_read(&DD_out_buffer,(char *) buffer->raw,
81 buffer->size);
82 //ALOGI("raw read got %d\n",bytes_raw);
83 if ( bytes_raw > 0) {
84 buffer->size = bytes_raw;
85 }
86 else
87 buffer->size = 0;
88 if (buffer->size > 0 && mute_raw_data_size < 32*1024) {
89 memset((char *)(buffer->i16),0,buffer->size);
90 mute_raw_data_size += buffer->size;
91 }
92 return;
93}
94static void AudioTrackCallback(int event, void* user, void *info) {
95 AudioTrack::Buffer *buffer = static_cast<AudioTrack::Buffer *>(info);
96
97 if (event != AudioTrack::EVENT_MORE_DATA) {
98 ALOGD("%s, audio track envent = %d!\n", __FUNCTION__, event);
99 return;
100 }
101 if (buffer == NULL || buffer->size == 0) {
102 return;
103 }
104 int bytes = 0;
105
106// code for raw data start
107 audio_format_t aformat = AUDIO_FORMAT_INVALID;
108 int user_raw_enable = amsysfs_get_sysfs_int("/sys/class/audiodsp/digital_raw");
109 //ALOGI("afmat %x,spdif_audio_type %x\n",aformat,spdif_audio_type);
110 int ddp_passth = (user_raw_enable == 2)&&(spdif_audio_type == EAC3);
111 if (user_raw_enable) {
112 if (ddp_passth) {
113 aformat = AUDIO_FORMAT_E_AC3;
114 }
115 else if (spdif_audio_type == AC3 || spdif_audio_type == EAC3 ) {
116 aformat = AUDIO_FORMAT_AC3;
117 }
118 else if (spdif_audio_type == DTS) {
119 aformat = AUDIO_FORMAT_DTS;
120 }
121 else if (spdif_audio_type == LPCM && last_aformat != AUDIO_FORMAT_INVALID) {
122 RawAudioTrackRelease();
123 }
124
125 if (aformat != last_aformat && aformat != AUDIO_FORMAT_INVALID) {
126 ALOGI("raw aformat changed from %x to %x\n",last_aformat,aformat);
127 RawAudioTrackRelease();
128 if (RawAudioTrackInit(aformat,48000/*TODO*/)) {
129 ALOGE("RawAudioTrackInit failed\n");
130 return;
131 }
132 }
133 }
134// raw data end
135 if (GetOutputdevice() == MODEANDROID) { // output PCM output when PCM data in
136//raw data start
137 RawAudioTrackRelease();
138// raw data end
139 bytes = buffer_read(&android_out_buffer, (char *) buffer->raw,
140 buffer->size);
141 if (bytes < 0)
142 buffer->size = 0;
143 } else if (GetOutputdevice() == MODERAW) {
144//raw data start
145 if (user_raw_enable == 0) {
146 RawAudioTrackRelease();
147 }
148// raw date end
149 bytes = buffer_read(&DDP_out_buffer, (char *) buffer->raw,
150 buffer->size);
151 if (bytes < 0)
152 buffer->size = 0;
153 } else {
154 if (output_record_enable == 1) {
155 bytes = buffer_read(&android_out_buffer, (char *) buffer->raw,
156 buffer->size);
157 if (bytes < 0)
158 buffer->size = 0;
159 } else {
160 memset(buffer->i16, 0, buffer->size);
161 }
162 }
163
164 I2S_state += 1;
165 return;
166}
167static int RawAudioTrackRelease(void) {
168 //raw here
169 if (glpTracker_raw != NULL ) {
170 if (raw_start_flag == 1)
171 glpTracker_raw->stop();
172 raw_start_flag = 0;
173 glpTracker_raw = NULL;
174 }
175 if (gmpAudioTracker_raw != NULL ) {
176 gmpAudioTracker_raw.clear();
177 gmpAudioTracker_raw = NULL;
178 ALOGI("RawAudioTrackRelease done\n");
179 }
180
181 // raw end
182#if 0
183 if (last_raw_flag == 2) {
184 ALOGI("change back digital raw to 2 for hdmi pass through\n");
185 amsysfs_set_sysfs_int("/sys/class/audiodsp/digital_raw",2);
186 last_raw_flag = 0;
187 }
188#endif
189 last_aformat = AUDIO_FORMAT_INVALID;
190 return 0;
191}
192static int AudioTrackRelease(void) {
193 if (glpTracker != NULL ) {
194 glpTracker->stop();
195 glpTracker = NULL;
196 }
197
198 if (gmpAudioTracker != NULL ) {
199 gmpAudioTracker.clear();
200 gmpAudioTracker = NULL;
201 }
202
203 return 0;
204}
205static int RawAudioTrackInit(audio_format_t aformat,int sr)
206{
207 status_t Status;
208 int user_raw_enable = amsysfs_get_sysfs_int("/sys/class/audiodsp/digital_raw");
209 int ddp_passth = (user_raw_enable == 2)&&(spdif_audio_type == EAC3);
210 int ret;
211
212 ALOGD("%s, entering...,aformat %x,sr %d\n", __FUNCTION__,aformat,sr);
213 //raw here
214 if (glpTracker_raw != NULL && gmpAudioTracker != NULL) {
215 glpTracker_raw = gmpAudioTracker_raw.get();
216 } else {
217 gmpAudioTracker_raw = new AudioTrack();
218 if (gmpAudioTracker_raw == NULL) {
219 ALOGE("%s, new gmpAudioTracker_raw failed.\n", __FUNCTION__);
220 return -1;
221 }
222 glpTracker_raw = gmpAudioTracker_raw.get();
223 }
224
225 Status = glpTracker_raw->set(AUDIO_STREAM_MUSIC, sr, aformat,
226 AUDIO_CHANNEL_OUT_STEREO, 0,
227 (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_DIRECT
228 | AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO),
229 RawAudioTrackCallback, NULL,
230 0, 0, false, (audio_session_t)0);
231 if (Status != NO_ERROR) {
232 ALOGE("%s, AudioTrack raw set failed.\n", __FUNCTION__);
233 if (gmpAudioTracker_raw != NULL ) {
234 gmpAudioTracker_raw.clear();
235 glpTracker_raw = NULL;
236 }
237 return -1;
238 }
239 Status = glpTracker_raw->initCheck();
240 if (Status != NO_ERROR) {
241 ALOGE("%s, AudioTrack raw initCheck failed.\n", __FUNCTION__);
242 RawAudioTrackRelease();
243 return -1;
244 }
245 //raw end
246#if 0
247 int digital_raw = amsysfs_get_sysfs_int("/sys/class/audiodsp/digital_raw");
248 if (digital_raw == 2) {
249 ALOGI("change digital raw to 2 for spdif pass through\n");
250 amsysfs_set_sysfs_int("/sys/class/audiodsp/digital_raw",1);
251 last_raw_flag = 2;
252 }
253#endif
254 glpTracker_raw->start();
255 ALOGI("RawAudioTrackInit done\n");
256 last_aformat = aformat;
257 mute_raw_data_size = 0;
258 return 0;
259}
260static int AudioTrackInit(void) {
261 status_t Status;
262
263 ALOGD("%s, entering...\n", __FUNCTION__);
264
265 I2S_state = 0;
266
267 if (glpTracker != NULL && gmpAudioTracker != NULL) {
268 glpTracker = gmpAudioTracker.get();
269 } else {
270 gmpAudioTracker = new AudioTrack();
271 if (gmpAudioTracker == NULL) {
272 ALOGE("%s, new AudioTrack failed.\n", __FUNCTION__);
273 return -1;
274 }
275 glpTracker = gmpAudioTracker.get();
276 }
277
278 Status = glpTracker->set(AUDIO_STREAM_MUSIC, 48000, AUDIO_FORMAT_PCM_16_BIT,
279 AUDIO_CHANNEL_OUT_STEREO, 0, AUDIO_OUTPUT_FLAG_NONE,
280 AudioTrackCallback, NULL, 0, 0, false, (audio_session_t)0);
281
282 if (Status != NO_ERROR) {
283 ALOGE("%s, AudioTrack set failed.\n", __FUNCTION__);
284 if (gmpAudioTracker != NULL ) {
285 gmpAudioTracker.clear();
286 glpTracker = NULL;
287 }
288 return -1;
289 }
290
291 Status = glpTracker->initCheck();
292 if (Status != NO_ERROR) {
293 ALOGE("%s, AudioTrack initCheck failed.\n", __FUNCTION__);
294 AudioTrackRelease();
295 return -1;
296 }
297
298 glpTracker->start();
299
300 Status = glpTracker->setVolume(1.0, 1.0);
301 if (Status != NO_ERROR) {
302 ALOGE("%s, AudioTrack setVolume failed.\n", __FUNCTION__);
303 AudioTrackRelease();
304 return -1;
305 }
306 ALOGD("%s, exit...\n", __FUNCTION__);
307 return 0;//RawAudioTrackInit(AUDIO_FORMAT_AC3,48000);
308}
309
310int new_android_audiotrack(void) {
311 return AudioTrackInit();
312}
313
314int release_android_audiotrack(void) {
315 amsysfs_set_sysfs_int("/sys/class/audiodsp/digital_codec",0);
316 return AudioTrackRelease();
317}
318
319int release_raw_audio_track(void) {
320 amsysfs_set_sysfs_int("/sys/class/audiodsp/digital_codec", 0);
321 return RawAudioTrackRelease();
322}
323