pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
plonk_PortAudioAudioHostInline.h
00001 /*
00002  -------------------------------------------------------------------------------
00003  This file is part of the Plink, Plonk, Plank libraries
00004  by Martin Robinson
00005  
00006  http://code.google.com/p/pl-nk/
00007  
00008  Copyright University of the West of England, Bristol 2011-14
00009  All rights reserved.
00010  
00011  Redistribution and use in source and binary forms, with or without
00012  modification, are permitted provided that the following conditions are met:
00013  
00014  * Redistributions of source code must retain the above copyright
00015    notice, this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright
00017    notice, this list of conditions and the following disclaimer in the
00018    documentation and/or other materials provided with the distribution.
00019  * Neither the name of University of the West of England, Bristol nor 
00020    the names of its contributors may be used to endorse or promote products
00021    derived from this software without specific prior written permission.
00022  
00023  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00024  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00025  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
00026  DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF THE WEST OF ENGLAND, BRISTOL BE 
00027  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
00028  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
00029  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
00030  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
00031  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
00032  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
00033  
00034  This software makes use of third party libraries. For more information see:
00035  doc/license.txt included in the distribution.
00036  -------------------------------------------------------------------------------
00037  */
00038 
00039 #if PLANK_INLINING_FUNCTIONS
00040 
00041 template<class SampleType>
00042 static inline int paCallback (const void *input, void *output,
00043                               unsigned long frameCount,
00044                               const PaStreamCallbackTimeInfo* timeInfo,
00045                               PaStreamCallbackFlags statusFlags,
00046                               void *userData)
00047 {
00048     PortAudioAudioHostBase<SampleType>* host = static_cast<PortAudioAudioHostBase<SampleType>*> (userData);
00049     return host->callback ((const SampleType**)input, (SampleType**)output, 
00050                            frameCount, timeInfo, statusFlags);
00051 }
00052 
00053 static inline bool paCheckError (PaError err)
00054 {
00055     if (err != paNoError)
00056     {
00057         printf ("paerror '%s' (%d)\n", Pa_GetErrorText (err), err);
00058         return true;
00059     }
00060     
00061     return false; 
00062 }
00063 
00064 //static inline void paGetInfo()
00065 //{
00066 //    const PaDeviceIndex inputDeviceId = Pa_GetDefaultInputDevice();
00067 //    const PaDeviceIndex outputDeviceId = Pa_GetDefaultOutputDevice();
00068 //    
00069 //    const PaDeviceInfo* inputInfo = Pa_GetDeviceInfo (inputDeviceId);
00070 //    const PaDeviceInfo* outputInfo = Pa_GetDeviceInfo (outputDeviceId);
00071 //    
00072 //
00073 //}
00074 
00075 //------------------------------------------------------------------------------
00076 
00077 template<class SampleType>
00078 PortAudioAudioHostBase<SampleType>::PortAudioAudioHostBase() throw() 
00079 :   stream (0)
00080 {
00081     PaError err;
00082         err = Pa_Initialize();
00083     paCheckError (err);
00084     
00085     this->setPreferredHostBlockSize (512);
00086     this->setPreferredGraphBlockSize (128);
00087     this->setPreferredHostSampleRate (44100.0);
00088     this->setNumInputs (1);
00089     this->setNumOutputs (2);
00090 }
00091 
00092 template<class SampleType>
00093 PortAudioAudioHostBase<SampleType>::~PortAudioAudioHostBase()
00094 {
00095     if (stream)
00096         this->stopHost();
00097     
00098     PaError err;
00099     err = Pa_Terminate();
00100     paCheckError (err);
00101 }
00102 
00103 template<class SampleType>
00104 Text PortAudioAudioHostBase<SampleType>::getHostName() const throw()
00105 {
00106     return "PortAudio (" + TypeUtility<SampleType>::getTypeName() + ")";
00107 }
00108 
00109 template<class SampleType>
00110 Text PortAudioAudioHostBase<SampleType>::getNativeHostName() const throw()
00111 {
00112     const PaHostApiIndex paHostIndex = Pa_GetDefaultHostApi();
00113     const PaHostApiInfo* info = Pa_GetHostApiInfo (paHostIndex);
00114     return info->name;
00115 }
00116 
00117 template<class SampleType>
00118 Text PortAudioAudioHostBase<SampleType>::getInputName() const throw()
00119 {
00120     const PaDeviceIndex deviceId = Pa_GetDefaultInputDevice();    
00121     const PaDeviceInfo* info = Pa_GetDeviceInfo (deviceId);
00122     return info->name;
00123 }
00124 
00125 template<class SampleType>
00126 Text PortAudioAudioHostBase<SampleType>::getOutputName() const throw()
00127 {
00128     const PaDeviceIndex deviceId = Pa_GetDefaultOutputDevice();    
00129     const PaDeviceInfo* info = Pa_GetDeviceInfo (deviceId);
00130     return info->name;
00131 }
00132 
00133 template<class SampleType>
00134 double PortAudioAudioHostBase<SampleType>::getCpuUsage() const throw()
00135 {
00136     if (!stream) return 0.0;
00137     return Pa_GetStreamCpuLoad (stream);
00138 }
00139 
00140 template<class SampleType>
00141 void PortAudioAudioHostBase<SampleType>::stopHost() throw()
00142 {
00143     PaError err;
00144     
00145     err = Pa_StopStream (stream);
00146     paCheckError (err);
00147     
00148     err = Pa_CloseStream (stream);
00149     paCheckError (err);
00150     
00151     stream = NULL;
00152     this->setIsRunning (false);
00153 }
00154 
00155 template<class SampleType>
00156 void PortAudioAudioHostBase<SampleType>::startHost() throw()
00157 {        
00158     PaError err;
00159     
00160     PaSampleFormat sampleFormat;
00161     
00162     switch (TypeUtility<SampleType>::getTypeCode()) 
00163     {
00164         case TypeCode::Float: sampleFormat = paFloat32; break;
00165         case TypeCode::Short: sampleFormat = paInt16;   break;
00166         case TypeCode::Int:   sampleFormat = paInt32;   break;
00167         case TypeCode::Int24: sampleFormat = paInt24;   break;
00168         case TypeCode::Char:  sampleFormat = paInt8;    break;
00169         default: sampleFormat = 0; break;
00170     }
00171         
00172     if (sampleFormat != 0)
00173     {
00174         err = Pa_OpenDefaultStream (&stream, 
00175                                     this->getNumInputs(), this->getNumOutputs(),
00176                                     sampleFormat | paNonInterleaved,
00177                                     this->getPreferredHostSampleRate(), this->getPreferredHostBlockSize(),
00178                                     paCallback<SampleType>, 
00179                                     this);
00180         
00181         // if our preferred sample rate and block size are invalid hopefully we get an error
00182         if (paCheckError (err)) 
00183             return;
00184         
00185         this->startHostInternal();
00186         
00187         err = Pa_StartStream (stream);
00188         paCheckError (err); 
00189     }
00190     else plonk_assertfalse;
00191 }
00192 
00193 template<class SampleType>
00194 int PortAudioAudioHostBase<SampleType>::callback (const SampleType **inputData, SampleType **outputData,
00195                                                   unsigned long frameCount,
00196                                                   const PaStreamCallbackTimeInfo* timeInfo,
00197                                                   PaStreamCallbackFlags statusFlags) throw()
00198 {
00199     (void)timeInfo;
00200     (void)statusFlags;
00201     
00202     this->setPreferredHostBlockSize ((int)frameCount);
00203     
00204     ConstBufferArray& inputs = this->getInputs();
00205     BufferArray& outputs = this->getOutputs();
00206 
00207     const int numInputs = inputs.length();
00208     const int numOutputs = outputs.length();
00209     
00210     int i;
00211     
00212     for (i = 0; i < numInputs; ++i)
00213         inputs.atUnchecked (i) = inputData[i];
00214 
00215     for (i = 0; i < numOutputs; ++i)
00216         outputs.atUnchecked (i) = outputData[i];
00217     
00218     this->process();
00219     
00220     return paContinue;
00221 }
00222 
00223 
00224 #if (defined(__OBJC__) && !PLONK_IOS)|| DOXYGEN
00225 END_PLONK_NAMESPACE
00226 
00227 @class PLAudioHost;
00228 
00229 using namespace plonk;
00230 
00235 @protocol PLAudioHostDelegate <NSObject>
00236 @optional
00237 - (FloatUnit)constructGraphFloat:(PLAudioHost*)host;
00238 - (ShortUnit)constructGraphShort:(PLAudioHost*)host;
00239 - (IntUnit)constructGraphInt:(PLAudioHost*)host;
00240 - (DoubleUnit)constructGraphDouble:(PLAudioHost*)host;
00241 - (void)hostStarting:(PLAudioHost*)host;
00242 - (void)hostStopped:(PLAudioHost*)host;
00243 @end
00244 
00245 
00252 @interface PLAudioHost : NSObject
00253 {
00254     void* peer;
00255     id<PLAudioHostDelegate> delegate;
00256     int type;
00257 }
00258 
00259 @property (nonatomic, assign) id delegate;                  
00260 @property (nonatomic, readonly) NSString* hostName;         
00261 @property (nonatomic, readonly) NSString* nativeHostName;   
00262 @property (nonatomic, readonly) NSString* inputName;        
00263 @property (nonatomic, readonly) NSString* outputName;       
00264 @property (nonatomic, readonly) double cpuUsage;            
00265 @property (nonatomic, readonly) BOOL isRunning;             
00266 @property (nonatomic, readonly) Dynamic outputUnit;         
00267 @property (nonatomic) int numInputs;                        
00268 @property (nonatomic) int numOutputs;                       
00269 @property (nonatomic) int preferredHostBlockSize;           
00270 @property (nonatomic) int preferredGraphBlockSize;          
00271 @property (nonatomic) double preferredHostSampleRate;       
00272 
00274 - (void)startHost;
00275 
00277 - (void)stopHost;
00278 
00279 @end
00280 
00281 BEGIN_PLONK_NAMESPACE
00282 
00283 template<class SampleType>
00284 class PortAudioAudioHostPeerBase : public PortAudioAudioHostBase<SampleType>
00285 {
00286 public:
00287     typedef typename PortAudioAudioHostBase<SampleType>::UnitType UnitType;
00288     
00289     PortAudioAudioHostPeerBase (PLAudioHost* p)
00290     :   peer (p)
00291     {
00292     }
00293     
00294     void hostStarting() throw()
00295     {
00296         if ([peer.delegate respondsToSelector:@selector(hostStarting:)])
00297             [peer.delegate hostStarting:peer];
00298     }
00299     
00300     void hostStopped() throw()
00301     {
00302         if ([peer.delegate respondsToSelector:@selector(hostStopped:)])
00303             [peer.delegate hostStopped:peer];
00304     }
00305         
00306     PLAudioHost* getPeer() const throw() { return peer; }
00307     
00308 private:
00309     PLAudioHost* peer; // no need to retain as the Obj-C peer owns this object
00310     
00311     PortAudioAudioHostPeerBase();
00312 };
00313 
00315 template<class SampleType>
00316 class PortAudioAudioHostPeer : public PortAudioAudioHostPeerBase<SampleType>
00317 {
00318 public:
00319     // pure virtual constructGraph not implemented to cause a compile-time error
00320     // only float, short, int and double sample types are supported
00321 };
00322 
00323 template<>
00324 class PortAudioAudioHostPeer<float> : public PortAudioAudioHostPeerBase<float>
00325 {
00326 public:
00327     PortAudioAudioHostPeer (PLAudioHost* peer)
00328     :   PortAudioAudioHostPeerBase<float> (peer)
00329     {
00330     }
00331     
00332     FloatUnit constructGraph() throw()
00333     {
00334         PLAudioHost* const peer = this->getPeer();
00335         plonk_assert (peer.delegate != nil);
00336         return [peer.delegate constructGraphFloat:peer];
00337     }
00338 };
00339 
00340 template<>
00341 class PortAudioAudioHostPeer<short> : public PortAudioAudioHostPeerBase<short>
00342 {
00343 public:
00344     PortAudioAudioHostPeer (PLAudioHost* peer)
00345     :   PortAudioAudioHostPeerBase<short> (peer)
00346     {
00347     }
00348     
00349     ShortUnit constructGraph() throw()
00350     {
00351         PLAudioHost* const peer = this->getPeer();
00352         plonk_assert (peer.delegate != nil);
00353         return [peer.delegate constructGraphShort:peer];
00354     }
00355 };
00356 
00357 template<>
00358 class PortAudioAudioHostPeer<int> : public PortAudioAudioHostPeerBase<int>
00359 {
00360 public:
00361     PortAudioAudioHostPeer (PLAudioHost* peer)
00362     :   PortAudioAudioHostPeerBase<int> (peer)
00363     {
00364     }
00365     
00366     IntUnit constructGraph() throw()
00367     {
00368         PLAudioHost* const peer = this->getPeer();
00369         plonk_assert (peer.delegate != nil);
00370         return [peer.delegate constructGraphInt:peer];
00371     }
00372 };
00373 
00374 template<>
00375 class PortAudioAudioHostPeer<double> : public PortAudioAudioHostPeerBase<double>
00376 {
00377 public:
00378     PortAudioAudioHostPeer (PLAudioHost* peer)
00379     :   PortAudioAudioHostPeerBase<double> (peer)
00380     {
00381     }
00382     
00383     DoubleUnit constructGraph() throw()
00384     {
00385         PLAudioHost* const peer = this->getPeer();
00386         plonk_assert (peer.delegate != nil);
00387         return [peer.delegate constructGraphInt:peer];
00388     }
00389 };
00390 
00391 #if PLONK_AUDIOHOST_PORTAUDIO_COMPILEOBJC
00392 
00393 END_PLONK_NAMESPACE
00394 
00395 using namespace plonk;
00396 
00397 @implementation PLAudioHost
00398 
00399 - (id)init
00400 {
00401     if (self = [super init])
00402     {
00403         peer = nil;
00404         type = TypeCode::Unknown;
00405     }
00406     
00407     return self;
00408 }
00409 
00410 - (void)dealloc
00411 {
00412     self.delegate = nil;
00413     
00414 #if !__has_feature(objc_arc)
00415     [super dealloc];
00416 #endif
00417 }
00418 
00419 - (NSString*)hostName
00420 {
00421     if (peer == nil) return @"";
00422     
00423     switch ((const int)type)
00424     {
00425         case TypeCode::Float:
00426             return [NSString stringWithUTF8String: static_cast< PortAudioAudioHostPeer<float>* > (peer)->getHostName().getArray()];
00427             
00428         case TypeCode::Short:
00429             return [NSString stringWithUTF8String: static_cast< PortAudioAudioHostPeer<short>* > (peer)->getHostName().getArray()];
00430             
00431         case TypeCode::Int:
00432             return [NSString stringWithUTF8String: static_cast< PortAudioAudioHostPeer<int>* > (peer)->getNativeHostName().getArray()];
00433             
00434         case TypeCode::Double:
00435             return [NSString stringWithUTF8String: static_cast< PortAudioAudioHostPeer<double>* > (peer)->getNativeHostName().getArray()];
00436             
00437         default:
00438             return @"";
00439     }
00440 }
00441 
00442 - (NSString*)nativeHostName
00443 {
00444     if (peer == nil) return @"";
00445     
00446     switch ((const int)type)
00447     {
00448         case TypeCode::Float:
00449             return [NSString stringWithUTF8String: static_cast< PortAudioAudioHostPeer<float>* > (peer)->getNativeHostName().getArray()];
00450             
00451         case TypeCode::Short:
00452             return [NSString stringWithUTF8String: static_cast< PortAudioAudioHostPeer<short>* > (peer)->getNativeHostName().getArray()];
00453             
00454         case TypeCode::Int:
00455             return [NSString stringWithUTF8String: static_cast< PortAudioAudioHostPeer<int>* > (peer)->getNativeHostName().getArray()];
00456             
00457         case TypeCode::Double:
00458             return [NSString stringWithUTF8String: static_cast< PortAudioAudioHostPeer<double>* > (peer)->getNativeHostName().getArray()];
00459             
00460         default:
00461             return @"";
00462     }
00463 }
00464 
00465 - (NSString*)inputName
00466 {
00467     if (peer == nil) return @"";
00468     
00469     switch ((const int)type)
00470     {
00471         case TypeCode::Float:
00472             return [NSString stringWithUTF8String: static_cast< PortAudioAudioHostPeer<float>* > (peer)->getInputName().getArray()];
00473             
00474         case TypeCode::Short:
00475             return [NSString stringWithUTF8String: static_cast< PortAudioAudioHostPeer<short>* > (peer)->getInputName().getArray()];
00476             
00477         case TypeCode::Int:
00478             return [NSString stringWithUTF8String: static_cast< PortAudioAudioHostPeer<int>* > (peer)->getInputName().getArray()];
00479             
00480         case TypeCode::Double:
00481             return [NSString stringWithUTF8String: static_cast< PortAudioAudioHostPeer<double>* > (peer)->getInputName().getArray()];
00482             
00483         default:
00484             return @"";
00485     }
00486 }
00487 
00488 - (NSString*)outputName
00489 {
00490     if (peer == nil) return @"";
00491     
00492     switch ((const int)type)
00493     {
00494         case TypeCode::Float:
00495             return [NSString stringWithUTF8String: static_cast< PortAudioAudioHostPeer<float>* > (peer)->getInputName().getArray()];
00496             
00497         case TypeCode::Short:
00498             return [NSString stringWithUTF8String: static_cast< PortAudioAudioHostPeer<short>* > (peer)->getInputName().getArray()];
00499             
00500         case TypeCode::Int:
00501             return [NSString stringWithUTF8String: static_cast< PortAudioAudioHostPeer<int>* > (peer)->getInputName().getArray()];
00502             
00503         case TypeCode::Double:
00504             return [NSString stringWithUTF8String: static_cast< PortAudioAudioHostPeer<double>* > (peer)->getInputName().getArray()];
00505             
00506         default:
00507             return @"";
00508     }
00509 }
00510 
00511 - (double)cpuUsage
00512 {
00513     if (peer == nil) return 0.0;
00514     
00515     switch ((const int)type)
00516     {
00517         case TypeCode::Float:   return static_cast< PortAudioAudioHostPeer<float>* > (peer)->getCpuUsage();
00518         case TypeCode::Short:   return static_cast< PortAudioAudioHostPeer<short>* > (peer)->getCpuUsage();
00519         case TypeCode::Int:     return static_cast< PortAudioAudioHostPeer<int>* > (peer)->getCpuUsage();
00520         case TypeCode::Double:  return static_cast< PortAudioAudioHostPeer<double>* > (peer)->getCpuUsage();
00521         default: return 0.0;
00522     }
00523 }
00524 
00525 - (BOOL)isRunning
00526 {
00527     if (peer == nil) return NO;
00528     
00529     switch ((const int)type)
00530     {
00531         case TypeCode::Float:   return static_cast< PortAudioAudioHostPeer<float>* > (peer)->getIsRunning() ? YES : NO;
00532         case TypeCode::Short:   return static_cast< PortAudioAudioHostPeer<short>* > (peer)->getIsRunning() ? YES : NO;
00533         case TypeCode::Int:     return static_cast< PortAudioAudioHostPeer<int>* > (peer)->getIsRunning() ? YES : NO;
00534         case TypeCode::Double:  return static_cast< PortAudioAudioHostPeer<double>* > (peer)->getIsRunning() ? YES : NO;
00535         default: return NO;
00536     }
00537 }
00538 
00539 - (BOOL)isPaused
00540 {
00541     if (peer == nil) return NO;
00542     
00543     switch ((const int)type)
00544     {
00545         case TypeCode::Float:   return static_cast< PortAudioAudioHostPeer<float>* > (peer)->getIsPaused() ? YES : NO;
00546         case TypeCode::Short:   return static_cast< PortAudioAudioHostPeer<short>* > (peer)->getIsPaused() ? YES : NO;
00547         case TypeCode::Int:     return static_cast< PortAudioAudioHostPeer<int>* > (peer)->getIsPaused() ? YES : NO;
00548         case TypeCode::Double:  return static_cast< PortAudioAudioHostPeer<double>* > (peer)->getIsPaused() ? YES : NO;
00549         default: return NO;
00550     }
00551 }
00552 
00553 - (Dynamic)outputUnit
00554 {
00555     Dynamic dyn;
00556     
00557     if (peer != nil)
00558     {
00559         switch ((const int)type)
00560         {
00561             case TypeCode::Float:   dyn = static_cast< PortAudioAudioHostPeer<float>* > (peer)->getOutputUnit(); break;
00562             case TypeCode::Short:   dyn = static_cast< PortAudioAudioHostPeer<short>* > (peer)->getOutputUnit(); break;
00563             case TypeCode::Int:     dyn = static_cast< PortAudioAudioHostPeer<int>* > (peer)->getOutputUnit(); break;
00564             case TypeCode::Double:  dyn = static_cast< PortAudioAudioHostPeer<double>* > (peer)->getOutputUnit(); break;
00565             default: { }
00566         }
00567     }
00568     
00569     return dyn;
00570 }
00571 
00572 - (int)numInputs
00573 {
00574     if (peer == nil) return 0;
00575     
00576     switch ((const int)type)
00577     {
00578         case TypeCode::Float:   return static_cast< PortAudioAudioHostPeer<float>* > (peer)->getNumInputs();
00579         case TypeCode::Short:   return static_cast< PortAudioAudioHostPeer<short>* > (peer)->getNumInputs();
00580         case TypeCode::Int:     return static_cast< PortAudioAudioHostPeer<int>* > (peer)->getNumInputs();
00581         case TypeCode::Double:  return static_cast< PortAudioAudioHostPeer<double>* > (peer)->getNumInputs();
00582         default: return 0.0;
00583     }
00584 }
00585 
00586 - (void)setNumInputs:(int)numInputs
00587 {
00588     if (peer == nil) return;
00589     
00590     switch ((const int)type)
00591     {
00592         case TypeCode::Float:   static_cast< PortAudioAudioHostPeer<float>* > (peer)->setNumInputs (numInputs); break;
00593         case TypeCode::Short:   static_cast< PortAudioAudioHostPeer<short>* > (peer)->setNumInputs (numInputs); break;
00594         case TypeCode::Int:     static_cast< PortAudioAudioHostPeer<int>* > (peer)->setNumInputs (numInputs); break;
00595         case TypeCode::Double:  static_cast< PortAudioAudioHostPeer<double>* > (peer)->setNumInputs (numInputs); break;
00596         default: { }
00597     }
00598 }
00599 
00600 - (int)numOutputs
00601 {
00602     if (peer == nil) return 0;
00603     
00604     switch ((const int)type)
00605     {
00606         case TypeCode::Float:   return static_cast< PortAudioAudioHostPeer<float>* > (peer)->getNumOutputs();
00607         case TypeCode::Short:   return static_cast< PortAudioAudioHostPeer<short>* > (peer)->getNumOutputs();
00608         case TypeCode::Int:     return static_cast< PortAudioAudioHostPeer<int>* > (peer)->getNumOutputs();
00609         case TypeCode::Double:  return static_cast< PortAudioAudioHostPeer<double>* > (peer)->getNumOutputs();
00610         default: return 0.0;
00611     }
00612 }
00613 
00614 - (void)setNumOutputs:(int)numOutputs
00615 {
00616     if (peer == nil) return;
00617     
00618     switch ((const int)type)
00619     {
00620         case TypeCode::Float:   static_cast< PortAudioAudioHostPeer<float>* > (peer)->setNumOutputs (numOutputs); break;
00621         case TypeCode::Short:   static_cast< PortAudioAudioHostPeer<short>* > (peer)->setNumOutputs (numOutputs); break;
00622         case TypeCode::Int:     static_cast< PortAudioAudioHostPeer<int>* > (peer)->setNumOutputs (numOutputs); break;
00623         case TypeCode::Double:  static_cast< PortAudioAudioHostPeer<double>* > (peer)->setNumOutputs (numOutputs); break;
00624         default: { }
00625     }
00626 }
00627 
00628 - (int)preferredHostBlockSize
00629 {
00630     if (peer == nil) return 0;
00631     
00632     switch ((const int)type)
00633     {
00634         case TypeCode::Float:   return static_cast< PortAudioAudioHostPeer<float>* > (peer)->getPreferredHostBlockSize();
00635         case TypeCode::Short:   return static_cast< PortAudioAudioHostPeer<short>* > (peer)->getPreferredHostBlockSize();
00636         case TypeCode::Int:     return static_cast< PortAudioAudioHostPeer<int>* > (peer)->getPreferredHostBlockSize();
00637         case TypeCode::Double:  return static_cast< PortAudioAudioHostPeer<double>* > (peer)->getPreferredHostBlockSize();
00638         default: return 0;
00639     }
00640 }
00641 
00642 - (void)setPreferredHostBlockSize:(int)preferredHostBlockSize
00643 {
00644     if (peer == nil) return;
00645     
00646     switch ((const int)type)
00647     {
00648         case TypeCode::Float:   static_cast< PortAudioAudioHostPeer<float>* > (peer)->setPreferredHostBlockSize (preferredHostBlockSize); break;
00649         case TypeCode::Short:   static_cast< PortAudioAudioHostPeer<short>* > (peer)->setPreferredHostBlockSize (preferredHostBlockSize); break;
00650         case TypeCode::Int:     static_cast< PortAudioAudioHostPeer<int>* > (peer)->setPreferredHostBlockSize (preferredHostBlockSize); break;
00651         case TypeCode::Double:  static_cast< PortAudioAudioHostPeer<double>* > (peer)->setPreferredHostBlockSize (preferredHostBlockSize); break;
00652         default: { }
00653     }
00654 }
00655 
00656 - (int)preferredGraphBlockSize
00657 {
00658     if (peer == nil) return 0;
00659     
00660     switch ((const int)type)
00661     {
00662         case TypeCode::Float:   return static_cast< PortAudioAudioHostPeer<float>* > (peer)->getPreferredGraphBlockSize();
00663         case TypeCode::Short:   return static_cast< PortAudioAudioHostPeer<short>* > (peer)->getPreferredGraphBlockSize();
00664         case TypeCode::Int:     return static_cast< PortAudioAudioHostPeer<int>* > (peer)->getPreferredGraphBlockSize();
00665         case TypeCode::Double:  return static_cast< PortAudioAudioHostPeer<double>* > (peer)->getPreferredGraphBlockSize();
00666         default: return 0;
00667     }
00668 }
00669 
00670 - (void)setPreferredGraphBlockSize:(int)preferredGraphBlockSize
00671 {
00672     if (peer == nil) return;
00673     
00674     switch ((const int)type)
00675     {
00676         case TypeCode::Float:   static_cast< PortAudioAudioHostPeer<float>* > (peer)->setPreferredGraphBlockSize (preferredGraphBlockSize); break;
00677         case TypeCode::Short:   static_cast< PortAudioAudioHostPeer<short>* > (peer)->setPreferredGraphBlockSize (preferredGraphBlockSize); break;
00678         case TypeCode::Int:     static_cast< PortAudioAudioHostPeer<int>* > (peer)->setPreferredGraphBlockSize (preferredGraphBlockSize); break;
00679         case TypeCode::Double:  static_cast< PortAudioAudioHostPeer<double>* > (peer)->setPreferredGraphBlockSize (preferredGraphBlockSize); break;
00680         default: { }
00681     }
00682 }
00683 
00684 - (double)preferredHostSampleRate
00685 {
00686     if (peer == nil) return 0.0;
00687     
00688     switch ((const int)type)
00689     {
00690         case TypeCode::Float:   return static_cast< PortAudioAudioHostPeer<float>* > (peer)->getPreferredHostSampleRate();
00691         case TypeCode::Short:   return static_cast< PortAudioAudioHostPeer<short>* > (peer)->getPreferredHostSampleRate();
00692         case TypeCode::Int:     return static_cast< PortAudioAudioHostPeer<int>* > (peer)->getPreferredHostSampleRate();
00693         case TypeCode::Double:  return static_cast< PortAudioAudioHostPeer<double>* > (peer)->getPreferredHostSampleRate();
00694         default: return 0.0;
00695     }
00696 }
00697 
00698 - (void)setPreferredHostSampleRate:(double)preferredHostSampleRate
00699 {
00700     if (peer == nil) return;
00701     
00702     switch ((const int)type)
00703     {
00704         case TypeCode::Float:   static_cast< PortAudioAudioHostPeer<float>* > (peer)->setPreferredHostSampleRate (preferredHostSampleRate); break;
00705         case TypeCode::Short:   static_cast< PortAudioAudioHostPeer<short>* > (peer)->setPreferredHostSampleRate (preferredHostSampleRate); break;
00706         case TypeCode::Int:     static_cast< PortAudioAudioHostPeer<int>* > (peer)->setPreferredHostSampleRate (preferredHostSampleRate); break;
00707         case TypeCode::Double:  static_cast< PortAudioAudioHostPeer<double>* > (peer)->setPreferredHostSampleRate (preferredHostSampleRate); break;
00708         default: { }
00709     }
00710 }
00711 
00712 - (void)startHost
00713 {
00714     if (peer == nil) return;
00715     
00716     switch ((const int)type)
00717     {
00718         case TypeCode::Float:   static_cast< PortAudioAudioHostPeer<float>* > (peer)->startHost(); break;
00719         case TypeCode::Short:   static_cast< PortAudioAudioHostPeer<short>* > (peer)->startHost(); break;
00720         case TypeCode::Int:     static_cast< PortAudioAudioHostPeer<int>* > (peer)->startHost(); break;
00721         case TypeCode::Double:  static_cast< PortAudioAudioHostPeer<double>* > (peer)->startHost(); break;
00722         default: { }
00723     }
00724 }
00725 
00726 - (void)stopHost
00727 {
00728     if (peer == nil) return;
00729     
00730     switch ((const int)type)
00731     {
00732         case TypeCode::Float:   static_cast< PortAudioAudioHostPeer<float>* > (peer)->stopHost(); break;
00733         case TypeCode::Short:   static_cast< PortAudioAudioHostPeer<short>* > (peer)->stopHost(); break;
00734         case TypeCode::Int:     static_cast< PortAudioAudioHostPeer<int>* > (peer)->stopHost(); break;
00735         case TypeCode::Double:  static_cast< PortAudioAudioHostPeer<double>* > (peer)->stopHost(); break;
00736         default: { }
00737     }
00738 }
00739 
00740 - (id)delegate
00741 {
00742     return delegate;
00743 }
00744 
00745 - (void)deletePeer
00746 {
00747     switch ((const int)type)
00748     {
00749         case TypeCode::Float:   delete static_cast< PortAudioAudioHostPeer<float>* > (peer);   break;
00750         case TypeCode::Short:   delete static_cast< PortAudioAudioHostPeer<short>* > (peer);   break;
00751         case TypeCode::Int:     delete static_cast< PortAudioAudioHostPeer<int>* > (peer);     break;
00752         case TypeCode::Double:  delete static_cast< PortAudioAudioHostPeer<double>* > (peer);  break;
00753         default: { }
00754     }
00755     
00756     peer = nil;
00757     type = TypeCode::Unknown;
00758 }
00759 
00760 - (void)setDelegate:(id)newDelegate
00761 {
00762     plonk_assert (delegate == nil || newDelegate == nil);
00763     
00764     [self deletePeer];
00765     
00766     delegate = newDelegate;
00767     
00768     if (delegate)
00769     {
00770         const unsigned int isFloat = [delegate respondsToSelector:@selector(constructGraphFloat:)] ? (1 << TypeCode::Float) : 0;
00771         const unsigned int isShort = [delegate respondsToSelector:@selector(constructGraphShort:)] ? (1 << TypeCode::Short) : 0;
00772         const unsigned int isInt = [delegate respondsToSelector:@selector(constructGraphInt:)] ? (1 << TypeCode::Int) : 0;
00773         const unsigned int isDouble = [delegate respondsToSelector:@selector(constructGraphDouble:)] ? (1 << TypeCode::Double) : 0;
00774         const unsigned int typeFlags = isFloat | isShort | isInt | isDouble;
00775         
00776         if (typeFlags != 0 && Bits::isPowerOf2 (typeFlags))
00777         {
00778             type = Bits::countTrailingZeroes (typeFlags);
00779             
00780             switch ((const int)type)
00781             {
00782                 case TypeCode::Float:   peer = new PortAudioAudioHostPeer<float> (self);   break;
00783                 case TypeCode::Short:   peer = new PortAudioAudioHostPeer<short> (self);   break;
00784                 case TypeCode::Int:     peer = new PortAudioAudioHostPeer<int> (self);     break;
00785                 case TypeCode::Double:  peer = new PortAudioAudioHostPeer<double> (self);  break;
00786                     
00787                 default:
00788                     peer = nil;
00789                     type = 0;
00790             }
00791         }
00792         else plonk_assertfalse; // either none or more than one constructGraph.. function was implemented
00793     }
00794 }
00795 
00796 @end
00797 
00798 BEGIN_PLONK_NAMESPACE
00799 #endif
00800 
00801 #endif
00802 
00803 
00804 #endif // PLANK_INLINING_FUNCTIONS
00805 
 All Classes Functions Typedefs Enumerations Enumerator Properties