This repository has been archived by the owner on Sep 30, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[droid] add AESinkAUDIOTRACK but leave disabled
- Loading branch information
Showing
5 changed files
with
603 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,266 @@ | ||
/* | ||
* Copyright (C) 2010-2012 Team XBMC | ||
* http://www.xbmc.org | ||
* | ||
* This Program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation; either version 2, or (at your option) | ||
* any later version. | ||
* | ||
* This Program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with XBMC; see the file COPYING. If not, write to | ||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
* http://www.gnu.org/copyleft/gpl.html | ||
* | ||
*/ | ||
|
||
#include "system.h" | ||
|
||
#include "AESinkAUDIOTRACK.h" | ||
#include "DynamicDll.h" | ||
#include "Utils/AEUtil.h" | ||
#include "Utils/AERingBuffer.h" | ||
#include "utils/log.h" | ||
|
||
#include <stdint.h> | ||
#include <limits.h> | ||
|
||
#include <libaudiotrack_wrapper.h> | ||
|
||
//////////////////////////////////////////////////////////////////////////////////////////// | ||
class DllLibAudioTrackInterface | ||
{ | ||
public: | ||
virtual ~DllLibAudioTrackInterface() {} | ||
|
||
virtual ATW_ctx ATW_create()=0; | ||
virtual void ATW_release(ATW_ctx ctx)=0; | ||
virtual int ATW_get_min_framecount(ATW_ctx ctx, int* frameCount, int sampleRate)=0; | ||
virtual int ATW_set( ATW_ctx ctx, int channelCount, int sampleRate, int frameCount, | ||
ATWCallback cbf, void* cbf_ctx)=0; | ||
virtual void ATW_start(ATW_ctx ctx)=0; | ||
virtual void ATW_stop( ATW_ctx ctx)=0; | ||
virtual int ATW_write(ATW_ctx ctx, const void* buffer, size_t size)=0; | ||
virtual void ATW_flush(ATW_ctx ctx)=0; | ||
virtual void ATW_pause(ATW_ctx ctx)=0; | ||
virtual void ATW_mute( ATW_ctx ctx, int mute)=0; | ||
virtual int ATW_muted(ATW_ctx ctx)=0; | ||
virtual void ATW_set_volume(ATW_ctx ctx, float left, float right)=0; | ||
virtual int ATW_latency(ATW_ctx ctx)=0; | ||
}; | ||
|
||
class DllLibAudioTrack : public DllDynamic, DllLibAudioTrackInterface | ||
{ | ||
DECLARE_DLL_WRAPPER(DllLibAudioTrack, "libaudiotrack_wrapper.so") | ||
|
||
DEFINE_METHOD0(ATW_ctx, ATW_create) | ||
DEFINE_METHOD1(void, ATW_release, (ATW_ctx p1)) | ||
DEFINE_METHOD3(int, ATW_get_min_framecount,(ATW_ctx p1, int *p2, int p3)) | ||
DEFINE_METHOD6(int, ATW_set, (ATW_ctx p1, int p2, int p3, int p4, | ||
ATWCallback p5, void *p6)) | ||
DEFINE_METHOD1(void, ATW_start, (ATW_ctx p1)) | ||
DEFINE_METHOD1(void, ATW_stop, (ATW_ctx p1)) | ||
DEFINE_METHOD3(int, ATW_write, (ATW_ctx p1, const void* p2, size_t p3)) | ||
DEFINE_METHOD1(void, ATW_flush, (ATW_ctx p1)) | ||
DEFINE_METHOD1(void, ATW_pause, (ATW_ctx p1)) | ||
DEFINE_METHOD2(void, ATW_mute, (ATW_ctx p1, int p2)) | ||
DEFINE_METHOD1(int, ATW_muted, (ATW_ctx p1)) | ||
DEFINE_METHOD3(void, ATW_set_volume, (ATW_ctx p1, float p2, float p3)) | ||
DEFINE_METHOD1(int, ATW_latency, (ATW_ctx p1)) | ||
|
||
BEGIN_METHOD_RESOLVE() | ||
RESOLVE_METHOD(ATW_create) | ||
RESOLVE_METHOD(ATW_release) | ||
RESOLVE_METHOD(ATW_get_min_framecount) | ||
RESOLVE_METHOD(ATW_set) | ||
RESOLVE_METHOD(ATW_start) | ||
RESOLVE_METHOD(ATW_stop) | ||
RESOLVE_METHOD(ATW_write) | ||
RESOLVE_METHOD(ATW_flush) | ||
RESOLVE_METHOD(ATW_pause) | ||
RESOLVE_METHOD(ATW_mute) | ||
RESOLVE_METHOD(ATW_muted) | ||
RESOLVE_METHOD(ATW_set_volume) | ||
RESOLVE_METHOD(ATW_latency) | ||
END_METHOD_RESOLVE() | ||
}; | ||
|
||
DllLibAudioTrack *CAESinkAUDIOTRACK::m_dll = NULL; | ||
|
||
CAESinkAUDIOTRACK::CAESinkAUDIOTRACK() | ||
{ | ||
CLog::Log(LOGDEBUG, "CAESinkAUDIOTRACK::CAESinkAUDIOTRACK"); | ||
if (!m_dll) | ||
{ | ||
m_dll = new DllLibAudioTrack; | ||
m_dll->Load(); | ||
} | ||
m_buffer = NULL; | ||
m_ATWrapper = m_dll->ATW_create(); | ||
} | ||
|
||
CAESinkAUDIOTRACK::~CAESinkAUDIOTRACK() | ||
{ | ||
CLog::Log(LOGDEBUG, "CAESinkAUDIOTRACK::~CAESinkAUDIOTRACK"); | ||
//delete m_dll, m_dll = NULL; | ||
} | ||
|
||
bool CAESinkAUDIOTRACK::Initialize(AEAudioFormat &format, std::string &device) | ||
{ | ||
CLog::Log(LOGDEBUG, "CAESinkAUDIOTRACK::Initialize"); | ||
if (!m_ATWrapper) | ||
return false; | ||
|
||
//format.m_sampleRate = (format.m_sampleRate = 44100) ? 44100 : 48000; | ||
format.m_sampleRate = 48000; | ||
format.m_dataFormat = AE_FMT_S16LE; | ||
|
||
CLog::Log(LOGDEBUG, "CAESinkAUDIOTRACK::Initialize2"); | ||
int min_frames; | ||
m_dll->ATW_get_min_framecount(m_ATWrapper, &min_frames, format.m_sampleRate); | ||
|
||
CLog::Log(LOGDEBUG, "CAESinkAUDIOTRACK::Initialize3, min_frames(%d)", min_frames); | ||
format.m_frames = min_frames; | ||
format.m_frameSamples = format.m_channelLayout.Count(); | ||
format.m_frameSize = format.m_frameSamples * (CAEUtil::DataFormatToBits(format.m_dataFormat) >> 3); | ||
m_dll->ATW_set(m_ATWrapper, format.m_frameSamples, format.m_sampleRate, format.m_frames, | ||
AudioTrackCallback, this); | ||
|
||
m_format = format; | ||
m_started = false; | ||
m_draining = false; | ||
m_buffer = new AERingBuffer(m_format.m_frameSize * m_format.m_sampleRate); | ||
|
||
m_dll->ATW_start(m_ATWrapper), m_started = true; | ||
|
||
return true; | ||
} | ||
|
||
void CAESinkAUDIOTRACK::Deinitialize() | ||
{ | ||
CLog::Log(LOGDEBUG, "CAESinkAUDIOTRACK::Deinitialize"); | ||
m_dll->ATW_stop(m_ATWrapper); | ||
m_dll->ATW_release(m_ATWrapper), m_ATWrapper = NULL; | ||
m_draining = false; | ||
delete m_buffer, m_buffer = NULL; | ||
} | ||
|
||
bool CAESinkAUDIOTRACK::IsCompatible(const AEAudioFormat format, const std::string device) | ||
{ | ||
CLog::Log(LOGDEBUG, "CAESinkAUDIOTRACK::IsCompatible"); | ||
return ((m_format.m_sampleRate == format.m_sampleRate) && | ||
(m_format.m_dataFormat == format.m_dataFormat) && | ||
(m_format.m_channelLayout == format.m_channelLayout)); | ||
} | ||
|
||
double CAESinkAUDIOTRACK::GetDelay() | ||
{ | ||
// DVDAudio.cpp says, returns the time it takes to play a packet if we add one at this time | ||
// return the delay in seconds | ||
float seconds_to_empty = (double)m_buffer->GetReadSize() / (double)m_format.m_sampleRate; | ||
float latency_sec = (double)m_dll->ATW_latency(m_ATWrapper) / 1000.0; | ||
//CLog::Log(LOGDEBUG, "CAESinkAUDIOTRACK::GetDelay, latency_sec(%f), buffer_sec(%f)", | ||
// latency_sec, buffer_sec); | ||
return seconds_to_empty + latency_sec; | ||
} | ||
|
||
double CAESinkAUDIOTRACK::GetCacheTime() | ||
{ | ||
// DVDAudio.cpp says, returns total amount of data cached in audio output at this time | ||
float seconds_to_full = (double)m_buffer->GetWriteSize() / (double)m_format.m_sampleRate; | ||
CLog::Log(LOGDEBUG, "CAESinkAUDIOTRACK::GetCacheTime, seconds_to_full(%f)", seconds_to_full); | ||
return seconds_to_full; | ||
} | ||
|
||
double CAESinkAUDIOTRACK::GetCacheTotal() | ||
{ | ||
float buffer_totalsec = (double)m_buffer->GetMaxSize() / (double)m_format.m_sampleRate; | ||
CLog::Log(LOGDEBUG, "CAESinkAUDIOTRACK::GetCacheTotal, buffer_sec(%f)", buffer_totalsec); | ||
return buffer_totalsec; | ||
} | ||
|
||
unsigned int CAESinkAUDIOTRACK::AddPackets(uint8_t *data, unsigned int frames) | ||
{ | ||
//CLog::Log(LOGDEBUG, "CAESinkAUDIOTRACK::AddPackets, frames(%d)", frames); | ||
unsigned int room = m_buffer->GetWriteSize(); | ||
unsigned int addbytes = frames * m_format.m_frameSize; | ||
unsigned int bytes_per_second = m_format.m_frameSize * m_format.m_sampleRate; | ||
|
||
if (m_draining) | ||
return frames; | ||
|
||
if (!m_started) | ||
m_dll->ATW_start(m_ATWrapper), m_started = true; | ||
|
||
unsigned int total_ms_sleep = 0; | ||
while (!m_draining && addbytes > room && total_ms_sleep < 200) | ||
{ | ||
// we got deleted | ||
if (!m_buffer || m_draining ) | ||
return 0; | ||
|
||
unsigned int ms_sleep_time = (1000 * room) / bytes_per_second; | ||
if (ms_sleep_time == 0) | ||
ms_sleep_time++; | ||
|
||
// sleep until we have space (estimated) or 1ms min | ||
Sleep(ms_sleep_time); | ||
total_ms_sleep += ms_sleep_time; | ||
|
||
room = m_buffer->GetWriteSize(); | ||
} | ||
|
||
if (addbytes > room) | ||
frames = 0; | ||
else | ||
m_buffer->Write(data, addbytes); | ||
|
||
Sleep(frames/m_format.m_sampleRate); | ||
return frames; | ||
} | ||
|
||
void CAESinkAUDIOTRACK::Drain() | ||
{ | ||
CLog::Log(LOGDEBUG, "CAESinkAUDIOTRACK::Drain"); | ||
m_started = false; | ||
m_draining = true; | ||
m_dll->ATW_stop( m_ATWrapper); | ||
m_dll->ATW_flush(m_ATWrapper); | ||
//m_dll->ATW_start(m_ATWrapper); | ||
} | ||
|
||
void CAESinkAUDIOTRACK::EnumerateDevicesEx(AEDeviceInfoList &list) | ||
{ | ||
CLog::Log(LOGDEBUG, "CAESinkAUDIOTRACK::EnumerateDevicesEx, entry"); | ||
CAEDeviceInfo info; | ||
|
||
info.m_channels.Reset(); | ||
info.m_dataFormats.clear(); | ||
info.m_sampleRates.clear(); | ||
|
||
info.m_deviceType = AE_DEVTYPE_PCM; | ||
info.m_deviceName = "AudioTrack"; | ||
info.m_displayName = "android"; | ||
info.m_displayNameExtra = "default display"; | ||
info.m_channels += AE_CH_FL; | ||
info.m_channels += AE_CH_FR; | ||
//info.m_sampleRates.push_back(44100); | ||
info.m_sampleRates.push_back(48000); | ||
info.m_dataFormats.push_back(AE_FMT_S16LE); | ||
|
||
list.push_back(info); | ||
CLog::Log(LOGDEBUG, "CAESinkAUDIOTRACK::EnumerateDevicesEx, exit"); | ||
} | ||
|
||
int CAESinkAUDIOTRACK::AudioTrackCallback(void *ctx, void *buffer, size_t size) | ||
{ | ||
CAESinkAUDIOTRACK *at_ctx = (CAESinkAUDIOTRACK*)ctx; | ||
unsigned int readsize = std::min(at_ctx->m_buffer->GetReadSize(), size); | ||
at_ctx->m_buffer->Read((unsigned char*)buffer, readsize); | ||
return readsize; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#pragma once | ||
/* | ||
* Copyright (C) 2010-2012 Team XBMC | ||
* http://www.xbmc.org | ||
* | ||
* This Program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation; either version 2, or (at your option) | ||
* any later version. | ||
* | ||
* This Program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with XBMC; see the file COPYING. If not, write to | ||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
* http://www.gnu.org/copyleft/gpl.html | ||
* | ||
*/ | ||
|
||
#include "system.h" | ||
#ifdef TARGET_ANDROID | ||
|
||
#include "Interfaces/AESink.h" | ||
#include "Utils/AEDeviceInfo.h" | ||
#include <stdint.h> | ||
|
||
typedef void* ATW_ctx; | ||
class AERingBuffer; | ||
class DllLibAudioTrack; | ||
|
||
class CAESinkAUDIOTRACK : public IAESink | ||
{ | ||
public: | ||
virtual const char *GetName() { return "AUDIOTRACK"; } | ||
|
||
CAESinkAUDIOTRACK(); | ||
virtual ~CAESinkAUDIOTRACK(); | ||
|
||
virtual bool Initialize(AEAudioFormat &format, std::string &device); | ||
virtual void Deinitialize(); | ||
virtual bool IsCompatible(const AEAudioFormat format, const std::string device); | ||
|
||
virtual double GetDelay (); | ||
virtual double GetCacheTime (); | ||
virtual double GetCacheTotal (); | ||
virtual unsigned int AddPackets (uint8_t *data, unsigned int frames); | ||
virtual void Drain (); | ||
|
||
static void EnumerateDevicesEx(AEDeviceInfoList &list); | ||
|
||
static int AudioTrackCallback(void *ctx, void *buffer, size_t size); | ||
private: | ||
static DllLibAudioTrack *m_dll; | ||
AEAudioFormat m_format; | ||
ATW_ctx m_ATWrapper; | ||
AERingBuffer *m_buffer; | ||
bool m_started; | ||
bool m_draining; | ||
|
||
}; | ||
|
||
#endif |
Oops, something went wrong.