aboutsummaryrefslogtreecommitdiff
path: root/xbmc/cores/AudioEngine/Engines/CoreAudioAEHALIOS.h
blob: 3ae6e8ff9c1e57f37968e34af20039cdd193b4e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#pragma once
/*
 *      Copyright (C) 2011-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
 *
 */

#ifdef __arm__

#include "ICoreAudioAEHAL.h"

#include <AudioUnit/AudioUnit.h>
#include <AudioUnit/AudioUnitProperties.h>
#include <AudioToolbox/AudioToolbox.h>
#include <AudioToolbox/AudioServices.h>
#include <CoreAudio/CoreAudioTypes.h>
#include <AudioToolbox/AUGraph.h>
#include <list>
#include <vector>

#include "utils/StdString.h"

#include "CoreAudioAEHAL.h"

#define kOutputBus 0
#define kInputBus 1
#define MAX_CONNECTION_LIMIT  8
#define INVALID_BUS -1

// Forward declarations
class CCoreAudioAE;
class CIOSCoreAudioConverter;

typedef std::list<AudioComponentInstance> IOSCoreAudioDeviceList;

// There is only one AudioSystemObject instance system-side.
// Therefore, all CIOSCoreAudioHardware methods are static
class CIOSCoreAudioHardware
{
public:
  static AudioComponentInstance FindAudioDevice(std::string deviceName);
  static AudioComponentInstance GetDefaultOutputDevice();
  static UInt32 GetOutputDevices(IOSCoreAudioDeviceList* pList);
};

class CCoreAudioUnit
{
public:
  CCoreAudioUnit();
  virtual ~CCoreAudioUnit();
  
  virtual bool Open(AUGraph audioGraph, AudioComponentDescription desc);
  virtual bool Open(AUGraph audioGraph, OSType type, OSType subType, OSType manufacturer);
  virtual void Close();
  virtual bool SetInputSource(ICoreAudioSource* pSource);
  virtual bool IsInitialized() {return m_Initialized;}
  virtual bool GetFormat(AudioStreamBasicDescription* pDesc, AudioUnitScope scope, AudioUnitElement bus);    
  virtual bool SetFormat(AudioStreamBasicDescription* pDesc, AudioUnitScope scope, AudioUnitElement bus);
  virtual bool SetMaxFramesPerSlice(UInt32 maxFrames);
  virtual void GetFormatDesc(AEAudioFormat format, AudioStreamBasicDescription *streamDesc);
  virtual float GetLatency();
  virtual bool SetSampleRate(Float64 sampleRate, AudioUnitScope scope, AudioUnitElement bus);
  virtual bool Stop();
  virtual bool Start();
  virtual AudioUnit   GetUnit  (){return m_audioUnit;}
  virtual AUGraph     GetGraph (){return m_audioGraph;}
  virtual AUNode      GetNode  (){return m_audioNode;}
  virtual int         GetBus   (){return m_busNumber;}
  virtual void        SetBus   (int busNumber){m_busNumber = busNumber;}
protected:
  bool SetRenderProc();
  bool RemoveRenderProc();
  static OSStatus RenderCallback(void *inRefCon, 
                                 AudioUnitRenderActionFlags *ioActionFlags, 
                                 const AudioTimeStamp *inTimeStamp, 
                                 UInt32 inBusNumber, 
                                 UInt32 inNumberFrames, 
                                 AudioBufferList *ioData);
  ICoreAudioSource*   m_pSource;
  AudioUnit           m_audioUnit;
  AUNode              m_audioNode;
  AUGraph             m_audioGraph;
  bool                m_Initialized;
  AURenderCallback    m_renderProc;
  int                 m_busNumber;
};

class CAUOutputDevice : public CCoreAudioUnit
{
public:
  CAUOutputDevice();
  virtual ~CAUOutputDevice();
  UInt32 GetBufferFrameSize();
  
  /*
  Float32 GetCurrentVolume();
  bool SetCurrentVolume(Float32 vol);
  */
  bool EnableInputOuput();
};

class CAUMultiChannelMixer : public CAUOutputDevice
{
public:
  CAUMultiChannelMixer();
  virtual ~CAUMultiChannelMixer();
  
  UInt32 GetInputBusCount();
  bool SetInputBusFormat(UInt32 busCount, AudioStreamBasicDescription *pFormat);
  bool SetInputBusCount(UInt32 busCount);
  UInt32 GetOutputBusCount();
  bool SetOutputBusCount(UInt32 busCount);
    
  Float32 GetCurrentVolume();
  bool SetCurrentVolume(Float32 vol);
};

class CCoreAudioGraph
{
private:
  AUGraph           m_audioGraph;
  
  CAUOutputDevice  *m_audioUnit;
  CAUMultiChannelMixer   *m_mixerUnit;
  CAUOutputDevice  *m_inputUnit;
  
  int m_reservedBusNumber[MAX_CONNECTION_LIMIT];
  bool              m_initialized;
  bool              m_allowMixing;
  
  typedef std::list<CAUOutputDevice*> AUUnitList;
  AUUnitList        m_auUnitList;
  
public:
  CCoreAudioGraph();
  ~CCoreAudioGraph();
  
  bool Open(ICoreAudioSource *pSource, AEAudioFormat &format, bool allowMixing);
  bool Close();
  bool Start();
  bool Stop();
  bool SetInputSource(ICoreAudioSource* pSource);
  bool SetCurrentVolume(Float32 vol);
  CAUOutputDevice *DestroyUnit(CAUOutputDevice *outputUnit);
  CAUOutputDevice *CreateUnit(AEAudioFormat &format);
  int GetFreeBus();
  void ReleaseBus(int busNumber);
  bool IsBusFree(int busNumber);
  int GetMixerChannelOffset(int busNumber);
  void ShowGraph();
  float GetLatency();
};

class CCoreAudioAEHALIOS : public ICoreAudioAEHAL
{
protected:
  CCoreAudioGraph  *m_audioGraph;
  bool              m_Initialized;
  bool              m_Passthrough;
  AEAudioFormat     m_initformat;
  bool              m_allowMixing;
  bool              m_encoded;
  AEDataFormat      m_rawDataFormat;
public:
  unsigned int      m_NumLatencyFrames;
  unsigned int      m_OutputBufferIndex;
  CCoreAudioAE     *m_ae;
  
  CCoreAudioAEHALIOS();
  virtual ~CCoreAudioAEHALIOS();
  
  virtual bool   InitializePCM(ICoreAudioSource *pSource, AEAudioFormat &format, bool allowMixing);
  virtual bool   InitializePCMEncoded(ICoreAudioSource *pSource, AEAudioFormat &format);
  virtual bool   Initialize(ICoreAudioSource *ae, bool passThrough, AEAudioFormat &format, AEDataFormat rawDataFormat, std::string &device);
  virtual void   Deinitialize();
  virtual void   EnumerateOutputDevices(AEDeviceList &devices, bool passthrough);
  virtual void   SetDirectInput(ICoreAudioSource *pSource, AEAudioFormat &format);
  virtual void   Stop();
  virtual bool   Start();
  virtual double GetDelay();
  virtual void   SetVolume(float volume);
  virtual unsigned int GetBufferIndex();
  virtual CAUOutputDevice *DestroyUnit(CAUOutputDevice *outputUnit);
  virtual CAUOutputDevice *CreateUnit(ICoreAudioSource *pSource, AEAudioFormat &format);
  virtual bool  AllowMixing() { return m_allowMixing; }
};

#endif