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