sipxmedialib  Version 3.3
MpCoreAudioHardware.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2009 SIPez LLC.
3 // Licensed to SIPfoundry under a Contributor Agreement.
4 //
5 // Copyright (C) 2009 SIPfoundry Inc.
6 // Licensed by SIPfoundry under the LGPL license.
7 //
8 // $$
10 
11 // Author: Sergey Kostanbaev <Sergey DOT Kostanbaev AT sipez DOT com>
12 
13 #ifndef _AudioHardware_h_
14 #define _AudioHardware_h_
15 
16 // SYSTEM INCLUDES
17 #include <stdlib.h>
18 #include <math.h>
19 #include <CoreAudio/AudioHardware.h>
20 #include <AudioUnit/AudioUnit.h>
21 #include <CoreServices/CoreServices.h>
22 #include <AudioToolbox/DefaultAudioOutput.h>
23 #include <AudioToolbox/AudioConverter.h>
24 
25 // APPLICATION INCLUDES
26 // DEFINES
27 // MACROS
28 // EXTERNAL FUNCTIONS
29 // EXTERNAL VARIABLES
30 // CONSTANTS
31 // STRUCTS
32 // TYPEDEFS
33 // FORWARD DECLARATIONS
34 
35 //#define DUMP_DEVICE
36 
41 {
42 /* //////////////////////////// PUBLIC //////////////////////////////////// */
43 public:
44 
45  CoreAudioHardware(AudioDeviceID devid, bool isInput)
46  : mDevId(devid)
47  , mIsInput(isInput)
48  {
49 #ifdef DUMP_DEVICE
50  if (devid != kAudioDeviceUnknown)
51  {
52  double list[32];
53  int i = getAvailableSampleRates(list, 32), j;
54  for (j = 0; j < i; j++)
55  printf("dev 0x%x: %g\n", (unsigned)mDevId, list[j]);
56  }
57 #endif
58  }
59 
60  AudioDeviceID getAudioDeviceID() const
61  {
62  return mDevId;
63  }
64 
65  bool IsInput() const
66  {
67  return mIsInput;
68  }
69 
70  bool IsValid() const
71  {
72  return mDevId != kAudioDeviceUnknown;
73  }
74 
75 
77  {
78  return CoreAudioHardware(kAudioDeviceUnknown, false);
79  }
80 
82  {
83  AudioDeviceID dev_id = kAudioDeviceUnknown;
84  UInt32 parm_size = sizeof(dev_id);
85  OSStatus st = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &parm_size, &dev_id);
86  if (st != kAudioHardwareNoError)
87  printf("AudioDeviceGetProperty->kAudioHardwarePropertyDefaultOutputDevice failed: %d\n", (int)st);
88 
89  return CoreAudioHardware(dev_id, false);
90  }
91 
93  {
94  AudioDeviceID dev_id = kAudioDeviceUnknown;
95  UInt32 parm_size = sizeof(dev_id);
96  OSStatus st = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &parm_size, &dev_id);
97  if (st != kAudioHardwareNoError)
98  printf("AudioDeviceGetProperty->kAudioHardwarePropertyDefaultInputDevice failed: %d\n", (int)st);
99 
100  return CoreAudioHardware(dev_id, true);
101  }
102 
103  double getActualSampleRate() const
104  {
105  Float64 actual = 0;
106  UInt32 sz = sizeof(actual);
107  OSStatus st = AudioDeviceGetProperty(mDevId, 0, mIsInput, kAudioDevicePropertyActualSampleRate, &sz, &actual);
108  if (st != kAudioHardwareNoError)
109  printf("[0x%x]AudioDeviceGetProperty->kAudioDevicePropertyActualSampleRate failed: %d\n", (unsigned)mDevId, (int)st);
110 
111  return actual;
112  }
113 
114  int getLatency() const
115  {
116  UInt32 actual = 0;
117  UInt32 sz = sizeof(actual);
118  OSStatus st = AudioDeviceGetProperty(mDevId, 0, mIsInput, kAudioDevicePropertyLatency, &sz, &actual);
119  if (st != kAudioHardwareNoError)
120  printf("[0x%x]AudioDeviceGetProperty->kAudioDevicePropertyLatency failed: %d\n", (unsigned)mDevId, (int)st);
121 
122  return actual;
123  }
124 
125  double getSuitableSampleRateFor(double sr)
126  {
127  const int sz = - getAvailableSampleRates(NULL, 0);
128  double buffs[sz];
129  int rating;
130  getAvailableSampleRates(buffs, sz);
131 
132  int prev = 20000;
133  int idx = 0;
134  // This's a simple algorithm for finding more suitable frequncy.
135  int j;
136  for (j = 0; j < sz; j++)
137  {
138  double p = buffs[j] / sr;
139  rating = (int)(10000 * (p - (int)p));
140  rating += (int)p;
141 
142  if ((rating < prev) && (p >= 1))
143  {
144  prev = rating;
145  idx = j;
146  }
147 
148  printf("[0x%x]RT: %d (%g) %g\n", (unsigned)mDevId, rating, buffs[j], sr);
149  }
150 
151  return buffs[idx];
152  }
153 
154  int getAvailableSampleRates(double *pBuff, const int bufLen) const
155  {
156  AudioValueRange buffRanges[bufLen];
157  UInt32 sz;
158  OSStatus st = AudioDeviceGetPropertyInfo(mDevId, 0, mIsInput, kAudioDevicePropertyAvailableNominalSampleRates, &sz, NULL);
159  if (st != kAudioHardwareNoError)
160  {
161  printf("[0x%x]AudioDeviceGetPropertyInfo->kAudioDevicePropertyAvailableNominalSampleRates failed: %d\n", (unsigned)mDevId, (int)st);
162  return 0;
163  }
164 
165  if (sz > sizeof(buffRanges))
166  return -(int)(sz / sizeof(buffRanges[0]));
167 
168  st = AudioDeviceGetProperty(mDevId, 0, mIsInput, kAudioDevicePropertyAvailableNominalSampleRates, &sz, &buffRanges);
169  if (st != kAudioHardwareNoError)
170  {
171  printf("[0x%x]AudioDeviceGetProperty->kAudioDevicePropertyAvailableNominalSampleRates failed: %d\n", (unsigned)mDevId, (int)st);
172  return 0;
173  }
174 
175  unsigned i;
176  for (i = 0; i < sz / sizeof(buffRanges[0]); i++)
177  {
178  pBuff[i] = buffRanges[i].mMinimum;
179  }
180  return i;
181  }
182 
183  bool getStreamFormat(AudioStreamBasicDescription& desc) const
184  {
185  UInt32 sz = sizeof(desc);
186  OSStatus st = AudioDeviceGetProperty(mDevId, 0, mIsInput, kAudioDevicePropertyStreamFormat, &sz, &desc);
187  if (st != kAudioHardwareNoError)
188  {
189  printf("[0x%x]AudioDeviceGetProperty->kAudioDevicePropertyStreamFormat failed: %d\n", (unsigned)mDevId, (int)st);
190  return false;
191  }
192  return true;
193  }
194 
195  bool setStreamFormat(const AudioStreamBasicDescription& desc)
196  {
197  UInt32 sz = sizeof(desc);
198  OSStatus st = AudioDeviceSetProperty(mDevId, NULL, 0, mIsInput, kAudioDevicePropertyStreamFormat, sz, &desc);
199  if (st != kAudioHardwareNoError)
200  {
201  printf("[0x%x]AudioDeviceSetProperty->kAudioDevicePropertyStreamFormat failed: %d\n", (unsigned)mDevId, (int)st);
202  return false;
203  }
204  return true;
205  }
206 
207  static void dumpAudioStreamBasicDescription(const char* header, const AudioStreamBasicDescription& desc)
208  {
209  printf("%smSampleRate = %g\n", header, desc.mSampleRate);
210  printf("%smFormatID = %s\n", header, (char*)&desc.mFormatID);
211  printf("%smFormatFlags = 0x%08lX\n", header, desc.mFormatFlags);
212  printf("%smBytesPerPacket = %ld\n", header, desc.mBytesPerPacket);
213  printf("%smFramesPerPacket = %ld\n", header, desc.mFramesPerPacket);
214  printf("%smChannelsPerFrame = %ld\n", header, desc.mChannelsPerFrame);
215  printf("%smBytesPerFrame = %ld\n", header, desc.mBytesPerFrame);
216  printf("%smBitsPerChannel = %ld\n", header, desc.mBitsPerChannel);
217  }
218 
219  static bool isEqualAudioStreamBasicDescription(const AudioStreamBasicDescription& desc, const AudioStreamBasicDescription& desc2)
220  {
221  return (desc.mSampleRate == desc2.mSampleRate &&
222  desc.mFormatID == desc2.mFormatID &&
223  desc.mFormatFlags == desc2.mFormatFlags &&
224  desc.mBytesPerPacket == desc2.mBytesPerPacket &&
225  desc.mFramesPerPacket == desc2.mFramesPerPacket &&
226  desc.mChannelsPerFrame == desc2.mChannelsPerFrame &&
227  desc.mBytesPerFrame == desc2.mBytesPerFrame &&
228  desc.mBitsPerChannel == desc2.mBitsPerChannel);
229  }
230 
231  unsigned getBufferSize() const
232  {
233  UInt32 sr = 0;
234  UInt32 sz = sizeof(sr);
235  OSStatus st = AudioDeviceGetProperty(mDevId, 0, mIsInput, kAudioDevicePropertyBufferSize, &sz, &sr);
236  if (st != kAudioHardwareNoError)
237  printf("[0x%x]AudioDeviceGetProperty->kAudioDevicePropertyBufferSize failed: %d\n", (unsigned)mDevId, (int)st);
238 
239  return sr;
240  }
241 
242 
243  bool setBufferSize(unsigned sr)
244  {
245  UInt32 sz = sizeof(sr);
246  OSStatus st = AudioDeviceSetProperty(mDevId, NULL, 0, mIsInput, kAudioDevicePropertyBufferSize, sz, &sr);
247  if (st != kAudioHardwareNoError)
248  {
249  printf("[0x%x]AudioDeviceGetProperty->kAudioDevicePropertyBufferSize failed: %d\n", (unsigned)mDevId, (int)st);
250  return false;
251  }
252  return true;
253  }
254 
255 protected:
256  AudioDeviceID mDevId;
257  bool mIsInput;
258 };
259 
260 
261 #endif
262 
unsigned getBufferSize() const
Definition: MpCoreAudioHardware.h:231
bool setStreamFormat(const AudioStreamBasicDescription &desc)
Definition: MpCoreAudioHardware.h:195
AudioDeviceID getAudioDeviceID() const
Definition: MpCoreAudioHardware.h:60
int getAvailableSampleRates(double *pBuff, const int bufLen) const
Definition: MpCoreAudioHardware.h:154
double getSuitableSampleRateFor(double sr)
Definition: MpCoreAudioHardware.h:125
bool IsValid() const
Definition: MpCoreAudioHardware.h:70
bool getStreamFormat(AudioStreamBasicDescription &desc) const
Definition: MpCoreAudioHardware.h:183
CoreAudioHardware(AudioDeviceID devid, bool isInput)
Definition: MpCoreAudioHardware.h:45
static void dumpAudioStreamBasicDescription(const char *header, const AudioStreamBasicDescription &desc)
Definition: MpCoreAudioHardware.h:207
bool IsInput() const
Definition: MpCoreAudioHardware.h:65
static CoreAudioHardware fromDefaultOutput()
Definition: MpCoreAudioHardware.h:81
bool setBufferSize(unsigned sr)
Definition: MpCoreAudioHardware.h:243
AudioDeviceID mDevId
Device handle.
Definition: MpCoreAudioHardware.h:256
int getLatency() const
Definition: MpCoreAudioHardware.h:114
static CoreAudioHardware fromDefaultInput()
Definition: MpCoreAudioHardware.h:92
Container for CoreAudio hardware device specific.
Definition: MpCoreAudioHardware.h:40
double getActualSampleRate() const
Definition: MpCoreAudioHardware.h:103
bool mIsInput
Whether input or output operations.
Definition: MpCoreAudioHardware.h:257
static bool isEqualAudioStreamBasicDescription(const AudioStreamBasicDescription &desc, const AudioStreamBasicDescription &desc2)
Definition: MpCoreAudioHardware.h:219
static CoreAudioHardware invalid()
Definition: MpCoreAudioHardware.h:76