2 * Copyright (C) 2010-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
21 #include "AESinkAUDIOTRACK.h"
22 #include "Utils/AEUtil.h"
23 #include "Utils/AERingBuffer.h"
24 #include "android/activity/XBMCApp.h"
25 #include "settings/Settings.h"
26 #if defined(HAS_LIBAMCODEC)
27 #include "utils/AMLUtils.h"
29 #include "utils/log.h"
33 #if defined(__ARM_NEON__)
35 #include "utils/CPUInfo.h"
36 #include "android/jni/JNIThreading.h"
38 // LGPLv2 from PulseAudio
39 // float values from AE are pre-clamped so we do not need to clamp again here
40 static void pa_sconv_s16le_from_f32ne_neon(unsigned n, const float32_t *a, int16_t *b)
44 const float32x4_t half4 = vdupq_n_f32(0.5f);
45 const float32x4_t scale4 = vdupq_n_f32(32767.0f);
46 const uint32x4_t mask4 = vdupq_n_u32(0x80000000);
48 for (i = 0; i < (n & ~3); i += 4)
50 const float32x4_t v4 = vmulq_f32(vld1q_f32(&a[i]), scale4);
51 const float32x4_t w4 = vreinterpretq_f32_u32(
52 vorrq_u32(vandq_u32(vreinterpretq_u32_f32(v4), mask4), vreinterpretq_u32_f32(half4)));
53 vst1_s16(&b[i], vmovn_s32(vcvtq_s32_f32(vaddq_f32(v4, w4))));
57 b[i] = (int16_t) lrintf(a[i] * 0x7FFF);
61 static jint GetStaticIntField(JNIEnv *jenv, std::string class_name, std::string field_name)
63 class_name.insert(0, "android/media/");
64 jclass cls = jenv->FindClass(class_name.c_str());
65 jfieldID field = jenv->GetStaticFieldID(cls, field_name.c_str(), "I");
66 jint int_field = jenv->GetStaticIntField(cls, field);
67 jenv->DeleteLocalRef(cls);
71 CAEDeviceInfo CAESinkAUDIOTRACK::m_info;
72 ////////////////////////////////////////////////////////////////////////////////////////////
73 CAESinkAUDIOTRACK::CAESinkAUDIOTRACK()
74 : CThread("AudioTrack")
78 m_volume_changed = false;
81 m_sinkbuffer_sec = 0.0;
82 m_sinkbuffer_sec_per_byte = 0.0;
84 m_audiotrackbuffer_sec = 0.0;
85 m_audiotrack_empty_sec = 0.0;
86 m_audiotrack_empty_sec_tweaks = 0.0;
87 #if defined(HAS_LIBAMCODEC)
89 m_audiotrack_empty_sec_tweaks = 0.250;
94 CAESinkAUDIOTRACK::~CAESinkAUDIOTRACK()
98 bool CAESinkAUDIOTRACK::Initialize(AEAudioFormat &format, std::string &device)
102 if (AE_IS_RAW(m_format.m_dataFormat))
103 m_passthrough = true;
105 m_passthrough = false;
107 #if defined(HAS_LIBAMCODEC)
108 if (CSettings::Get().GetBool("videoplayer.useamcodec"))
109 aml_set_audio_passthrough(m_passthrough);
112 // default to 44100, all android devices support it.
113 // then check if we can support the requested rate.
114 unsigned int sampleRate = 44100;
115 for (size_t i = 0; i < m_info.m_sampleRates.size(); i++)
117 if (m_format.m_sampleRate == m_info.m_sampleRates[i])
119 sampleRate = m_format.m_sampleRate;
123 m_format.m_sampleRate = sampleRate;
125 // default to AE_FMT_S16LE,
126 // then check if we can support the requested format.
127 AEDataFormat dataFormat = AE_FMT_S16LE;
128 for (size_t i = 0; i < m_info.m_dataFormats.size(); i++)
130 if (m_format.m_dataFormat == m_info.m_dataFormats[i])
132 dataFormat = m_format.m_dataFormat;
136 m_format.m_dataFormat = dataFormat;
138 m_format.m_channelLayout = m_info.m_channels;
139 m_format.m_frameSize = m_format.m_channelLayout.Count() * (CAEUtil::DataFormatToBits(m_format.m_dataFormat) >> 3);
142 m_volume_changed = false;
143 // launch the process thread and wait for the
144 // AutoTrack jni object to get created and setup.
148 if(!m_inited.WaitMSec(100))
150 while(!m_inited.WaitMSec(1))
154 // m_min_frames is volatile and has been setup by Process()
155 m_format.m_frames = m_min_frames;
156 m_format.m_frameSamples = m_format.m_frames * m_format.m_channelLayout.Count();
162 void CAESinkAUDIOTRACK::Deinitialize()
164 // force m_bStop and set m_wake, if might be sleeping.
168 delete m_sinkbuffer, m_sinkbuffer = NULL;
170 _aligned_free(m_alignedS16), m_alignedS16 = NULL;
173 bool CAESinkAUDIOTRACK::IsCompatible(const AEAudioFormat &format, const std::string &device)
175 return ((m_format.m_sampleRate == format.m_sampleRate) &&
176 (m_format.m_dataFormat == format.m_dataFormat) &&
177 (m_format.m_channelLayout == format.m_channelLayout));
180 double CAESinkAUDIOTRACK::GetDelay()
182 // this includes any latency due to AudioTrack buffer,
183 // AudioMixer (if any) and audio hardware driver.
185 double sinkbuffer_seconds_to_empty = m_sinkbuffer_sec_per_byte * (double)m_sinkbuffer->GetReadSize();
186 sinkbuffer_seconds_to_empty += m_audiotrack_empty_sec;
187 if (sinkbuffer_seconds_to_empty > 0.0)
188 sinkbuffer_seconds_to_empty += m_audiotrack_empty_sec_tweaks;
189 return sinkbuffer_seconds_to_empty;
192 double CAESinkAUDIOTRACK::GetCacheTime()
194 // returns the time in seconds that it will take
195 // to underrun the buffer if no sample is added.
197 double sinkbuffer_seconds_to_empty = m_sinkbuffer_sec_per_byte * (double)m_sinkbuffer->GetReadSize();
198 sinkbuffer_seconds_to_empty += m_audiotrack_empty_sec;
199 if (sinkbuffer_seconds_to_empty > 0.0)
200 sinkbuffer_seconds_to_empty += m_audiotrack_empty_sec_tweaks;
201 return sinkbuffer_seconds_to_empty;
204 double CAESinkAUDIOTRACK::GetCacheTotal()
206 // total amount that the audio sink can buffer in units of seconds
208 return m_sinkbuffer_sec + m_audiotrackbuffer_sec;
211 unsigned int CAESinkAUDIOTRACK::AddPackets(uint8_t *data, unsigned int frames, bool hasAudio, bool blocking)
213 // write as many frames of audio as we can fit into our internal buffer.
215 // our internal sink buffer is always AE_FMT_S16
216 unsigned int write_frames = m_sinkbuffer->GetWriteSize() / m_sink_frameSize;
217 if (write_frames > frames)
218 write_frames = frames;
220 if (hasAudio && write_frames)
222 switch(m_format.m_dataFormat)
225 m_sinkbuffer->Write(data, write_frames * m_sink_frameSize);
228 #if defined(__ARM_NEON__)
231 m_alignedS16 = (int16_t*)_aligned_malloc(m_format.m_frames * m_sink_frameSize, 16);
232 // neon convert AE_FMT_S16LE to AE_FMT_FLOAT
233 pa_sconv_s16le_from_f32ne_neon(write_frames * m_format.m_channelLayout.Count(), (const float32_t *)data, m_alignedS16);
234 m_sinkbuffer->Write((unsigned char*)m_alignedS16, write_frames * m_sink_frameSize);
242 // AddPackets runs under a non-idled AE thread we must block or sleep.
243 // Trying to calc the optimal sleep is tricky so just a minimal sleep.
247 return hasAudio ? write_frames:frames;
250 void CAESinkAUDIOTRACK::Drain()
252 CLog::Log(LOGDEBUG, "CAESinkAUDIOTRACK::Drain");
253 CSingleLock lock(m_drain_lock);
258 bool CAESinkAUDIOTRACK::HasVolume()
263 void CAESinkAUDIOTRACK::SetVolume(float scale)
265 // Android uses fixed steps, reverse scale back to percent
266 float gain = CAEUtil::ScaleToGain(scale);
267 m_volume = CAEUtil::GainToPercent(gain);
270 CSingleLock lock(m_volume_lock);
271 m_volume_changed = true;
275 void CAESinkAUDIOTRACK::EnumerateDevicesEx(AEDeviceInfoList &list, bool force)
277 m_info.m_channels.Reset();
278 m_info.m_dataFormats.clear();
279 m_info.m_sampleRates.clear();
281 m_info.m_deviceType = AE_DEVTYPE_PCM;
282 m_info.m_deviceName = "AudioTrack";
283 m_info.m_displayName = "android";
284 m_info.m_displayNameExtra = "audiotrack";
285 m_info.m_channels += AE_CH_FL;
286 m_info.m_channels += AE_CH_FR;
287 m_info.m_sampleRates.push_back(44100);
288 m_info.m_sampleRates.push_back(48000);
289 m_info.m_dataFormats.push_back(AE_FMT_S16LE);
290 #if defined(__ARM_NEON__)
291 if (g_cpuInfo.GetCPUFeatures() & CPU_FEATURE_NEON)
292 m_info.m_dataFormats.push_back(AE_FMT_FLOAT);
295 list.push_back(m_info);
298 void CAESinkAUDIOTRACK::Process()
300 CLog::Log(LOGDEBUG, "CAESinkAUDIOTRACK::Process");
302 JNIEnv *jenv = xbmc_jnienv();
304 jclass jcAudioTrack = jenv->FindClass("android/media/AudioTrack");
306 jmethodID jmInit = jenv->GetMethodID(jcAudioTrack, "<init>", "(IIIIII)V");
307 jmethodID jmPlay = jenv->GetMethodID(jcAudioTrack, "play", "()V");
308 jmethodID jmStop = jenv->GetMethodID(jcAudioTrack, "stop", "()V");
309 jmethodID jmFlush = jenv->GetMethodID(jcAudioTrack, "flush", "()V");
310 jmethodID jmRelease = jenv->GetMethodID(jcAudioTrack, "release", "()V");
311 jmethodID jmWrite = jenv->GetMethodID(jcAudioTrack, "write", "([BII)I");
312 jmethodID jmPlayState = jenv->GetMethodID(jcAudioTrack, "getPlayState", "()I");
313 jmethodID jmPlayHeadPosition = jenv->GetMethodID(jcAudioTrack, "getPlaybackHeadPosition", "()I");
314 jmethodID jmGetMinBufferSize = jenv->GetStaticMethodID(jcAudioTrack, "getMinBufferSize", "(III)I");
316 jint audioFormat = GetStaticIntField(jenv, "AudioFormat", "ENCODING_PCM_16BIT");
317 jint channelConfig = GetStaticIntField(jenv, "AudioFormat", "CHANNEL_OUT_STEREO");
319 jint min_buffer_size = jenv->CallStaticIntMethod(jcAudioTrack, jmGetMinBufferSize,
320 m_format.m_sampleRate, channelConfig, audioFormat);
322 m_sink_frameSize = m_format.m_channelLayout.Count() * CAEUtil::DataFormatToBits(AE_FMT_S16LE) >> 3;
323 m_min_frames = min_buffer_size / m_sink_frameSize;
325 m_audiotrackbuffer_sec = (double)m_min_frames / (double)m_format.m_sampleRate;
326 m_audiotrack_empty_sec = 0.0;
328 // setup a 1/4 second internal sink lockless ring buffer
329 m_sinkbuffer = new AERingBuffer(m_sink_frameSize * m_format.m_sampleRate / 4);
330 m_sinkbuffer_sec_per_byte = 1.0 / (double)(m_sink_frameSize * m_format.m_sampleRate);
331 m_sinkbuffer_sec = (double)m_sinkbuffer_sec_per_byte * m_sinkbuffer->GetMaxSize();
333 jobject joAudioTrack = jenv->NewObject(jcAudioTrack, jmInit,
334 GetStaticIntField(jenv, "AudioManager", "STREAM_MUSIC"),
335 m_format.m_sampleRate,
339 GetStaticIntField(jenv, "AudioTrack", "MODE_STREAM"));
341 // Set the initial volume
345 CXBMCApp::SetSystemVolume(jenv, volume);
347 // The AudioTrack object has been created and waiting to play,
349 // yield to give other threads a chance to do some work.
352 // cache the playing int value.
353 jint playing = GetStaticIntField(jenv, "AudioTrack", "PLAYSTATE_PLAYING");
355 // create a java byte buffer for writing pcm data to AudioTrack.
356 jarray jbuffer = jenv->NewByteArray(min_buffer_size);
358 int64_t frames_written = 0;
359 int64_t frame_position = 0;
363 if (m_volume_changed && !m_passthrough)
365 // check of volume changes and make them,
366 // do it here to keep jni calls local to this thread.
367 CXBMCApp::SetSystemVolume(jenv, m_volume);
368 CSingleLock lock(m_volume_lock);
369 m_volume_changed = false;
373 unsigned char byte_drain[1024];
374 unsigned int byte_drain_size = m_sinkbuffer->GetReadSize();
375 if (byte_drain_size > 1024)
376 byte_drain_size = 1024;
377 while (byte_drain_size)
379 m_sinkbuffer->Read(byte_drain, byte_drain_size);
380 byte_drain_size = m_sinkbuffer->GetReadSize();
381 if (byte_drain_size > 1024)
382 byte_drain_size = 1024;
384 jenv->CallVoidMethod(joAudioTrack, jmStop);
385 jenv->CallVoidMethod(joAudioTrack, jmFlush);
386 CSingleLock lock(m_drain_lock);
390 unsigned int read_bytes = m_sinkbuffer->GetReadSize();
391 if (read_bytes > (unsigned int)min_buffer_size)
392 read_bytes = min_buffer_size;
396 // android will auto pause the playstate when it senses idle,
397 // check it and set playing if it does this. Do this before
398 // writing into its buffer.
399 if (jenv->CallIntMethod(joAudioTrack, jmPlayState) != playing)
400 jenv->CallVoidMethod( joAudioTrack, jmPlay);
402 // Write a buffer of audio data to Java AudioTrack.
403 // Warning, no other JNI function can be called after
404 // GetPrimitiveArrayCritical until ReleasePrimitiveArrayCritical.
405 void *pBuffer = jenv->GetPrimitiveArrayCritical(jbuffer, NULL);
408 m_sinkbuffer->Read((unsigned char*)pBuffer, read_bytes);
409 jenv->ReleasePrimitiveArrayCritical(jbuffer, pBuffer, 0);
410 // jmWrite is blocking and returns when the data has been transferred
411 // from the Java layer and queued for playback.
412 jenv->CallIntMethod(joAudioTrack, jmWrite, jbuffer, 0, read_bytes);
415 // calc the number of seconds until audiotrack buffer is empty.
416 frame_position = jenv->CallIntMethod(joAudioTrack, jmPlayHeadPosition);
417 if (frame_position == 0)
419 frames_written += read_bytes / m_sink_frameSize;
420 m_audiotrack_empty_sec = (double)(frames_written - frame_position) / m_format.m_sampleRate;
421 // some times, we can get frame_position
422 // ahead of frames_written, not a clue why. clamp it.
423 if (m_audiotrack_empty_sec < 0.0f)
424 m_audiotrack_empty_sec = 0.0f;
426 if (m_sinkbuffer->GetReadSize() == 0)
428 // the sink buffer is empty, stop playback.
429 // Audiotrack will playout any written contents.
430 jenv->CallVoidMethod(joAudioTrack, jmStop);
431 // sleep this audio thread, we will get woken when we have audio data.
432 m_wake.WaitMSec(250);
436 jenv->CallVoidMethod(joAudioTrack, jmStop);
437 jenv->CallVoidMethod(joAudioTrack, jmFlush);
438 jenv->CallVoidMethod(joAudioTrack, jmRelease);
440 // might toss an exception on jmRelease so catch it.
441 jthrowable exception = jenv->ExceptionOccurred();
444 jenv->ExceptionDescribe();
445 jenv->ExceptionClear();
448 jenv->DeleteLocalRef(jbuffer);
449 jenv->DeleteLocalRef(joAudioTrack);
450 jenv->DeleteLocalRef(jcAudioTrack);