/[svn]/linuxsampler/trunk/src/drivers/audio/AudioOutputDeviceAsio.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/drivers/audio/AudioOutputDeviceAsio.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1947 by persson, Sun May 3 12:15:40 2009 UTC revision 1948 by persson, Sun Jul 19 11:12:13 2009 UTC
# Line 28  Line 28 
28  #define kMaxOutputChannels 32  #define kMaxOutputChannels 32
29  #define ASIO_MAX_DEVICE_INFO 32  #define ASIO_MAX_DEVICE_INFO 32
30    
31  #define NUM_STANDARDSAMPLINGRATES   3   /* 11.025, 22.05, 44.1 */  #define NUM_STANDARDSAMPLINGRATES 3  // 11.025, 22.05, 44.1
32  #define NUM_CUSTOMSAMPLINGRATES     9   /* must be the same number of elements as in the array below */  #define NUM_CUSTOMSAMPLINGRATES   9  // must be the same number of elements as in the array below
33  #define MAX_NUMSAMPLINGRATES  (NUM_STANDARDSAMPLINGRATES+NUM_CUSTOMSAMPLINGRATES)  #define MAX_NUMSAMPLINGRATES  (NUM_STANDARDSAMPLINGRATES + NUM_CUSTOMSAMPLINGRATES)
34    
35  // internal data storage  // internal data storage
36  typedef struct DriverInfo  struct DriverInfo {
 {  
37      // ASIOInit()      // ASIOInit()
38      ASIODriverInfo driverInfo;      ASIODriverInfo driverInfo;
39    
# Line 51  typedef struct DriverInfo Line 50  typedef struct DriverInfo
50    
51      // ASIOGetSampleRate()      // ASIOGetSampleRate()
52      ASIOSampleRate sampleRate;      ASIOSampleRate sampleRate;
53      int numSampleRates;      int            numSampleRates;
54      std::vector<int> sampleRates;      std::vector<int> sampleRates;
55    
56      // ASIOOutputReady()      // ASIOOutputReady()
# Line 62  typedef struct DriverInfo Line 61  typedef struct DriverInfo
61      long           outputLatency;      long           outputLatency;
62    
63      // ASIOCreateBuffers ()      // ASIOCreateBuffers ()
64      long numInputBuffers;       // becomes number of actual created input buffers      long           numInputBuffers;  // becomes number of actual created input buffers
65      long numOutputBuffers;      // becomes number of actual created output buffers      long           numOutputBuffers; // becomes number of actual created output buffers
66      ASIOBufferInfo bufferInfos[kMaxInputChannels + kMaxOutputChannels]; // buffer info's      ASIOBufferInfo bufferInfos[kMaxInputChannels + kMaxOutputChannels];
67    
68      // ASIOGetChannelInfo()      // ASIOGetChannelInfo()
69      ASIOChannelInfo channelInfos[kMaxInputChannels + kMaxOutputChannels]; // channel info's      ASIOChannelInfo channelInfos[kMaxInputChannels + kMaxOutputChannels];
70      // The above two arrays share the same indexing, as the data in them are linked together      // The above two arrays share the same indexing, as the data in them are linked together
71    
72      // Information from ASIOGetSamplePosition()      // Information from ASIOGetSamplePosition()
73      // data is converted to double floats for easier use, however 64 bit integer can be used, too      // data is converted to double floats for easier use, however 64 bit integer can be used, too
74      double         nanoSeconds;      double         nanoSeconds;
75      double         samples;      double         samples;
76      double         tcSamples;   // time code samples      double         tcSamples;   // time code samples
77    
78      // bufferSwitchTimeInfo()      // bufferSwitchTimeInfo()
79      ASIOTime       tInfo;                       // time info state      ASIOTime       tInfo;       // time info state
80      unsigned long  sysRefTime;      // system reference time, when bufferSwitch() was called      unsigned long  sysRefTime;  // system reference time, when bufferSwitch() was called
81    
82      // Signal the end of processing in this example      // Signal the end of processing in this example
83      bool           stopped;      bool           stopped;
84  } DriverInfo;  };
85    
86  extern AsioDrivers* asioDrivers;  extern AsioDrivers* asioDrivers;
87  extern bool loadAsioDriver(char *name);  extern bool loadAsioDriver(char* name);
88    
89  static ASIODriverInfo MyAsioDriverInfo;  static ASIODriverInfo MyAsioDriverInfo;
90  static DriverInfo asioDriverInfo = {0};  static DriverInfo asioDriverInfo = { { 0 }, 0 };
91    
92  static bool asioDriverOpened = false;  static bool asioDriverOpened = false;
93  static bool AudioOutputDeviceAsioInstantiated = false;  static bool AudioOutputDeviceAsioInstantiated = false;
# Line 100  namespace LinuxSampler { Line 100  namespace LinuxSampler {
100  // callback prototypes  // callback prototypes
101    
102  ASIOCallbacks asioCallbacks;  ASIOCallbacks asioCallbacks;
103  ASIOBufferInfo bufferInfos[2];  AudioOutputDeviceAsio* GlobalAudioOutputDeviceAsioThisPtr;
 AudioOutputDeviceAsio *GlobalAudioOutputDeviceAsioThisPtr;  
104    
105  template<int bitres>  template<int bitres>
106  static void floatToASIOSTInt32LSBXX(float *in, void *dest, int numSamples) {  static void floatToASIOSTInt32LSBXX(float* in, void* dest, int numSamples) {
107      double pos_max_value = (1 << bitres) -1.0;      double pos_max_value = (1 << bitres) -1.0;
108      double neg_max_value = -pos_max_value;      double neg_max_value = -pos_max_value;
109      int32_t *out = (int32_t *)dest;      int32_t* out = (int32_t*)dest;
110      for(int i=0; i < numSamples ; i++) {      for (int i = 0; i < numSamples ; i++) {
111          double sample_point = in[i] * pos_max_value;          double sample_point = in[i] * pos_max_value;
112          if (sample_point < neg_max_value) sample_point = neg_max_value;          if (sample_point < neg_max_value) sample_point = neg_max_value;
113          if (sample_point >  pos_max_value) sample_point =  pos_max_value;          if (sample_point >  pos_max_value) sample_point =  pos_max_value;
# Line 116  static void floatToASIOSTInt32LSBXX(floa Line 115  static void floatToASIOSTInt32LSBXX(floa
115      }      }
116  }  }
117    
118  static void floatToASIOSTInt16LSB(float *in, void *dest, int numSamples) {  static void floatToASIOSTInt16LSB(float* in, void* dest, int numSamples) {
119      int16_t *out = (int16_t *)dest;      int16_t* out = (int16_t*)dest;
120      for(int i=0; i < numSamples ; i++) {      for (int i = 0; i < numSamples ; i++) {
121          float sample_point = in[i] * 32768.0f;          float sample_point = in[i] * 32768.0f;
122          if (sample_point < -32768.0) sample_point = -32768.0;          if (sample_point < -32768.0) sample_point = -32768.0;
123          if (sample_point >  32767.0) sample_point =  32767.0;          if (sample_point >  32767.0) sample_point =  32767.0;
# Line 126  static void floatToASIOSTInt16LSB(float Line 125  static void floatToASIOSTInt16LSB(float
125      }      }
126  }  }
127    
128  static void floatToASIOSTInt32LSB(float *in, void *dest, int numSamples) {  static void floatToASIOSTInt32LSB(float* in, void* dest, int numSamples) {
129      int32_t *out = (int32_t *)dest;      int32_t* out = (int32_t*)dest;
130      for(int i=0; i < numSamples ; i++) {      for (int i = 0; i < numSamples ; i++) {
131          double sample_point = in[i] * 2147483648.0;          double sample_point = in[i] * 2147483648.0;
132          if (sample_point < - 2147483648.0) sample_point = -2147483648.0;          if (sample_point < - 2147483648.0) sample_point = -2147483648.0;
133          if (sample_point >  2147483647.0) sample_point =  2147483647.0;          if (sample_point >  2147483647.0) sample_point =  2147483647.0;
# Line 138  static void floatToASIOSTInt32LSB(float Line 137  static void floatToASIOSTInt32LSB(float
137    
138  std::vector<String> getAsioDriverNames();  std::vector<String> getAsioDriverNames();
139    
140  static bool ASIO_loadAsioDriver(const char *name)  static bool ASIO_loadAsioDriver(const char* name) {
141  {      dmsg(2,("ASIO_loadAsioDriver: trying to load '%s'\n", name));
142      dmsg(2,("ASIO_loadAsioDriver: trying to load '%s'\n",name));  #ifdef  WINDOWS
143          #ifdef  WINDOWS      CoInitialize(0);
144                  CoInitialize(0);  #endif
145          #endif      return loadAsioDriver(const_cast<char*>(name));
146                  return loadAsioDriver(const_cast<char*>(name));  }
147  }  
148    void ASIO_OpenAndQueryDeviceInfo(String driverName, DriverInfo* driverInfo,
149  int ASIO_OpenAndQueryDeviceInfo(char *driverName, DriverInfo *driverInfo, ASIODriverInfo *asioDriverInfo)                                   ASIODriverInfo* asioDriverInfo) throw (AudioOutputException) {
150  {      static const char* errmsg = "Error: ASIO Initalization Error";
151      ASIOSampleRate possibleSampleRates[]  
152          = {8000.0, 9600.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0, 44100.0, 48000.0, 88200.0, 96000.0};      ASIOSampleRate possibleSampleRates[] =
153            { 8000.0, 9600.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0,
154      ASIOChannelInfo channelInfos;            32000.0, 44100.0, 48000.0, 88200.0, 96000.0 };
155      ASIOError     asioError;  
156        ASIOError asioError;
157      // call this function in order to fill the internal vector containing the list of ASIO cards  
158      // since the reading of the list is performed only one time subsequent calls to this function will be automatically ignored      // Call this function in order to fill the internal vector
159      // calling getAsioDriverNames() is needed in the case of a LinuxSampler client application first creating an ASIO device      // containing the list of ASIO cards.
160      // which calls ASIO_OpenAndQueryDeviceInfo() and afterwards retrieve the list of available ASIO cards  
161      // since getAsioDriverNames() unloads the current driver and loads the driver 'dummy' this would cause      // Since the reading of the list is performed only one time,
162      // the audio stopping and forcing the create the audio output device again      // subsequent calls to this function will be automatically
163        // ignored.
164    
165        // Calling getAsioDriverNames() is needed in the case of a
166        // LinuxSampler client application first creating an ASIO device,
167        // which calls ASIO_OpenAndQueryDeviceInfo(), and afterwards
168        // retrieve the list of available ASIO cards, since
169        // getAsioDriverNames() unloads the current driver and loads the
170        // driver 'dummy' this would cause the audio stopping and forcing
171        // the create the audio output device again.
172      getAsioDriverNames();      getAsioDriverNames();
173    
174      dmsg(2,("ASIO_OpenAndQueryDeviceInfo driverName='%s' current='%s'\n",driverName, currentAsioDriverName.c_str() ));      dmsg(2,("ASIO_OpenAndQueryDeviceInfo driverName='%s' current='%s'\n",
175      if(!strcmp(driverName, currentAsioDriverName.c_str() )) {              driverName.c_str(), currentAsioDriverName.c_str()));
176          // if the given ASIO driver name == current ASIO driver name and the driver      if (driverName == currentAsioDriverName) {
177          // was already opened then do nothing          // if the given ASIO driver name == current ASIO driver name
178          if(asioDriverOpened) {          // and the driver was already opened then do nothing
179            if (asioDriverOpened) {
180              dmsg(2,("asioDriver ALREADY OPENED, DOING NOTHING !\n"));              dmsg(2,("asioDriver ALREADY OPENED, DOING NOTHING !\n"));
181              return 0;              return;
182          }          }
183      }      }
184      else {      else {
185      dmsg(2,("driverName != currentAsioDriverName , new asio driver specified, opening device ....\n"));          dmsg(2,("driverName != currentAsioDriverName, new asio driver specified, opening device ....\n"));
186          // if a new ASIO driver name was specified then first check if we need to close          // if a new ASIO driver name was specified then first check if
187          // the old one          // we need to close the old one
188          if(asioDriverOpened) {          if (asioDriverOpened) {
189              dmsg(2,("different asioDriver ALREADY OPENED, closing old one !\n"));              dmsg(2,("different asioDriver ALREADY OPENED, closing old one !\n"));
190              asioDriverOpened = false;              asioDriverOpened = false;
191              ASIOExit(); // close the old ASIO driver              ASIOExit(); // close the old ASIO driver
# Line 184  int ASIO_OpenAndQueryDeviceInfo(char *dr Line 193  int ASIO_OpenAndQueryDeviceInfo(char *dr
193      }      }
194      currentAsioDriverName = driverName;      currentAsioDriverName = driverName;
195    
196          memset((void *)asioDriverInfo,0,sizeof(ASIODriverInfo));      memset((void*)asioDriverInfo, 0, sizeof(ASIODriverInfo));
197      asioDriverInfo->asioVersion=1;      asioDriverInfo->asioVersion = 1;
198      asioDriverInfo->sysRef = NULL;      asioDriverInfo->sysRef = NULL;
199    
200      /* MUST BE CHECKED : to force fragments loading on Mac */      // MUST BE CHECKED : to force fragments loading on Mac
201      //ASIO_loadAsioDriver("dummy");      // ASIO_loadAsioDriver("dummy");
202    
203      dmsg(2,("Before ASIO_loadAsioDriver('%s')\n",driverName));      dmsg(2,("Before ASIO_loadAsioDriver('%s')\n", driverName.c_str()));
204      if ( !ASIO_loadAsioDriver(driverName) ) {      if (!ASIO_loadAsioDriver(driverName.c_str())) {
205          dmsg(2,("ASIO_OpenAndQueryDeviceInfo could not loadAsioDriver %s\n", driverName));          dmsg(2,("ASIO_OpenAndQueryDeviceInfo could not loadAsioDriver %s\n", driverName.c_str()));
206          return -1;          throw AudioOutputException(errmsg);
207      }      }
208      dmsg(2,("Before ASIOInit()\n"));      dmsg(2,("Before ASIOInit()\n"));
209      if( (asioError = ASIOInit(asioDriverInfo)) != ASE_OK ) {      if ((asioError = ASIOInit(asioDriverInfo)) != ASE_OK) {
210          dmsg(2,("ASIO_OpenAndQueryDeviceInfo: ASIOInit returned %d for %s\n", asioError, driverName));          dmsg(1,("ASIO_OpenAndQueryDeviceInfo: ASIOInit returned %d for %s\n",
211          return asioError;                  int(asioError), driverName.c_str()));
212            throw AudioOutputException(errmsg);
213      }      }
214      dmsg(2,("Before ASIOGetChannels()\n"));      dmsg(2,("Before ASIOGetChannels()\n"));
215      if( (asioError = ASIOGetChannels(&driverInfo->numInputChannels, &driverInfo->numOutputChannels) != ASE_OK)) {      if ((asioError = ASIOGetChannels(&driverInfo->numInputChannels,
216          dmsg(2,("ASIO_OpenAndQueryDeviceInfo could not ASIOGetChannels for %s\n", driverName));                                       &driverInfo->numOutputChannels)) != ASE_OK) {
217          return asioError;          dmsg(1,("ASIO_OpenAndQueryDeviceInfo could not ASIOGetChannels for %s: %d\n",
218                    driverName.c_str(), int(asioError)));
219            throw AudioOutputException(errmsg);
220      }      }
221    
222      dmsg(2,("Before ASIOGetBufferSize()\n"));      dmsg(2,("Before ASIOGetBufferSize()\n"));
223      if( (asioError = ASIOGetBufferSize(&driverInfo->minBufSize,&driverInfo->maxBufSize,&driverInfo->preferredBufSize,&driverInfo->bufGranularity) != ASE_OK)) {      if ((asioError = ASIOGetBufferSize(&driverInfo->minBufSize,
224          dmsg(2,("ASIO_OpenAndQueryDeviceInfo could not ASIOGetBufferSize for %s\n", driverName));                                         &driverInfo->maxBufSize,
225          return asioError;                                         &driverInfo->preferredBufSize,
226                                           &driverInfo->bufGranularity)) != ASE_OK) {
227            dmsg(1,("ASIO_OpenAndQueryDeviceInfo could not ASIOGetBufferSize for %s: %d\n",
228                    driverName.c_str(), int(asioError)));
229            throw AudioOutputException(errmsg);
230      }      }
231    
232      dmsg(2,("ASIO_OpenAndQueryDeviceInfo: InputChannels = %d\n", driverInfo->numInputChannels ));      dmsg(2,("ASIO_OpenAndQueryDeviceInfo: InputChannels = %ld\n", driverInfo->numInputChannels));
233      dmsg(2,("ASIO_OpenAndQueryDeviceInfo: OutputChannels = %d\n", driverInfo->numOutputChannels ));      dmsg(2,("ASIO_OpenAndQueryDeviceInfo: OutputChannels = %ld\n", driverInfo->numOutputChannels));
234    
235      /* Loop through the possible sampling rates and check each to see if the device supports it. */      // Loop through the possible sampling rates and check each to see
236        // if the device supports it.
237      driverInfo->numSampleRates = 0;      driverInfo->numSampleRates = 0;
238      driverInfo->sampleRates.clear();      driverInfo->sampleRates.clear();
239      for (int index = 0; index < MAX_NUMSAMPLINGRATES; index++) {      for (int index = 0; index < MAX_NUMSAMPLINGRATES; index++) {
240          if (ASIOCanSampleRate(possibleSampleRates[index]) != ASE_NoClock) {          if (ASIOCanSampleRate(possibleSampleRates[index]) != ASE_NoClock) {
241              dmsg(2,("ASIOCanSampleRate: possible sample rate = %d\n", (long)possibleSampleRates[index]));              dmsg(2,("ASIOCanSampleRate: possible sample rate = %ld\n",
242              driverInfo->sampleRates.push_back( (int)possibleSampleRates[index] );                      (long)possibleSampleRates[index]));
243                driverInfo->sampleRates.push_back((int)possibleSampleRates[index]);
244              driverInfo->numSampleRates++;              driverInfo->numSampleRates++;
245          }          }
246      }      }
247    
248      /* get the channel infos for each output channel (including sample format)  */      // get the channel infos for each output channel (including sample format)
249      for(int i=0 ; i < driverInfo->numOutputChannels ; i++) {      for (int i = 0; i < driverInfo->numOutputChannels; i++) {
250          driverInfo->channelInfos[i].channel = i;          driverInfo->channelInfos[i].channel = i;
251          driverInfo->channelInfos[i].isInput = ASIOFalse;          driverInfo->channelInfos[i].isInput = ASIOFalse;
252          ASIOGetChannelInfo(&driverInfo->channelInfos[i]);          ASIOGetChannelInfo(&driverInfo->channelInfos[i]);
253          dmsg(2,("channelInfos[%d].type (sampleformat) = %d\n", i, driverInfo->channelInfos[i].type));          dmsg(2,("channelInfos[%d].type (sampleformat) = %d\n",
254                    i, int(driverInfo->channelInfos[i].type)));
255      }      }
256    
257      dmsg(2,("ASIO_OpenAndQueryDeviceInfo: driver opened.\n"));      dmsg(2,("ASIO_OpenAndQueryDeviceInfo: driver opened.\n"));
258      asioDriverOpened = true;      asioDriverOpened = true;
     return ASE_OK;  
259  }  }
260    
261    
262  std::vector<String> getAsioDriverNames() {  std::vector<String> getAsioDriverNames() {
   
263      char* names[ASIO_MAX_DEVICE_INFO];      char* names[ASIO_MAX_DEVICE_INFO];
264      int numDrivers;      int numDrivers;
265    
266      if(asioDriverListLoaded) {      if (asioDriverListLoaded) {
267          dmsg(2,("getAsioDriverNames: ASIO driver list already loaded, doing returning cached list.\n"));          dmsg(2,("getAsioDriverNames: ASIO driver list already loaded, doing returning cached list.\n"));
268          return asioDriverList;          return asioDriverList;
269      }      }
270    
271      /* MUST BE CHECKED : to force fragments loading on Mac */      // MUST BE CHECKED : to force fragments loading on Mac
272      ASIO_loadAsioDriver("dummy");      ASIO_loadAsioDriver("dummy");
273    
274      #if MAC  #if MAC
275      numDrivers = asioDrivers->getNumFragments();      numDrivers = asioDrivers->getNumFragments();
276      #elif WINDOWS  #elif WINDOWS
277      numDrivers = asioDrivers->asioGetNumDev();      numDrivers = asioDrivers->asioGetNumDev();
278      #endif  #endif
279    
280      for (int i = 0 ; i < ASIO_MAX_DEVICE_INFO ; i++) {      for (int i = 0; i < ASIO_MAX_DEVICE_INFO; i++) {
281          names[i] = new char[32];          names[i] = new char[32];
282          memset(names[i],0,32);          memset(names[i], 0, 32);
283      }      }
284    
285      /* Get names of all available ASIO drivers */      // Get names of all available ASIO drivers
286      asioDrivers->getDriverNames(names,ASIO_MAX_DEVICE_INFO);      asioDrivers->getDriverNames(names, ASIO_MAX_DEVICE_INFO);
287      dmsg(2,("getAsioDriverNames: numDrivers=%d\n",numDrivers));      dmsg(2,("getAsioDriverNames: numDrivers=%d\n", numDrivers));
288    
289      for (int i = 0 ; i < numDrivers ; i++) {      for (int i = 0; i < numDrivers; i++) {
290          dmsg(2,("ASIO DRIVERLIST: i=%d  name='%s'\n",i,names[i]));          dmsg(2,("ASIO DRIVERLIST: i=%d  name='%s'\n", i, names[i]));
291    
292          #if 1  #if 1
293          asioDriverList.push_back(names[i]);          asioDriverList.push_back(names[i]);
294          #else  #else
295          int asioError;          int asioError;
296          //  FIXME: we currently try what is the best methode to exclude not connected devices or not working drivers          // FIXME: We currently try what is the best method to exclude
297          // the code below is for testing only, it tried to load each ASIO driver and if it gives an error it is not included          // not connected devices or not working drivers. The code
298          // in the list of available drivers (asioDriverList)          // below is for testing only, it tries to load each ASIO
299          if ( ASIO_loadAsioDriver(names[i]) ) {          // driver and if it gives an error it is not included in the
300              if( (asioError = ASIOInit(&MyAsioDriverInfo)) == ASE_OK ) {          // list of available drivers (asioDriverList).
301            if (ASIO_loadAsioDriver(names[i])) {
302                if ((asioError = ASIOInit(&MyAsioDriverInfo)) == ASE_OK) {
303                  asioDriverList.push_back(names[i]);                  asioDriverList.push_back(names[i]);
304              }              }
305              else {              else {
306                  dmsg(2,("getDriverList: ASIOInit of driver %s gave Error %d ! ignoring it.\n", names[i],asioError));                  dmsg(2,("getDriverList: ASIOInit of driver %s gave Error %d! ignoring it.\n",
307                            names[i], asioError));
308              }              }
309          }          }
310          else {          else {
311              dmsg(2,("getDriverList: load  driver %s failed! ignoring it.\n", names[i]));              dmsg(2,("getDriverList: load  driver %s failed! ignoring it.\n", names[i]));
312          }          }
313          // FIXME: we need to check this ASIOExit is needed (gave a crash on a ASIO ADSP24(WDM) card so we commented it out)          // FIXME: we need to check this ASIOExit is needed (gave a
314          //ASIOExit();          // crash on a ASIO ADSP24(WDM) card so we commented it out)
315          #endif          // ASIOExit();
316          //currentAsioDriverName="";  #endif
317            //currentAsioDriverName = "";
318      }      }
319    
320      for (int i = 0 ; i < ASIO_MAX_DEVICE_INFO ; i++) {      for (int i = 0; i < ASIO_MAX_DEVICE_INFO; i++) {
321          delete[] names[i];          delete[] names[i];
322      }      }
323    
324          dmsg(2,("getAsioDriverNames: returing from function. asioDriverList.size()=%d\n", asioDriverList.size() ));      dmsg(2,("getAsioDriverNames: returing from function. asioDriverList.size()=%d\n",
325                int(asioDriverList.size())));
326      asioDriverListLoaded = true;      asioDriverListLoaded = true;
327          return asioDriverList;      return asioDriverList;
328  }  }
329    
330  unsigned long get_sys_reference_time()  // currently not unsed
331  {  unsigned long get_sys_reference_time() {
332          // get the system reference time      // get the system reference time
333          #if WINDOWS  #if WINDOWS
334                  return timeGetTime();      return timeGetTime();
335          #elif MAC  #elif MAC
336                  static const double twoRaisedTo32 = 4294967296.;      static const double twoRaisedTo32 = 4294967296.;
337                  UnsignedWide ys;      UnsignedWide ys;
338                  Microseconds(&ys);      Microseconds(&ys);
339                  double r = ((double)ys.hi * twoRaisedTo32 + (double)ys.lo);      double r = ((double)ys.hi * twoRaisedTo32 + (double)ys.lo);
340                  return (unsigned long)(r / 1000.);      return (unsigned long)(r / 1000.);
341          #endif  #endif
342  }  }
343    
344    
345  //----------------------------------------------------------------------------------  //----------------------------------------------------------------------------------
346  // conversion from 64 bit ASIOSample/ASIOTimeStamp to double float  // conversion from 64 bit ASIOSample/ASIOTimeStamp to double float
347  #if NATIVE_INT64  #if NATIVE_INT64
348          #define ASIO64toDouble(a)  (a)  #define ASIO64toDouble(a)  (a)
349  #else  #else
350          const double twoRaisedTo32 = 4294967296.;  const double twoRaisedTo32 = 4294967296.;
351          #define ASIO64toDouble(a)  ((a).lo + (a).hi * twoRaisedTo32)  #define ASIO64toDouble(a)  ((a).lo + (a).hi * twoRaisedTo32)
352  #endif  #endif
353    
354    
355  ASIOTime* AudioOutputDeviceAsio::bufferSwitchTimeInfo(ASIOTime *timeInfo, long index, ASIOBool processNow)  ASIOTime* AudioOutputDeviceAsio::bufferSwitchTimeInfo(ASIOTime *timeInfo, long index,
356  {                                                        ASIOBool processNow) {
   
357      static long processedSamples = 0;      static long processedSamples = 0;
358      // store the timeInfo for later use      // store the timeInfo for later use
359      asioDriverInfo.tInfo = *timeInfo;      asioDriverInfo.tInfo = *timeInfo;
# Line 355  ASIOTime* AudioOutputDeviceAsio::bufferS Line 375  ASIOTime* AudioOutputDeviceAsio::bufferS
375      else      else
376          asioDriverInfo.tcSamples = 0;          asioDriverInfo.tcSamples = 0;
377    
378      // TODO: ignore for now.  get the system reference time      // TODO: ignore for now. get the system reference time
379      // asioDriverInfo.sysRefTime = get_sys_reference_time();      // asioDriverInfo.sysRefTime = get_sys_reference_time();
380    
381          // buffer size in samples      // buffer size in samples
382          long buffSize = asioDriverInfo.chosenBufSize;      long buffSize = asioDriverInfo.chosenBufSize;
         int32_t *p;  
383    
384      //  tell LinuxSampler to  render a fragment of buffSize samples      // tell LinuxSampler to  render a fragment of buffSize samples
385      GlobalAudioOutputDeviceAsioThisPtr->RenderAudio(buffSize);      GlobalAudioOutputDeviceAsioThisPtr->RenderAudio(buffSize);
386    
387          // now write and convert the samples to the ASIO buffer      // now write and convert the samples to the ASIO buffer
388          for (int i = 0; i < asioDriverInfo.numOutputBuffers; i++)      for (int i = 0; i < asioDriverInfo.numOutputBuffers; i++)
389          {      {
390          // do processing for the outputs only          // do processing for the outputs only
391          switch (asioDriverInfo.channelInfos[i].type)          switch (asioDriverInfo.channelInfos[i].type)
392          {          {
393              case ASIOSTInt16LSB:          case ASIOSTInt16LSB:
394                  floatToASIOSTInt16LSB(GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(),              floatToASIOSTInt16LSB(GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(),
395                      (int16_t *)asioDriverInfo.bufferInfos[i].buffers[index], buffSize);                                    (int16_t*)asioDriverInfo.bufferInfos[i].buffers[index], buffSize);
396                  break;              break;
397              case ASIOSTInt24LSB:                // used for 20 bits as well          case ASIOSTInt24LSB:   // used for 20 bits as well
398                  memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 3);              memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 3);
399                  break;              break;
400              case ASIOSTInt32LSB:          case ASIOSTInt32LSB:
401                  floatToASIOSTInt32LSB(GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(),              floatToASIOSTInt32LSB(GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(),
402                      (int32_t *)asioDriverInfo.bufferInfos[i].buffers[index], buffSize);                                    (int32_t*)asioDriverInfo.bufferInfos[i].buffers[index], buffSize);
403                  break;              break;
404              case ASIOSTFloat32LSB:              // IEEE 754 32 bit float, as found on Intel x86 architecture          case ASIOSTFloat32LSB: // IEEE 754 32 bit float, as found on Intel x86 architecture
405                  throw AudioOutputException(String("ASIO Error: ASIOSTFloat32LSB not yet supported! report to LinuxSampler developers.") );              throw AudioOutputException("ASIO Error: ASIOSTFloat32LSB not yet supported! report to LinuxSampler developers.");
406                  break;              break;
407              case ASIOSTFloat64LSB:              // IEEE 754 64 bit double float, as found on Intel x86 architecture          case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture
408                  throw AudioOutputException(String("ASIO Error: ASIOSTFloat64LSB not yet supported! report to LinuxSampler developers.") );              throw AudioOutputException("ASIO Error: ASIOSTFloat64LSB not yet supported! report to LinuxSampler developers.");
409                  break;              break;
410    
411              // these are used for 32 bit data buffer, with different alignment of the data inside              // These are used for 32 bit data buffer, with different
412              // 32 bit PCI bus systems can more easily used with these              // alignment of the data inside. 32 bit PCI bus systems
413              case ASIOSTInt32LSB16:              // 32 bit data with 16 bit alignment              // can more easily used with these.
414                  floatToASIOSTInt32LSBXX<16>( GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(),  
415                    (int32_t *)asioDriverInfo.bufferInfos[i].buffers[index], buffSize);          case ASIOSTInt32LSB16: // 32 bit data with 16 bit alignment
416                  break;              floatToASIOSTInt32LSBXX<16>(GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(),
417              case ASIOSTInt32LSB18:              // 32 bit data with 18 bit alignment                                          (int32_t*)asioDriverInfo.bufferInfos[i].buffers[index],
418                  floatToASIOSTInt32LSBXX<18>( GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(),                                          buffSize);
419                    (int32_t *)asioDriverInfo.bufferInfos[i].buffers[index], buffSize);              break;
420                  break;          case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment
421              case ASIOSTInt32LSB20:              // 32 bit data with 20 bit alignment              floatToASIOSTInt32LSBXX<18>(GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(),
422                  floatToASIOSTInt32LSBXX<20>( GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(),                                          (int32_t*)asioDriverInfo.bufferInfos[i].buffers[index],
423                    (int32_t *)asioDriverInfo.bufferInfos[i].buffers[index], buffSize);                                          buffSize);
424                  break;              break;
425              case ASIOSTInt32LSB24:              // 32 bit data with 24 bit alignment          case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment
426                  floatToASIOSTInt32LSBXX<24>( GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(),              floatToASIOSTInt32LSBXX<20>(GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(),
427                    (int32_t *)asioDriverInfo.bufferInfos[i].buffers[index], buffSize);                                          (int32_t*)asioDriverInfo.bufferInfos[i].buffers[index],
428                  break;                                          buffSize);
429              case ASIOSTInt16MSB:              break;
430                  throw AudioOutputException(String("ASIO Error: ASIOSTInt16MSB not yet supported! report to LinuxSampler developers.") );          case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment
431                                  break;              floatToASIOSTInt32LSBXX<24>(GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(),
432                          case ASIOSTInt24MSB:            // used for 20 bits as well                                          (int32_t*)asioDriverInfo.bufferInfos[i].buffers[index],
433                  throw AudioOutputException(String("ASIO Error: ASIOSTInt24MSB not yet supported! report to LinuxSampler developers.") );                                          buffSize);
434                                  break;              break;
435                          case ASIOSTInt32MSB:          case ASIOSTInt16MSB:
436                  throw AudioOutputException(String("ASIO Error: ASIOSTInt32MSB not yet supported! report to LinuxSampler developers.") );              throw AudioOutputException("ASIO Error: ASIOSTInt16MSB not yet supported! report to LinuxSampler developers.");
437                                  break;              break;
438                          case ASIOSTFloat32MSB:          // IEEE 754 32 bit float, as found on bigendian architecture          case ASIOSTInt24MSB:   // used for 20 bits as well
439                  throw AudioOutputException(String("ASIO Error: ASIOSTFloat32MSB not yet supported! report to LinuxSampler developers.") );              throw AudioOutputException("ASIO Error: ASIOSTInt24MSB not yet supported! report to LinuxSampler developers.");
440                                  break;              break;
441                          case ASIOSTFloat64MSB:          // IEEE 754 64 bit double float, as found on bigendian architecture          case ASIOSTInt32MSB:
442                  throw AudioOutputException(String("ASIO Error: ASIOSTFloat64MSB not yet supported! report to LinuxSampler developers.") );              throw AudioOutputException("ASIO Error: ASIOSTInt32MSB not yet supported! report to LinuxSampler developers.");
443                                  break;              break;
444            case ASIOSTFloat32MSB: // IEEE 754 32 bit float, as found on bigendian architecture
445                                  // these are used for 32 bit data buffer, with different alignment of the data inside              throw AudioOutputException("ASIO Error: ASIOSTFloat32MSB not yet supported! report to LinuxSampler developers.");
446                                  // 32 bit PCI bus systems can more easily used with these              break;
447                          case ASIOSTInt32MSB16:          // 32 bit data with 18 bit alignment          case ASIOSTFloat64MSB: // IEEE 754 64 bit double float, as found on bigendian architecture
448                  throw AudioOutputException(String("ASIO Error: ASIOSTInt32MSB16 not yet supported! report to LinuxSampler developers.") );              throw AudioOutputException("ASIO Error: ASIOSTFloat64MSB not yet supported! report to LinuxSampler developers.");
449                  break;              break;
450              case ASIOSTInt32MSB18:              // 32 bit data with 18 bit alignment  
451                  throw AudioOutputException(String("ASIO Error: ASIOSTInt32MSB18 not yet supported! report to LinuxSampler developers.") );              // These are used for 32 bit data buffer, with different
452                  break;              // alignment of the data inside.  32 bit PCI bus systems
453                          case ASIOSTInt32MSB20:          // 32 bit data with 20 bit alignment              // can more easily used with these.
454                  throw AudioOutputException(String("ASIO Error: ASIOSTInt32MSB20 not yet supported! report to LinuxSampler developers.") );  
455                  break;          case ASIOSTInt32MSB16: // 32 bit data with 18 bit alignment
456                          case ASIOSTInt32MSB24:          // 32 bit data with 24 bit alignment              throw AudioOutputException("ASIO Error: ASIOSTInt32MSB16 not yet supported! report to LinuxSampler developers.");
457                  throw AudioOutputException(String("ASIO Error: ASIOSTInt32MSB24 not yet supported! report to LinuxSampler developers.") );              break;
458                                  break;          case ASIOSTInt32MSB18: // 32 bit data with 18 bit alignment
459              default:              throw AudioOutputException("ASIO Error: ASIOSTInt32MSB18 not yet supported! report to LinuxSampler developers.");
460              throw AudioOutputException(String("ASIO Error: unknown ASIOST sample format. report error.") );              break;
461                  break;          case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment
462                throw AudioOutputException("ASIO Error: ASIOSTInt32MSB20 not yet supported! report to LinuxSampler developers.");
463                break;
464            case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment
465                throw AudioOutputException("ASIO Error: ASIOSTInt32MSB24 not yet supported! report to LinuxSampler developers.");
466                break;
467            default:
468                throw AudioOutputException("ASIO Error: unknown ASIOST sample format. report error.");
469                break;
470          }          }
471          }      }
472    
473          // finally if the driver supports the ASIOOutputReady() optimization, do it here, all data are in place      // finally if the driver supports the ASIOOutputReady()
474          if (asioDriverInfo.ASIOOutputReadySupported)      // optimization, do it here, all data are in place
475                  ASIOOutputReady();      if (asioDriverInfo.ASIOOutputReadySupported)
476            ASIOOutputReady();
477    
478      processedSamples += buffSize;      processedSamples += buffSize;
479          return 0L;      return 0L;
480  }  }
481    
482  void AudioOutputDeviceAsio::bufferSwitch(long index, ASIOBool processNow)  void AudioOutputDeviceAsio::bufferSwitch(long index, ASIOBool processNow) {
483  {      // The actual processing callback.
484      // the actual processing callback.  
485      // as this is a "back door" into the bufferSwitchTimeInfo a timeInfo needs to be created      // As this is a "back door" into the bufferSwitchTimeInfo, a
486      // though it will only set the timeInfo.samplePosition and timeInfo.systemTime fields and the according flags      // timeInfo needs to be created, though it will only set the
487        // timeInfo.samplePosition and timeInfo.systemTime fields and the
488        // according flags.
489      ASIOTime  timeInfo;      ASIOTime  timeInfo;
490      memset (&timeInfo, 0, sizeof (timeInfo));      memset(&timeInfo, 0, sizeof(timeInfo));
491    
492      // get the time stamp of the buffer, not necessary if no      // Get the time stamp of the buffer. Not necessary if no
493      // synchronization to other media is required      // synchronization to other media is required.
494      if(ASIOGetSamplePosition(&timeInfo.timeInfo.samplePosition, &timeInfo.timeInfo.systemTime) == ASE_OK)      if (ASIOGetSamplePosition(&timeInfo.timeInfo.samplePosition,
495                                  &timeInfo.timeInfo.systemTime) == ASE_OK)
496          timeInfo.timeInfo.flags = kSystemTimeValid | kSamplePositionValid;          timeInfo.timeInfo.flags = kSystemTimeValid | kSamplePositionValid;
497    
498      bufferSwitchTimeInfo (&timeInfo, index, processNow);      bufferSwitchTimeInfo(&timeInfo, index, processNow);
499    }
500    
501    void sampleRateChanged(ASIOSampleRate sRate) {
502        // Do whatever you need to do if the sample rate changed.
503        // Usually this only happens during external sync.
504        // Audio processing is not stopped by the driver, actual sample rate
505        // might not have even changed, maybe only the sample rate status of an
506        // AES/EBU or S/PDIF digital input at the audio device.
507        // You might have to update time/sample related conversion routines, etc.
508  }  }
509    
510  void sampleRateChanged(ASIOSampleRate sRate)  long asioMessages(long selector, long value, void* message, double* opt) {
511  {      dmsg(2,("asioMessages selector=%ld value=%ld\n", selector, value));
         // do whatever you need to do if the sample rate changed  
         // usually this only happens during external sync.  
         // Audio processing is not stopped by the driver, actual sample rate  
         // might not have even changed, maybe only the sample rate status of an  
         // AES/EBU or S/PDIF digital input at the audio device.  
         // You might have to update time/sample related conversion routines, etc.  
 }  
   
 long asioMessages(long selector, long value, void* message, double* opt)  
 {  
     dmsg(2,("asioMessages selector=%d value=%d\n",selector,value));  
512      // currently the parameters "value", "message" and "opt" are not used.      // currently the parameters "value", "message" and "opt" are not used.
513      long ret = 0;      long ret = 0;
514      switch(selector)      switch (selector)
515      {      {
516          case kAsioSelectorSupported:      case kAsioSelectorSupported:
517              if(value == kAsioResetRequest          if (value == kAsioResetRequest ||
518              || value == kAsioEngineVersion              value == kAsioEngineVersion ||
519              || value == kAsioResyncRequest              value == kAsioResyncRequest ||
520              || value == kAsioLatenciesChanged              value == kAsioLatenciesChanged ||
521              // the following three were added for ASIO 2.0, we don't necessarily have to support them              // the following three were added for ASIO 2.0, we don't necessarily have to support them
522              || value == kAsioSupportsTimeInfo              value == kAsioSupportsTimeInfo ||
523              || value == kAsioSupportsTimeCode              value == kAsioSupportsTimeCode ||
524              || value == kAsioSupportsInputMonitor)              value == kAsioSupportsInputMonitor)
                 ret = 1L;  
             break;  
         case kAsioResetRequest:  
             // defer the task and perform the reset of the driver during the next "safe" situation  
             // You cannot reset the driver right now, as this code is called from the driver.  
             // Reset the driver is done by completely destruct is. I.e. ASIOStop(), ASIODisposeBuffers(), Destruction  
             // Afterwards you initialize the driver again.  
             //GlobalAudioOutputDeviceAsioThisPtr->asioDriverInfo.stopped;  // In this sample the processing will just stop  
             ret = 1L;  
             break;  
         case kAsioResyncRequest:  
             // This informs the application, that the driver encountered some non fatal data loss.  
             // It is used for synchronization purposes of different media.  
             // Added mainly to work around the Win16Mutex problems in Windows 95/98 with the  
             // Windows Multimedia system, which could loose data because the Mutex was hold too long  
             // by another thread.  
             // However a driver can issue it in other situations, too.  
525              ret = 1L;              ret = 1L;
526              break;          break;
527          case kAsioLatenciesChanged:      case kAsioResetRequest:
528              // This will inform the host application that the drivers were latencies changed.          // Defer the task and perform the reset of the driver during the next "safe" situation.
529              // Beware, it this does not mean that the buffer sizes have changed!          // You cannot reset the driver right now, as this code is called from the driver.
530              // You might need to update internal delay data.          // Reset the driver is done by completely destruct is. I.e. ASIOStop(),
531              ret = 1L;          // ASIODisposeBuffers(), Destruction
532              break;          // Afterwards you initialize the driver again.
533          case kAsioEngineVersion:  
534              // return the supported ASIO version of the host application          //GlobalAudioOutputDeviceAsioThisPtr->asioDriverInfo.stopped; // In this sample the processing will just stop
535              // If a host applications does not implement this selector, ASIO 1.0 is assumed          ret = 1L;
536              // by the driver          break;
537              ret = 2L;      case kAsioResyncRequest:
538              break;          // This informs the application, that the driver encountered some non fatal data loss.
539          case kAsioSupportsTimeInfo:          // It is used for synchronization purposes of different media.
540              // informs the driver wether the asioCallbacks.bufferSwitchTimeInfo() callback          // Added mainly to work around the Win16Mutex problems in Windows 95/98 with the
541              // is supported.          // Windows Multimedia system, which could loose data because the Mutex was hold too long
542              // For compatibility with ASIO 1.0 drivers the host application should always support          // by another thread.
543              // the "old" bufferSwitch method, too.          // However a driver can issue it in other situations, too.
544              ret = 1;          ret = 1L;
545              break;          break;
546          case kAsioSupportsTimeCode:      case kAsioLatenciesChanged:
547              // informs the driver wether application is interested in time code info.          // This will inform the host application that the drivers were latencies changed.
548              // If an application does not need to know about time code, the driver has less work          // Beware, it this does not mean that the buffer sizes have changed!
549              // to do.          // You might need to update internal delay data.
550              ret = 0;          ret = 1L;
551              break;          break;
552        case kAsioEngineVersion:
553            // Return the supported ASIO version of the host application.
554            // If a host applications does not implement this selector, ASIO 1.0 is assumed
555            // by the driver
556            ret = 2L;
557            break;
558        case kAsioSupportsTimeInfo:
559            // Informs the driver whether the asioCallbacks.bufferSwitchTimeInfo() callback
560            // is supported.
561            // For compatibility with ASIO 1.0 drivers the host application should always support
562            // the "old" bufferSwitch method, too.
563            ret = 1;
564            break;
565        case kAsioSupportsTimeCode:
566            // Informs the driver whether application is interested in time code info.
567            // If an application does not need to know about time code, the driver has less work
568            // to do.
569            ret = 0;
570            break;
571      }      }
572      return ret;      return ret;
573  }  }
# Line 545  long asioMessages(long selector, long va Line 576  long asioMessages(long selector, long va
576  // *************** ParameterCard ***************  // *************** ParameterCard ***************
577  // *  // *
578    
579      AudioOutputDeviceAsio::ParameterCard::ParameterCard() : DeviceCreationParameterString() {  AudioOutputDeviceAsio::ParameterCard::ParameterCard() : DeviceCreationParameterString() {
580          InitWithDefault(); // use default card      InitWithDefault(); // use default card
581      }  }
   
     AudioOutputDeviceAsio::ParameterCard::ParameterCard(String s) throw (Exception) : DeviceCreationParameterString(s) {  
     }  
   
     String AudioOutputDeviceAsio::ParameterCard::Description() {  
         return "Sound card to be used";  
     }  
582    
583      bool AudioOutputDeviceAsio::ParameterCard::Fix() {  AudioOutputDeviceAsio::ParameterCard::ParameterCard(String s) throw (Exception) : DeviceCreationParameterString(s) {
584          return true;  }
     }  
585    
586      bool AudioOutputDeviceAsio::ParameterCard::Mandatory() {  String AudioOutputDeviceAsio::ParameterCard::Description() {
587          return false;      return "Sound card to be used";
588      }  }
589    
590      std::map<String,DeviceCreationParameter*> AudioOutputDeviceAsio::ParameterCard::DependsAsParameters() {  bool AudioOutputDeviceAsio::ParameterCard::Fix() {
591          return std::map<String,DeviceCreationParameter*>(); // no dependencies      return true;
592      }  }
593    
594      optional<String> AudioOutputDeviceAsio::ParameterCard::DefaultAsString(std::map<String,String> Parameters) {  bool AudioOutputDeviceAsio::ParameterCard::Mandatory() {
595        return false;
596    }
597    
598          std::vector<String> cards = PossibilitiesAsString(Parameters);  std::map<String,DeviceCreationParameter*> AudioOutputDeviceAsio::ParameterCard::DependsAsParameters() {
599          if (cards.empty()) throw Exception("AudioOutputDeviceAsio: Can't find any card");      return std::map<String,DeviceCreationParameter*>(); // no dependencies
600          dmsg(2,("AudioOutputDeviceAsio::ParameterCard::DefaultAsString='%s'\n",cards[0].c_str() ));  }
601    
602          // if currentAsioDriverName is empty then return the first card  optional<String> AudioOutputDeviceAsio::ParameterCard::DefaultAsString(std::map<String,String> Parameters) {
603          // otherwise return the currentAsioDriverName. this avoids closing the current ASIO driver      std::vector<String> cards = PossibilitiesAsString(Parameters);
604          // when the LSCP client calls commands like GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO ASIO CARD      if (cards.empty()) throw Exception("AudioOutputDeviceAsio: Can't find any card");
605          // which would load the default card (without this check it would always be the same which would cause the above problem)      dmsg(2,("AudioOutputDeviceAsio::ParameterCard::DefaultAsString='%s'\n", cards[0].c_str()));
         if( currentAsioDriverName == "" ) {  
             return cards[0]; // first card by default  
         }  
         else {  
             return currentAsioDriverName;  
         }  
606    
607        // If currentAsioDriverName is empty then return the first card,
608        // otherwise return the currentAsioDriverName. This avoids closing
609        // the current ASIO driver when the LSCP client calls commands
610        // like GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO ASIO CARD, which
611        // would load the default card (without this check it would always
612        // be the same which would cause the above problem).
613        if (currentAsioDriverName == "") {
614            return cards[0]; // first card by default
615      }      }
616        else {
617      std::vector<String> AudioOutputDeviceAsio::ParameterCard::PossibilitiesAsString(std::map<String,String> Parameters) {          return currentAsioDriverName;
         dmsg(2,("AudioOutputDeviceAsio::ParameterCard::PossibilitiesAsString:\n"));  
                 return getAsioDriverNames();  
618      }      }
619    
620      void AudioOutputDeviceAsio::ParameterCard::OnSetValue(String s) throw (Exception) {  }
         // not posssible, as parameter is fix  
     }  
621    
622      String AudioOutputDeviceAsio::ParameterCard::Name() {  std::vector<String> AudioOutputDeviceAsio::ParameterCard::PossibilitiesAsString(std::map<String,String> Parameters) {
623          return "CARD";      dmsg(2,("AudioOutputDeviceAsio::ParameterCard::PossibilitiesAsString:\n"));
624      }      return getAsioDriverNames();
625    }
626    
627    void AudioOutputDeviceAsio::ParameterCard::OnSetValue(String s) throw (Exception) {
628        // not posssible, as parameter is fix
629    }
630    
631    String AudioOutputDeviceAsio::ParameterCard::Name() {
632        return "CARD";
633    }
634    
635    
636    
637  // *************** ParameterSampleRate ***************  // *************** ParameterSampleRate ***************
638  // *  // *
639    
640      AudioOutputDeviceAsio::ParameterSampleRate::ParameterSampleRate() : AudioOutputDevice::ParameterSampleRate::ParameterSampleRate() {  AudioOutputDeviceAsio::ParameterSampleRate::ParameterSampleRate() : AudioOutputDevice::ParameterSampleRate::ParameterSampleRate() {
641      }  }
642    
643      AudioOutputDeviceAsio::ParameterSampleRate::ParameterSampleRate(String s) : AudioOutputDevice::ParameterSampleRate::ParameterSampleRate(s) {  AudioOutputDeviceAsio::ParameterSampleRate::ParameterSampleRate(String s) : AudioOutputDevice::ParameterSampleRate::ParameterSampleRate(s) {
644      }  }
645    
646      std::map<String,DeviceCreationParameter*> AudioOutputDeviceAsio::ParameterSampleRate::DependsAsParameters() {  std::map<String,DeviceCreationParameter*> AudioOutputDeviceAsio::ParameterSampleRate::DependsAsParameters() {
647          static ParameterCard card;      static ParameterCard card;
648          std::map<String,DeviceCreationParameter*> dependencies;      std::map<String,DeviceCreationParameter*> dependencies;
649          dependencies[card.Name()] = &card;      dependencies[card.Name()] = &card;
650          return dependencies;      return dependencies;
651      }  }
652    
653      optional<int> AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt(std::map<String,String> Parameters) {  optional<int> AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt(std::map<String,String> Parameters) {
654          if (!Parameters.count("CARD")) {      if (!Parameters.count("CARD")) {
655              dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning optional<int>::nothing  (parameter CARD not supplied)\n"));          dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning optional<int>::nothing  (parameter CARD not supplied)\n"));
656              return optional<int>::nothing;          return optional<int>::nothing;
657                  }      }
658    
659          // return the default samplerate. first try 44100 then 48000,  then the first samplerate found in the list      // return the default samplerate. first try 44100 then 48000, then
660          ParameterCard card(Parameters["CARD"]);      // the first samplerate found in the list
661          if( ASIO_OpenAndQueryDeviceInfo((char *)card.ValueAsString().c_str(), &asioDriverInfo, &MyAsioDriverInfo) != ASE_OK) {      ParameterCard card(Parameters["CARD"]);
662              throw AudioOutputException(String("Error: ASIO Initalization Error") );      ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo, &MyAsioDriverInfo);
663        for (uint i = 0; i < asioDriverInfo.sampleRates.size(); i++) {
664            if (asioDriverInfo.sampleRates[i] == 44100) {
665                return 44100;
666                dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning 44100\n"));
667          }          }
668          for(int i = 0 ; i < asioDriverInfo.sampleRates.size() ; i++) {          if (asioDriverInfo.sampleRates[i] == 48000) {
669              if(asioDriverInfo.sampleRates[i] == 44100) {              dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning 48000\n"));
670                  return 44100;              return 48000;
                 dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning 44100\n"));  
             }  
             if(asioDriverInfo.sampleRates[i] == 48000) {  
                 dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning 48000\n"));  
                 return 48000;  
             }  
671          }          }
         dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning %d\n",asioDriverInfo.sampleRates[0]));  
         return asioDriverInfo.sampleRates[0];  
672      }      }
673        dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning %d\n",
674                asioDriverInfo.sampleRates[0]));
675        return asioDriverInfo.sampleRates[0];
676    }
677    
678          std::vector<int> AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt(std::map<String,String> Parameters) {  std::vector<int> AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt(std::map<String,String> Parameters) {
679          dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt\n"));      dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt\n"));
680          if (!Parameters.count("CARD")) {      if (!Parameters.count("CARD")) {
681              dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt returning empty vector  (parameter CARD not supplied)\n"));          dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt returning empty vector  (parameter CARD not supplied)\n"));
682              return std::vector<int>();          return std::vector<int>();
683          }      }
684    
685          ParameterCard card(Parameters["CARD"]);      ParameterCard card(Parameters["CARD"]);
686          if( ASIO_OpenAndQueryDeviceInfo((char *)card.ValueAsString().c_str(), &asioDriverInfo, &MyAsioDriverInfo) != ASE_OK) {      ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo, &MyAsioDriverInfo);
             throw AudioOutputException(String("Error: ASIO Initalization Error") );  
         }  
687    
688          for(int i=0;i<asioDriverInfo.sampleRates.size();i++) {      for (uint i = 0; i < asioDriverInfo.sampleRates.size(); i++) {
689              dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt samplerate[%d]=%d\n",i,asioDriverInfo.sampleRates[i]));          dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt samplerate[%d]=%d\n", i, asioDriverInfo.sampleRates[i]));
690          }      }
691    
692                  return asioDriverInfo.sampleRates;      return asioDriverInfo.sampleRates;
693       }  }
694    
695    
696    
697  // *************** ParameterChannels ***************  // *************** ParameterChannels ***************
698  // *  // *
699    
700      AudioOutputDeviceAsio::ParameterChannels::ParameterChannels() : AudioOutputDevice::ParameterChannels::ParameterChannels() {  AudioOutputDeviceAsio::ParameterChannels::ParameterChannels() : AudioOutputDevice::ParameterChannels::ParameterChannels() {
701          //InitWithDefault();      //InitWithDefault();
702          // could not determine default value? ...      // could not determine default value? ...
703          //if (ValueAsInt() == 0) SetValue(2); // ... then (try) a common value      //if (ValueAsInt() == 0) SetValue(2); // ... then (try) a common value
704      }  }
   
     AudioOutputDeviceAsio::ParameterChannels::ParameterChannels(String s) : AudioOutputDevice::ParameterChannels::ParameterChannels(s) {  
     }  
705    
706      std::map<String,DeviceCreationParameter*> AudioOutputDeviceAsio::ParameterChannels::DependsAsParameters() {  AudioOutputDeviceAsio::ParameterChannels::ParameterChannels(String s) : AudioOutputDevice::ParameterChannels::ParameterChannels(s) {
707          static ParameterCard card;  }
         std::map<String,DeviceCreationParameter*> dependencies;  
         dependencies[card.Name()] = &card;  
         return dependencies;  
     }  
708    
709      optional<int> AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt(std::map<String,String> Parameters) {  std::map<String,DeviceCreationParameter*> AudioOutputDeviceAsio::ParameterChannels::DependsAsParameters() {
710          dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt\n"));      static ParameterCard card;
711          if (!Parameters.count("CARD")) {      std::map<String,DeviceCreationParameter*> dependencies;
712              dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt returning optional<int>::nothing (CARD parameter not supplied)\n"));      dependencies[card.Name()] = &card;
713              return optional<int>::nothing;      return dependencies;
714          }  }
715    
716          ParameterCard card(Parameters["CARD"]);  optional<int> AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt(std::map<String,String> Parameters) {
717          if( ASIO_OpenAndQueryDeviceInfo((char *)card.ValueAsString().c_str(), &asioDriverInfo, &MyAsioDriverInfo) != ASE_OK) {      dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt\n"));
718              throw AudioOutputException(String("Error: ASIO Initialization Error") );      if (!Parameters.count("CARD")) {
719          }          dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt returning optional<int>::nothing (CARD parameter not supplied)\n"));
720          dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt returning %d\n",asioDriverInfo.numOutputChannels));          return optional<int>::nothing;
         return asioDriverInfo.numOutputChannels;  
721      }      }
722    
723      optional<int> AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt(std::map<String,String> Parameters) {      ParameterCard card(Parameters["CARD"]);
724          dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt!\n"));      ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo, &MyAsioDriverInfo);
725          if (!Parameters.count("CARD")) {      dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt returning %ld\n",
726              dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt returning optional<int>::nothing (CARD parameter not supplied)\n"));              asioDriverInfo.numOutputChannels));
727              return optional<int>::nothing;      return asioDriverInfo.numOutputChannels;
728          }  }
729          dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt returning 1\n"));  
730          return 1;  optional<int> AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt(std::map<String,String> Parameters) {
731        dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt!\n"));
732        if (!Parameters.count("CARD")) {
733            dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt returning optional<int>::nothing (CARD parameter not supplied)\n"));
734            return optional<int>::nothing;
735      }      }
736        dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt returning 1\n"));
737        return 1;
738    }
739    
740      optional<int> AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt(std::map<String,String> Parameters) {  optional<int> AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt(std::map<String,String> Parameters) {
741          dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt!\n"));      dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt!\n"));
742          if (!Parameters.count("CARD")) {      if (!Parameters.count("CARD")) {
743          dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt returning optional<int>::nothing (CARD parameter not supplied)\n"));          dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt returning optional<int>::nothing (CARD parameter not supplied)\n"));
744              return optional<int>::nothing;          return optional<int>::nothing;
         }  
   
         ParameterCard card(Parameters["CARD"]);  
         if( ASIO_OpenAndQueryDeviceInfo((char *)card.ValueAsString().c_str(), &asioDriverInfo, &MyAsioDriverInfo) != ASE_OK) {  
             throw AudioOutputException(String("Error: ASIO Init Error") );  
         }  
         dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt returning %d\n",asioDriverInfo.numOutputChannels));  
         return asioDriverInfo.numOutputChannels;  
745      }      }
746    
747        ParameterCard card(Parameters["CARD"]);
748        ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo, &MyAsioDriverInfo);
749        dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt returning %ld\n",
750                asioDriverInfo.numOutputChannels));
751        return asioDriverInfo.numOutputChannels;
752    }
753    
754    
755    
756  // *************** ParameterFragmentSize ***************  // *************** ParameterFragmentSize ***************
757  // *  // *
758    
759      AudioOutputDeviceAsio::ParameterFragmentSize::ParameterFragmentSize() : DeviceCreationParameterInt() {  AudioOutputDeviceAsio::ParameterFragmentSize::ParameterFragmentSize() : DeviceCreationParameterInt() {
760          InitWithDefault();      InitWithDefault();
761      }  }
   
     AudioOutputDeviceAsio::ParameterFragmentSize::ParameterFragmentSize(String s) throw (Exception) : DeviceCreationParameterInt(s) {  
     }  
762    
763      String AudioOutputDeviceAsio::ParameterFragmentSize::Description() {  AudioOutputDeviceAsio::ParameterFragmentSize::ParameterFragmentSize(String s) throw (Exception) : DeviceCreationParameterInt(s) {
764          return "Size of each buffer fragment";  }
     }  
765    
766      bool AudioOutputDeviceAsio::ParameterFragmentSize::Fix() {  String AudioOutputDeviceAsio::ParameterFragmentSize::Description() {
767          return true;      return "Size of each buffer fragment";
768      }  }
769    
770      bool AudioOutputDeviceAsio::ParameterFragmentSize::Mandatory() {  bool AudioOutputDeviceAsio::ParameterFragmentSize::Fix() {
771          return false;      return true;
772      }  }
773    
774      std::map<String,DeviceCreationParameter*> AudioOutputDeviceAsio::ParameterFragmentSize::DependsAsParameters() {  bool AudioOutputDeviceAsio::ParameterFragmentSize::Mandatory() {
775          static ParameterCard card;      return false;
776          std::map<String,DeviceCreationParameter*> dependencies;  }
         dependencies[card.Name()] = &card;  
         return dependencies;  
     }  
777    
778      optional<int> AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt(std::map<String,String> Parameters) {  std::map<String,DeviceCreationParameter*> AudioOutputDeviceAsio::ParameterFragmentSize::DependsAsParameters() {
779          dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt!\n"));      static ParameterCard card;
780          if (!Parameters.count("CARD")) {      std::map<String,DeviceCreationParameter*> dependencies;
781              dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt returning optional<int>::nothing (no CARD parameter supplied\n"));      dependencies[card.Name()] = &card;
782              return optional<int>::nothing;      return dependencies;
783          }  }
784    
785          ParameterCard card(Parameters["CARD"]);  optional<int> AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt(std::map<String,String> Parameters) {
786          if( ASIO_OpenAndQueryDeviceInfo((char *)card.ValueAsString().c_str(), &asioDriverInfo, &MyAsioDriverInfo) != ASE_OK) {      dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt!\n"));
787              throw AudioOutputException(String("Error: ASIO Initialization Error") );      if (!Parameters.count("CARD")) {
788          }          dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt returning optional<int>::nothing (no CARD parameter supplied\n"));
789          dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt returning %d\n",asioDriverInfo.preferredBufSize));          return optional<int>::nothing;
         return asioDriverInfo.preferredBufSize;  
790      }      }
791    
792      optional<int> AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt(std::map<String,String> Parameters) {      ParameterCard card(Parameters["CARD"]);
793          dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt!\n"));      ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo, &MyAsioDriverInfo);
794          if (!Parameters.count("CARD")) {      dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt returning %ld\n",
795              dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt returning optional<int>::nothing (no CARD parameter supplied\n"));              asioDriverInfo.preferredBufSize));
796              return optional<int>::nothing;      return asioDriverInfo.preferredBufSize;
797          }  }
798    
799          ParameterCard card(Parameters["CARD"]);  optional<int> AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt(std::map<String,String> Parameters) {
800          if( ASIO_OpenAndQueryDeviceInfo((char *)card.ValueAsString().c_str(), &asioDriverInfo, &MyAsioDriverInfo) != ASE_OK) {      dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt!\n"));
801              throw AudioOutputException(String("Error: ASIO Initalization Error") );      if (!Parameters.count("CARD")) {
802          }          dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt returning optional<int>::nothing (no CARD parameter supplied\n"));
803          dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt returning %d\n",asioDriverInfo.minBufSize));          return optional<int>::nothing;
         return asioDriverInfo.minBufSize;  
804      }      }
805    
806      optional<int> AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt(std::map<String,String> Parameters) {      ParameterCard card(Parameters["CARD"]);
807          dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt!\n"));      ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo, &MyAsioDriverInfo);
808          if (!Parameters.count("CARD")) {      dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt returning %ld\n",
809          dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt returning optional<int>::nothing (no CARD parameter supplied\n"));              asioDriverInfo.minBufSize));
810              return optional<int>::nothing;      return asioDriverInfo.minBufSize;
811          }  }
812    
813          ParameterCard card(Parameters["CARD"]);  optional<int> AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt(std::map<String,String> Parameters) {
814          if( ASIO_OpenAndQueryDeviceInfo((char *)card.ValueAsString().c_str(), &asioDriverInfo, &MyAsioDriverInfo) != ASE_OK) {      dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt!\n"));
815              throw AudioOutputException(String("Error: ASIO Initialization Error") );      if (!Parameters.count("CARD")) {
816          }          dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt returning optional<int>::nothing (no CARD parameter supplied\n"));
817          dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt returning %d\n",asioDriverInfo.maxBufSize));          return optional<int>::nothing;
         return asioDriverInfo.maxBufSize;  
818      }      }
819    
820      std::vector<int> AudioOutputDeviceAsio::ParameterFragmentSize::PossibilitiesAsInt(std::map<String,String> Parameters) {      ParameterCard card(Parameters["CARD"]);
821          dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::PossibilitiesAsInt!\n"));      ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo, &MyAsioDriverInfo);
822          return std::vector<int>();      dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt returning %ld\n",
823      }              asioDriverInfo.maxBufSize));
824        return asioDriverInfo.maxBufSize;
825    }
826    
827      void AudioOutputDeviceAsio::ParameterFragmentSize::OnSetValue(int i) throw (Exception) {  std::vector<int> AudioOutputDeviceAsio::ParameterFragmentSize::PossibilitiesAsInt(std::map<String,String> Parameters) {
828          // not posssible, as parameter is fix      dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::PossibilitiesAsInt!\n"));
829      }      return std::vector<int>();
830    }
831    
832      String AudioOutputDeviceAsio::ParameterFragmentSize::Name() {  void AudioOutputDeviceAsio::ParameterFragmentSize::OnSetValue(int i) throw (Exception) {
833          return "FRAGMENTSIZE";      // not posssible, as parameter is fix
834      }  }
835    
836    String AudioOutputDeviceAsio::ParameterFragmentSize::Name() {
837        return "FRAGMENTSIZE";
838    }
839    
840    
841    
842  // *************** AudioOutputDeviceAsio ***************  // *************** AudioOutputDeviceAsio ***************
843  // *  // *
844    
845      /**  /**
846        * Create and initialize Asio audio output device with given parameters.   * Create and initialize Asio audio output device with given parameters.
847        *   *
848        * @param Parameters - optional parameters   * @param Parameters - optional parameters
849        * @throws AudioOutputException  if output device cannot be opened   * @throws AudioOutputException  if output device cannot be opened
850        */   */
851      AudioOutputDeviceAsio::AudioOutputDeviceAsio(std::map<String,DeviceCreationParameter*> Parameters) : AudioOutputDevice(Parameters) {  AudioOutputDeviceAsio::AudioOutputDeviceAsio(std::map<String,DeviceCreationParameter*> Parameters) : AudioOutputDevice(Parameters) {
852          if(AudioOutputDeviceAsioInstantiated) throw Exception("AudioOutputDeviceAsio: Sorry, only one ASIO card at time can be opened");      if (AudioOutputDeviceAsioInstantiated) throw Exception("AudioOutputDeviceAsio: Sorry, only one ASIO card at time can be opened");
853          AudioOutputDeviceAsioInstantiated = true;      AudioOutputDeviceAsioInstantiated = true;
854          asioDriverOpened = false;      asioDriverOpened = false;
855          this->uiAsioChannels = ((DeviceCreationParameterInt*)Parameters["CHANNELS"])->ValueAsInt();      this->uiAsioChannels = ((DeviceCreationParameterInt*)Parameters["CHANNELS"])->ValueAsInt();
856          this->uiSamplerate   = ((DeviceCreationParameterInt*)Parameters["SAMPLERATE"])->ValueAsInt();      this->uiSamplerate   = ((DeviceCreationParameterInt*)Parameters["SAMPLERATE"])->ValueAsInt();
857          this->FragmentSize   = ((DeviceCreationParameterInt*)Parameters["FRAGMENTSIZE"])->ValueAsInt();      this->FragmentSize   = ((DeviceCreationParameterInt*)Parameters["FRAGMENTSIZE"])->ValueAsInt();
858          String Card          = ((DeviceCreationParameterString*)Parameters["CARD"])->ValueAsString();      String card          = ((DeviceCreationParameterString*)Parameters["CARD"])->ValueAsString();
   
   
                 dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio constructor\n"));  
   
                 asioIsPlaying = false;  
859    
         ASIO_OpenAndQueryDeviceInfo((char *)Card.c_str(), &asioDriverInfo, &MyAsioDriverInfo);  
         dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIO_OpenAndQueryDeviceInfo\n"));  
860    
861          if( ASIOSetSampleRate(uiSamplerate) != ASE_OK ) {      dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio constructor\n"));
             throw AudioOutputException(String("Error: ASIOSetSampleRate: cannot set samplerate. ") );  
         }  
         dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIOSetSampleRate\n"));  
862    
863          if(ASIOOutputReady() == ASE_OK) asioDriverInfo.ASIOOutputReadySupported = true;      asioIsPlaying = false;
         else asioDriverInfo.ASIOOutputReadySupported = false;  
         dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIOOutputReady\n"));  
   
         asioDriverInfo.numInputBuffers = 0;  
         asioDriverInfo.numOutputBuffers = uiAsioChannels;  
         asioDriverInfo.chosenBufSize = FragmentSize;  
   
         for( int i = 0 ; i < uiAsioChannels ; i++) {  
             asioDriverInfo.bufferInfos[i].isInput = ASIOFalse;  
             asioDriverInfo.bufferInfos[i].channelNum = i;  
         }  
864    
865          asioCallbacks.bufferSwitch = &bufferSwitch;      ASIO_OpenAndQueryDeviceInfo(card, &asioDriverInfo, &MyAsioDriverInfo);
866          asioCallbacks.sampleRateDidChange = &sampleRateChanged;      dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIO_OpenAndQueryDeviceInfo\n"));
         asioCallbacks.asioMessage = &asioMessages;  
         asioCallbacks.bufferSwitchTimeInfo = &bufferSwitchTimeInfo;  
867    
868          if ( ASIOCreateBuffers(asioDriverInfo.bufferInfos, asioDriverInfo.numOutputBuffers, asioDriverInfo.chosenBufSize = FragmentSize, &asioCallbacks) != ASE_OK ){      if (ASIOSetSampleRate(uiSamplerate) != ASE_OK) {
869              throw AudioOutputException(String("AudioOutputDeviceAsio: Error: ASIOCreateBuffers failed.") );          throw AudioOutputException("Error: ASIOSetSampleRate: cannot set samplerate.");
870          }      }
871          dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIOCreateBuffers\n"));      dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIOSetSampleRate\n"));
872    
873          // create audio channels for this audio device to which the sampler engines can write to      if (ASIOOutputReady() == ASE_OK) asioDriverInfo.ASIOOutputReadySupported = true;
874          for (int i = 0; i < uiAsioChannels; i++) this->Channels.push_back(new AudioChannel(i, FragmentSize));      else asioDriverInfo.ASIOOutputReadySupported = false;
875        dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIOOutputReady\n"));
876    
877          // FIXME: temporary global variable used to store the this pointer for the ASIO callbacks wanting to access the AudioOutputDeviceAsio methods      asioDriverInfo.numInputBuffers = 0;
878          GlobalAudioOutputDeviceAsioThisPtr = this;      asioDriverInfo.numOutputBuffers = uiAsioChannels;
879        asioDriverInfo.chosenBufSize = FragmentSize;
880    
881          if (((DeviceCreationParameterBool*)Parameters["ACTIVE"])->ValueAsBool()) {      for (uint i = 0; i < uiAsioChannels; i++) {
882              Play();          asioDriverInfo.bufferInfos[i].isInput = ASIOFalse;
883          }          asioDriverInfo.bufferInfos[i].channelNum = i;
884      }      }
885    
886      AudioOutputDeviceAsio::~AudioOutputDeviceAsio() {      asioCallbacks.bufferSwitch = &bufferSwitch;
887          ASIOExit();      asioCallbacks.sampleRateDidChange = &sampleRateChanged;
888          asioDriverOpened = false;      asioCallbacks.asioMessage = &asioMessages;
889          AudioOutputDeviceAsioInstantiated = false;      asioCallbacks.bufferSwitchTimeInfo = &bufferSwitchTimeInfo;
890    
891        if (ASIOCreateBuffers(asioDriverInfo.bufferInfos,
892                              asioDriverInfo.numOutputBuffers,
893                              asioDriverInfo.chosenBufSize = FragmentSize,
894                              &asioCallbacks) != ASE_OK) {
895            throw AudioOutputException("AudioOutputDeviceAsio: Error: ASIOCreateBuffers failed.");
896      }      }
897        dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIOCreateBuffers\n"));
898    
899      void AudioOutputDeviceAsio::Play() {      // create audio channels for this audio device to which the sampler engines can write to
900          dmsg(2,("AudioOutputDeviceAsio::Play() !\n"));      for (uint i = 0; i < uiAsioChannels; i++) {
901          if ( ASIOStart() != ASE_OK ){          Channels.push_back(new AudioChannel(i, FragmentSize));
                     asioIsPlaying = false;  
             throw AudioOutputException(String("AudioOutputDeviceAsio: Error: ASIOStart failed.") );  
         }  
                 else asioIsPlaying = true;  
902      }      }
903    
904      bool AudioOutputDeviceAsio::IsPlaying() {      // FIXME: temporary global variable used to store the this pointer
905          return asioIsPlaying;      // for the ASIO callbacks wanting to access the AudioOutputDeviceAsio
906        // methods
907        GlobalAudioOutputDeviceAsioThisPtr = this;
908    
909        if (((DeviceCreationParameterBool*)Parameters["ACTIVE"])->ValueAsBool()) {
910            Play();
911      }      }
912    }
913    
914    AudioOutputDeviceAsio::~AudioOutputDeviceAsio() {
915        ASIOExit();
916        asioDriverOpened = false;
917        AudioOutputDeviceAsioInstantiated = false;
918    }
919    
920      void AudioOutputDeviceAsio::Stop() {  void AudioOutputDeviceAsio::Play() {
921          dmsg(2,("AudioOutputDeviceAsio::Stop() !\n"));      dmsg(2,("AudioOutputDeviceAsio::Play() !\n"));
922          ASIOStop();      if (ASIOStart() != ASE_OK) {
923          asioIsPlaying = false;          asioIsPlaying = false;
924            throw AudioOutputException("AudioOutputDeviceAsio: Error: ASIOStart failed.");
925      }      }
926        else asioIsPlaying = true;
927    }
928    
929      AudioChannel* AudioOutputDeviceAsio::CreateChannel(uint ChannelNr) {  bool AudioOutputDeviceAsio::IsPlaying() {
930          dmsg(2,("AudioOutputDeviceAsio::CreateChannel value=%d  uiAsioChannels=%d\n",ChannelNr,uiAsioChannels));      return asioIsPlaying;
931          // just create a mix channel  }
         return new AudioChannel(ChannelNr, Channel(ChannelNr % uiAsioChannels));  
     }  
932    
933      uint AudioOutputDeviceAsio::MaxSamplesPerCycle() {  void AudioOutputDeviceAsio::Stop() {
934          dmsg(2,("AudioOutputDeviceAsio::MaxSamplesPerCycle value=%d\n",FragmentSize));      dmsg(2,("AudioOutputDeviceAsio::Stop() !\n"));
935          return FragmentSize;      ASIOStop();
936      }      asioIsPlaying = false;
937    }
938    
939      uint AudioOutputDeviceAsio::SampleRate() {  AudioChannel* AudioOutputDeviceAsio::CreateChannel(uint ChannelNr) {
940          dmsg(2,("AudioOutputDeviceAsio::SampleRate value=%d\n",uiSamplerate)); fflush(stdout);      dmsg(2,("AudioOutputDeviceAsio::CreateChannel value=%d  uiAsioChannels=%d\n",
941          return uiSamplerate;              ChannelNr, uiAsioChannels));
942      }      // just create a mix channel
943        return new AudioChannel(ChannelNr, Channel(ChannelNr % uiAsioChannels));
944    }
945    
946      String AudioOutputDeviceAsio::Name() {  uint AudioOutputDeviceAsio::MaxSamplesPerCycle() {
947          return "ASIO";      dmsg(2,("AudioOutputDeviceAsio::MaxSamplesPerCycle value=%d\n", FragmentSize));
948      }      return FragmentSize;
949    }
950    
951      String AudioOutputDeviceAsio::Driver() {  uint AudioOutputDeviceAsio::SampleRate() {
952          return Name();      dmsg(2,("AudioOutputDeviceAsio::SampleRate value=%d\n", uiSamplerate)); fflush(stdout);
953      }      return uiSamplerate;
954    }
955    
956      String AudioOutputDeviceAsio::Description() {  String AudioOutputDeviceAsio::Name() {
957          return "Audio Streaming Input Output 2.2";      return "ASIO";
958      }  }
959    
960      String AudioOutputDeviceAsio::Version() {  String AudioOutputDeviceAsio::Driver() {
961         String s = "$Revision: 1.4 $";      return Name();
962         return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword  }
963      }  
964    String AudioOutputDeviceAsio::Description() {
965        return "Audio Streaming Input Output 2.2";
966    }
967    
968    String AudioOutputDeviceAsio::Version() {
969        String s = "$Revision: 1.5 $";
970        return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
971    }
972    
973  } // namespace LinuxSampler  } // namespace LinuxSampler

Legend:
Removed from v.1947  
changed lines
  Added in v.1948

  ViewVC Help
Powered by ViewVC