CLAM-Development
1.1
|
00001 00002 #ifndef __RtAAudioDevice_hxx__ 00003 #define __RtAAudioDevice_hxx__ 00004 00005 #include "RtAudio.hxx" 00006 #include "AudioIO.hxx" 00007 #include "AudioIn.hxx" 00008 #include "AudioOut.hxx" 00009 #include "AudioDeviceList.hxx" 00010 #include "AudioDevice.hxx" 00011 #include <cstdio> 00012 00013 00014 00015 #ifdef __MACOSX_CORE__ 00016 #define MACOSX_WORKAROUND 00017 #endif 00018 00019 #ifdef __MACOSX_CORE__ 00020 /* a kludgy factor 2 (22050->44100) sample rate conversion 00021 ** because macosx drivers do not handle 22050 */ 00022 #define FACTOR2SRC_KLUDGE 00023 #endif 00024 00025 namespace CLAM 00026 { 00027 typedef signed short MY_TYPE; 00028 #define FORMAT RtAudio::RTAUDIO_SINT16 00029 class RtAAudioDevice: public AudioDevice 00030 { 00031 private: 00032 class Buffer 00033 { 00034 friend class RtAAudioDevice; 00035 private: 00036 Buffer(int channels = 0,int frames = 0) 00037 { 00038 mData = 0; 00039 Alloc(channels,frames); 00040 mChannelsDone = 0; 00041 mReadIndex = 0; 00042 mWriteIndex = 0; 00043 } 00044 void Alloc(int channels = 0,int frames = 0) 00045 { 00046 if (mData) delete mData; 00047 mChannels = channels; 00048 mFrames = frames; 00049 if (mChannels && mFrames) 00050 { 00051 mData = new TData[mChannels*mFrames]; 00052 }else{ 00053 mData = 0; 00054 } 00055 } 00056 00057 TData* mData; 00058 int mReadIndex; 00059 int mWriteIndex; 00060 int mChannels; 00061 int mChannelsDone; 00062 int mFrames; 00063 int Filled(void) 00064 { 00065 return mWriteIndex >= mReadIndex ? 00066 mWriteIndex - mReadIndex : 00067 mWriteIndex + mFrames - mReadIndex; 00068 } 00069 00070 void CopyTo(MY_TYPE* ptr,int frames) 00071 { 00072 int cnt = frames*mChannels; 00073 int limit = mFrames*mChannels; 00074 int i = mReadIndex*mChannels; 00075 00076 #ifdef DEBUG_RDWR_POS 00077 printf("copyto: r=%d %d\n",mReadIndex,frames); 00078 #endif 00079 while (cnt--) 00080 { 00081 *ptr++ = (MY_TYPE)(mData[i++]*32767.); 00082 if (i==limit) i = 0; 00083 } 00084 mReadIndex += frames; 00085 if (mReadIndex >= mFrames) mReadIndex -= mFrames; 00086 00087 } 00088 00089 #ifdef FACTOR2SRC_KLUDGE 00090 void CopyToFactor2SRC(MY_TYPE* ptr,int frames) 00091 { 00092 int cnt = frames*mChannels; 00093 int limit = mFrames*mChannels; 00094 int i = mReadIndex*mChannels; 00095 00096 #ifdef DEBUG_RDWR_POS 00097 printf("copyto: r=%d %d\n",mReadIndex,frames); 00098 #endif 00099 while (cnt--) 00100 { 00101 *ptr++ = (MY_TYPE)(mData[i]*32767.); 00102 *ptr++ = (MY_TYPE)(mData[i]*32767.); 00103 i++; 00104 if (i==limit) i = 0; 00105 } 00106 mReadIndex += frames; 00107 if (mReadIndex >= mFrames) mReadIndex -= mFrames; 00108 00109 } 00110 #endif 00111 00112 void CopyFrom(MY_TYPE* ptr,int frames) 00113 { 00114 int cnt = frames*mChannels; 00115 int limit = mFrames*mChannels; 00116 int i = mWriteIndex*mChannels; 00117 00118 #ifdef DEBUG_RDWR_POS 00119 printf("copyfrom: w=%d %d\n",mWriteIndex,frames); 00120 #endif 00121 while (cnt--) 00122 { 00123 mData[i++] = TData(*ptr++)/32767.; 00124 if (i==limit) i = 0; 00125 } 00126 mWriteIndex += frames; 00127 if (mWriteIndex >= mFrames) mWriteIndex -= mFrames; 00128 } 00129 00130 #ifdef FACTOR2SRC_KLUDGE 00131 void CopyFromDoFactor2SRC(MY_TYPE* ptr,int frames) 00132 { 00133 int cnt = frames*mChannels; 00134 int limit = mFrames*mChannels; 00135 int i = mWriteIndex*mChannels; 00136 00137 #ifdef DEBUG_RDWR_POS 00138 printf("copyfrom: w=%d %d\n",mWriteIndex,frames); 00139 #endif 00140 while (cnt--) 00141 { 00142 TData t = TData(*ptr++); 00143 t += TData(*ptr++); 00144 t /= 65534.; 00145 mData[i++] = t; 00146 if (i==limit) i = 0; 00147 } 00148 mWriteIndex += frames; 00149 if (mWriteIndex >= mFrames) mWriteIndex -= mFrames; 00150 } 00151 #endif 00152 00153 void ChannelCopyFrom(TData* ptr,int size,int chnId) 00154 { 00155 int i = mWriteIndex*mChannels+chnId; 00156 int n = size; 00157 int limit = mChannels*mFrames; 00158 00159 #ifdef DEBUG_RDWR_POS 00160 printf("ChannelCopyFrom: w=%d %d\n",mWriteIndex,size); 00161 #endif 00162 fflush(stdout); 00163 while (n--) 00164 { 00165 mData[i] = *ptr++; 00166 i += mChannels; 00167 if (i>=limit) i = chnId; 00168 } 00169 mChannelsDone++; 00170 if (mChannelsDone==mChannels) 00171 { 00172 mWriteIndex += size; 00173 if (mWriteIndex >= mFrames) mWriteIndex -= mFrames; 00174 mChannelsDone = 0; 00175 } 00176 } 00177 00178 void ChannelCopyTo(TData* ptr,int size,int chnId) 00179 { 00180 int i = mReadIndex*mChannels+chnId; 00181 int n = size; 00182 int limit = mChannels*mFrames; 00183 00184 #ifdef DEBUG_RDWR_POS 00185 printf("ChannelCopyTo: r=%d %d\n",mReadIndex,size); 00186 #endif 00187 while (n--) 00188 { 00189 *ptr++ = mData[i]; 00190 i += mChannels; 00191 if (i>=limit) i = chnId; 00192 } 00193 mChannelsDone++; 00194 if (mChannelsDone==mChannels) 00195 { 00196 mReadIndex += size; 00197 if (mReadIndex >= mFrames) mReadIndex -= mFrames; 00198 mChannelsDone = 0; 00199 } 00200 } 00201 }; 00202 00203 RtAudio *mRtAudio; 00204 int mRtAudioStream; 00205 MY_TYPE *mRtAudioBuffer; 00206 int mRtAudioBufferSize; 00207 #ifdef MACOSX_WORKAROUND 00208 int mInternalRtAudioBufferSize; 00209 #endif 00210 Buffer mWriteBuffer; 00211 Buffer mReadBuffer; 00212 bool mStarted; 00213 bool mTickOnRead; 00214 bool mTickOnWrite; 00215 int mDevice; 00216 #ifdef FACTOR2SRC_KLUDGE 00217 bool mDoFactor2SRC; 00218 #endif 00219 public: 00220 RtAAudioDevice(const std::string& name,int _device); 00221 ~RtAAudioDevice(); 00222 00223 void Start(void) throw(Err); 00224 void Stop(void) throw(Err); 00225 void Tick(void); 00226 void Read(Audio& audio,const int channelID); 00227 void Write(const Audio& audio,const int channelID); 00228 }; 00229 00230 00231 class RtAAudioDeviceList : public AudioDeviceList 00232 { 00233 private: 00234 static RtAAudioDeviceList sDevices; 00235 00236 RtAAudioDeviceList(); 00237 00238 std::vector< int > mDevIDs; 00239 00240 protected: 00241 00242 void EnumerateAvailableDevices() throw ( Err ); 00243 00244 public: 00245 00246 virtual ~RtAAudioDeviceList(); 00247 00248 inline std::string DefaultDevice() 00249 { 00250 return "default"; 00251 } 00252 static void init(); 00253 00254 AudioDevice* Create( const std::string& name, const std::string& device ); 00255 00256 }; 00257 00258 } // namespace CLAM 00259 00260 #endif // __RtAAudioDevice_hxx__ 00261