CLAM-Development  1.4.0
RtAAudioDevice.hxx
Go to the documentation of this file.
1 
2 #ifndef __RtAAudioDevice_hxx__
3 #define __RtAAudioDevice_hxx__
4 
5 #include "RtAudio.hxx"
6 #include "AudioIO.hxx"
7 #include "AudioIn.hxx"
8 #include "AudioOut.hxx"
9 #include "AudioDeviceList.hxx"
10 #include "AudioDevice.hxx"
11 #include <cstdio>
12 
13 
14 
15 #ifdef __MACOSX_CORE__
16 #define MACOSX_WORKAROUND
17 #endif
18 
19 #ifdef __MACOSX_CORE__
20 /* a kludgy factor 2 (22050->44100) sample rate conversion
21 ** because macosx drivers do not handle 22050 */
22 #define FACTOR2SRC_KLUDGE
23 #endif
24 
25 namespace CLAM
26 {
27  typedef signed short MY_TYPE;
28  #define FORMAT RtAudio::RTAUDIO_SINT16
30  {
31  private:
32  class Buffer
33  {
34  friend class RtAAudioDevice;
35  private:
36  Buffer(int channels = 0,int frames = 0)
37  {
38  mData = 0;
39  Alloc(channels,frames);
40  mChannelsDone = 0;
41  mReadIndex = 0;
42  mWriteIndex = 0;
43  }
44  void Alloc(int channels = 0,int frames = 0)
45  {
46  if (mData) delete mData;
47  mChannels = channels;
48  mFrames = frames;
49  if (mChannels && mFrames)
50  {
51  mData = new TData[mChannels*mFrames];
52  }else{
53  mData = 0;
54  }
55  }
56 
57  TData* mData;
58  int mReadIndex;
59  int mWriteIndex;
60  int mChannels;
61  int mChannelsDone;
62  int mFrames;
63  int Filled(void)
64  {
65  return mWriteIndex >= mReadIndex ?
66  mWriteIndex - mReadIndex :
67  mWriteIndex + mFrames - mReadIndex;
68  }
69 
70  void CopyTo(MY_TYPE* ptr,int frames)
71  {
72  int cnt = frames*mChannels;
73  int limit = mFrames*mChannels;
74  int i = mReadIndex*mChannels;
75 
76 #ifdef DEBUG_RDWR_POS
77  printf("copyto: r=%d %d\n",mReadIndex,frames);
78 #endif
79  while (cnt--)
80  {
81  *ptr++ = (MY_TYPE)(mData[i++]*32767.);
82  if (i==limit) i = 0;
83  }
84  mReadIndex += frames;
85  if (mReadIndex >= mFrames) mReadIndex -= mFrames;
86 
87  }
88 
89 #ifdef FACTOR2SRC_KLUDGE
90  void CopyToFactor2SRC(MY_TYPE* ptr,int frames)
91  {
92  int cnt = frames*mChannels;
93  int limit = mFrames*mChannels;
94  int i = mReadIndex*mChannels;
95 
96 #ifdef DEBUG_RDWR_POS
97  printf("copyto: r=%d %d\n",mReadIndex,frames);
98 #endif
99  while (cnt--)
100  {
101  *ptr++ = (MY_TYPE)(mData[i]*32767.);
102  *ptr++ = (MY_TYPE)(mData[i]*32767.);
103  i++;
104  if (i==limit) i = 0;
105  }
106  mReadIndex += frames;
107  if (mReadIndex >= mFrames) mReadIndex -= mFrames;
108 
109  }
110 #endif
111 
112  void CopyFrom(MY_TYPE* ptr,int frames)
113  {
114  int cnt = frames*mChannels;
115  int limit = mFrames*mChannels;
116  int i = mWriteIndex*mChannels;
117 
118 #ifdef DEBUG_RDWR_POS
119  printf("copyfrom: w=%d %d\n",mWriteIndex,frames);
120 #endif
121  while (cnt--)
122  {
123  mData[i++] = TData(*ptr++)/32767.;
124  if (i==limit) i = 0;
125  }
126  mWriteIndex += frames;
127  if (mWriteIndex >= mFrames) mWriteIndex -= mFrames;
128  }
129 
130 #ifdef FACTOR2SRC_KLUDGE
131  void CopyFromDoFactor2SRC(MY_TYPE* ptr,int frames)
132  {
133  int cnt = frames*mChannels;
134  int limit = mFrames*mChannels;
135  int i = mWriteIndex*mChannels;
136 
137 #ifdef DEBUG_RDWR_POS
138  printf("copyfrom: w=%d %d\n",mWriteIndex,frames);
139 #endif
140  while (cnt--)
141  {
142  TData t = TData(*ptr++);
143  t += TData(*ptr++);
144  t /= 65534.;
145  mData[i++] = t;
146  if (i==limit) i = 0;
147  }
148  mWriteIndex += frames;
149  if (mWriteIndex >= mFrames) mWriteIndex -= mFrames;
150  }
151 #endif
152 
153  void ChannelCopyFrom(TData* ptr,int size,int chnId)
154  {
155  int i = mWriteIndex*mChannels+chnId;
156  int n = size;
157  int limit = mChannels*mFrames;
158 
159 #ifdef DEBUG_RDWR_POS
160  printf("ChannelCopyFrom: w=%d %d\n",mWriteIndex,size);
161 #endif
162  fflush(stdout);
163  while (n--)
164  {
165  mData[i] = *ptr++;
166  i += mChannels;
167  if (i>=limit) i = chnId;
168  }
169  mChannelsDone++;
170  if (mChannelsDone==mChannels)
171  {
172  mWriteIndex += size;
173  if (mWriteIndex >= mFrames) mWriteIndex -= mFrames;
174  mChannelsDone = 0;
175  }
176  }
177 
178  void ChannelCopyTo(TData* ptr,int size,int chnId)
179  {
180  int i = mReadIndex*mChannels+chnId;
181  int n = size;
182  int limit = mChannels*mFrames;
183 
184 #ifdef DEBUG_RDWR_POS
185  printf("ChannelCopyTo: r=%d %d\n",mReadIndex,size);
186 #endif
187  while (n--)
188  {
189  *ptr++ = mData[i];
190  i += mChannels;
191  if (i>=limit) i = chnId;
192  }
193  mChannelsDone++;
194  if (mChannelsDone==mChannels)
195  {
196  mReadIndex += size;
197  if (mReadIndex >= mFrames) mReadIndex -= mFrames;
198  mChannelsDone = 0;
199  }
200  }
201  };
202 
203  RtAudio *mRtAudio;
204  int mRtAudioStream;
205  MY_TYPE *mRtAudioBuffer;
206  int mRtAudioBufferSize;
207 #ifdef MACOSX_WORKAROUND
208  int mInternalRtAudioBufferSize;
209 #endif
210  Buffer mWriteBuffer;
211  Buffer mReadBuffer;
212  bool mStarted;
213  bool mTickOnRead;
214  bool mTickOnWrite;
215  int mDevice;
216 #ifdef FACTOR2SRC_KLUDGE
217  bool mDoFactor2SRC;
218 #endif
219  public:
220  RtAAudioDevice(const std::string& name,int _device);
221  ~RtAAudioDevice();
222 
223  void Start(void) throw(Err);
224  void Stop(void) throw(Err);
225  void Tick(void);
226  void Read(Audio& audio,const int channelID);
227  void Write(const Audio& audio,const int channelID);
228  };
229 
230 
232  {
233  private:
234  static RtAAudioDeviceList sDevices;
235 
237 
238  std::vector< int > mDevIDs;
239 
240  protected:
241 
242  void EnumerateAvailableDevices() throw ( Err );
243 
244  public:
245 
246  virtual ~RtAAudioDeviceList();
247 
248  inline std::string DefaultDevice()
249  {
250  return "default";
251  }
252  static void init();
253 
254  AudioDevice* Create( const std::string& name, const std::string& device );
255 
256  };
257 
258 } // namespace CLAM
259 
260 #endif // __RtAAudioDevice_hxx__
261