CSL  6.0
CAIO.cpp
Go to the documentation of this file.
1 //
2 // CAIO.cpp -- DAC IO using CoreAudio
3 // See the copyright notice and acknowledgment of authors in the file COPYRIGHT
4 //
5 
6 #include "CAIO.h"
7 
8 #include "CAAudioHardwareDevice.h"
9 #include "CAAudioHardwareSystem.h"
10 
11 using namespace csl;
12 
13 // This callback routine will be called by CoreAudio/AudioUnits
14 
15 static ComponentResult RenderCallback (void * userData, AudioUnitRenderActionFlags * ioActionFlags,
16  const AudioTimeStamp * inTimeStamp, UInt32 inOutputBusNumber,
17  UInt32 inNumberFrames, AudioBufferList * ioData) {
18  AUIO * auio = (AUIO *) userData; // cast uder data ptr
19  unsigned numChannels = ioData->mNumberBuffers; // assumes non-interleaved buffers
20  Buffer * auBuffer = & auio->mOutputBuffer; // temp buffer for passing ptrs to CSL
21  for (unsigned i = 0; i < numChannels; i++) // copy IO data ptrs to buffer
22  auBuffer->mBuffers[i] = (sample *) ioData->mBuffers[i].mData;
23  auBuffer->mAreBuffersAllocated = true; // set up buffer
24  auBuffer->mDidIAllocateBuffers = false;
25  auBuffer->mIsPopulated = false;
26  auio->mNumFramesPlayed += inNumberFrames;
27  auio->pullInput( * auBuffer);
28  return noErr;
29 }
30 
31 // AUIO Constructors
32 
33 AUIO :: AUIO() : IO() { }
34 
35 AUIO :: AUIO(unsigned s_rate, unsigned b_size, int in_device, int out_device, unsigned in_chans, unsigned out_chans)
36  : IO(s_rate, b_size, in_device, out_device, in_chans, out_chans) { }
37 
39 
40 void AUIO :: handleError(OSStatus err) throw(CException) {
41  logMsg(kLogError, "An error occured while using the AudioUnit default output\n");
42  logMsg(kLogError, "Error number: %d\n", (int)err);
43  throw IOError("CoreAudio error");
44 }
45 
46 // Open plugs in the callback function
47 
48 void AUIO :: open() throw(CException) {
49 #ifdef DO_TIMING
50  mThisSec = mTimeVals = mTimeSum = 0;
51 #endif
52  OSStatus result;
53  AURenderCallbackStruct renderCallback;
54  renderCallback.inputProc = RenderCallback;
55  renderCallback.inputProcRefCon = this;
56  // plug in the audio renderer callback
57  result = AudioUnitSetProperty (mAudioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0,
58  &renderCallback, sizeof(renderCallback));
59  if (noErr != result)
60  handleError(result);
61 }
62 
63 // Start/stop
64 
65 void AUIO :: start() throw(CException) {
66  mNumFramesPlayed = 0;
67 }
68 
69 void AUIO :: stop() throw(CException) {
70  // don't need to do anything
71 }
72 
73 // Close stop the callback
74 
75 void AUIO :: close() throw(CException) {
76  OSStatus result;
77  AURenderCallbackStruct renderCallback;
78  renderCallback.inputProc = NULL;
79  renderCallback.inputProcRefCon = this;
80  result = AudioUnitSetProperty (mAudioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0,
81  &renderCallback, sizeof(renderCallback));
82  if (noErr != result)
83  handleError(result);
84 }
85 
86 // Answer the most recent input buffer
87 
90 }
91 
92 // really get the desired format of input
93 
94 Buffer & AUIO :: getInput(unsigned numFrames, unsigned numChannels) throw(CException) {
95  if (mNumInChannels == 0)
96  throw IOError("Can't get unopened input");
97 // Interleaver interleaver;
98 // interleaver.deinterleave(mInputBuffer, mInputPointer, numFrames, numChannels);
99  mInputBuffer.mIsPopulated = true;
100  return(mInputBuffer);
101 }
102 
103 /////////////////////// CoreAudio IO /////////////////////////////////
104 
105 // Constructor creates input/output device list
106 
107 extern vector < IODevice *> gIODevices; // Global list of all known IO devices
108 
109 // CAIO constructor -- verbose version loads a table of the CAIO devices
110 
112 
113 CAIO :: CAIO(unsigned s_rate, unsigned b_size, int in_device, int out_device, unsigned in_chans, unsigned out_chans)
114  : AUIO(s_rate, b_size, in_device, out_device, in_chans, out_chans) {
115  if (gIODevices.empty()) { // if we've never set up before
116  UInt32 numDevs = CAAudioHardwareSystem::GetNumberDevices();
117  if (numDevs > 0) { // if you found any devices
118  logMsg("");
119  logMsg("IO Table");
120  UInt32 devIndex = 0;
121  AudioDeviceID defInID = CAAudioHardwareSystem::GetDefaultDevice(kAudioDeviceSectionInput, false);
122  AudioDeviceID defOutID = CAAudioHardwareSystem::GetDefaultDevice(kAudioDeviceSectionOutput, false);
123  while (devIndex < numDevs) { // loop over devices
124  IODevice * newDev = new IODevice;
125  CAAudioHardwareDevice theDevice(CAAudioHardwareSystem::GetDeviceAtIndex(devIndex));
126  newDev->mIndex = theDevice.GetAudioDeviceID(); // copy index, name, rates, etc.
127  CFStringGetCString(theDevice.CopyName(), newDev->mName, CSL_NAME_LEN, 0);
128  newDev->mFrameRate = (float) theDevice.GetNominalSampleRate();
129  // get # of I/O channels for device
130  newDev->mMaxInputChannels = theDevice.GetTotalNumberChannels(kAudioDeviceSectionInput);
131  newDev->mMaxOutputChannels = theDevice.GetTotalNumberChannels(kAudioDeviceSectionOutput);
132  if (newDev->mIndex == defInID)
133  newDev->mIsDefaultIn = 1;
134  else newDev->mIsDefaultIn = 0;
135  if (newDev->mIndex == defOutID)
136  newDev->mIsDefaultOut = 1;
137  else newDev->mIsDefaultOut = 0;
138  gIODevices.push_back(newDev); // push onto global list
139  ++devIndex;
140  // Print out the CoreAudio device list
141  newDev->dump();
142  }
143  }
144  logMsg("");
145  }
146 }
147 
149 
150 // Error fnuction
151 
152 void CAIO :: handleError(OSStatus result) throw(CException) {
153  AudioUnitUninitialize(mAudioUnit);
154  CloseComponent(mAudioUnit);
155  AUIO::handleError(result);
156 }
157 
158 // Open sets up CAIO
159 
160 void CAIO :: open() throw(CException) { // Get the output audio unit
161  OSStatus result = noErr;
162  ComponentDescription desc;
163  // get the cmoponent
164  desc.componentType = kAudioUnitType_Output;
165  desc.componentSubType = kAudioUnitSubType_DefaultOutput;
166  desc.componentManufacturer = kAudioUnitManufacturer_Apple;
167  desc.componentFlags = 0;
168  desc.componentFlagsMask = 0;
169  Component comp = FindNextComponent(NULL, &desc);
170  // check it
171  if (comp == NULL)
172  logMsg(kLogError, "An error occured while opening the AudioUnit default output\n");
173  // open up
174  result = OpenAComponent(comp, &mAudioUnit);
175  if (noErr != result)
176  handleError(result);
177  // AU init!
178  result = AudioUnitInitialize (mAudioUnit);
179  if (noErr != result)
180  handleError(result);
181  // AU open
182  AUIO::open();
183 }
184 
185 void CAIO :: start() throw(CException) {
186  OSStatus result = AudioOutputUnitStart(mAudioUnit); // Start 'er up!
187  if (noErr != result)
188  handleError(result);
189 }
190 
191 void CAIO :: stop() throw(CException) {
192  OSStatus result = AudioOutputUnitStop(mAudioUnit);
193  if (noErr != result)
194  handleError(result);
195 }
196 
197 void CAIO :: close() throw(CException) {
198  AudioUnitUninitialize(mAudioUnit);
199  CloseComponent(mAudioUnit);
200 }
void logMsg(const char *format,...)
These are the public logging messages.
Definition: CGestalt.cpp:292
long mTimeSum
for printing run-time statistics
Definition: CSL_Core.h:797
unsigned mNumFrames
num frames used in each buffer
Definition: CSL_Core.h:113
bool mAreBuffersAllocated
are the buffers allocated?
Definition: CSL_Core.h:120
bool mIsDefaultIn
am i the default in?
Definition: CSL_Core.h:827
AdditiveInstrument.h – Sum-of-sines synthesis instrument class.
Definition: Accessor.h:17
void pullInput(Buffer &outBuffer, SampleBuffer out=0)
get a buffer from the CSL graph
Definition: CSL_Core.cpp:1425
unsigned mIndex
index (API-specific)
Definition: CSL_Core.h:822
char mName[CSL_NAME_LEN]
public members
Definition: CSL_Core.h:821
bool mIsDefaultOut
am i the default out?
Definition: CSL_Core.h:828
CAIO()
Definition: CAIO.cpp:111
~AUIO()
Definition: CAIO.cpp:38
AUIO()
Definition: CAIO.cpp:33
virtual void start()
Definition: CAIO.cpp:65
void stop()
Definition: CAIO.cpp:191
SampleBufferVector mBuffers
the storage vector – pointers to (SampleBuffer) buffers
Definition: CSL_Core.h:182
void close()
open/close start/stop methods
Definition: CAIO.cpp:197
#define CSL_NAME_LEN
default string length
Definition: CSL_Types.h:121
void dump()
pretty-print the receiver' device
Definition: CSL_Core.cpp:1570
unsigned mNumChannels
num channels in buffer (num mono buffers)
Definition: CSL_Core.h:112
static ComponentResult RenderCallback(void *userData, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inOutputBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
Definition: CAIO.cpp:15
virtual void close()
open/close start/stop methods
Definition: CAIO.cpp:75
float sample
(could be changed to int, or double)
Definition: CSL_Types.h:191
virtual void stop()
Definition: CAIO.cpp:69
float mFrameRate
current SR
Definition: CSL_Core.h:825
IO – the abstract I/O scheduling class; subclasses interface to specific I/O APIs.
Definition: CSL_Core.h:752
AudioUnit mAudioUnit
Definition: CAIO.h:37
long mThisSec
Definition: CSL_Core.h:797
unsigned mMaxInputChannels
HW ins
Definition: CSL_Core.h:823
unsigned mNumFramesPlayed
counter of frames I've played
Definition: CSL_Core.h:784
static unsigned mNumInChannels
The actual start-up values are defined in CSL_Types.h.
Definition: CGestalt.cpp:29
IO Error.
virtual void open()
open/close start/stop methods
Definition: CAIO.cpp:48
void handleError(OSStatus result)
Definition: CAIO.cpp:40
unsigned mMaxOutputChannels
HW outs
Definition: CSL_Core.h:824
void start()
Definition: CAIO.cpp:185
bool mDidIAllocateBuffers
who allocated my data buffers?
Definition: CSL_Core.h:121
vector< IODevice * > gIODevices
Definition: CSL_Core.cpp:1387
Buffer – the multi-channel sample buffer class (passed around between generators and IO guys)...
Definition: CSL_Core.h:106
Buffer mOutputBuffer
the output buffer I use (passed to nextBuffer calls)
Definition: CSL_Core.h:779
Buffer mInputBuffer
the most recent input buffer (if it's turned on)
Definition: CSL_Core.h:778
~CAIO()
Definition: CAIO.cpp:148
void open()
open/close start/stop methods
Definition: CAIO.cpp:160
virtual Buffer & getInput()
get the current input buffer
Definition: CAIO.cpp:88
long mTimeVals
Definition: CSL_Core.h:797
IO Device class – a holder for a sound interface with name, id, # IO channels, etc.
Definition: CSL_Core.h:815
void handleError(OSStatus result)
Definition: CAIO.cpp:152
General-purpose AudioUnit IO class.
Definition: CAIO.h:21
bool mIsPopulated
does the buffer have data?
Definition: CSL_Core.h:122
Base class of CSL exceptions (written upper-case). Has a string message.