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

Contents of /linuxsampler/trunk/src/drivers/audio/AudioOutputDeviceCoreAudio.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3766 - (show annotations) (download)
Mon Apr 6 12:41:49 2020 UTC (3 years, 11 months ago) by schoenebeck
File size: 22738 byte(s)
Fixed deadlocks (e.g. when restarting engines).

* Individual thread implementations (e.g. disk thread, etc.):
  Disable thread cancellation on critical sections, e.g. when holding
  mutex locks, to prevent deadlocks if thread is stopped and/or
  restarted.

* Added TestCancel() calls to thread implementations if missing.

* No need to wrap Thread::TestCancel() calls into
  CONFIG_PTHREAD_TESTCANCEL macro conditions (since TestCancel() is
  already a stub on systems which don't have pthread_testcancel()
  available).

* If compiled for debugging: give each thread a human readable name
  to simplify debugging of multi-threading issues.

* DiskThreadBase: TestCancel() and pthread_testcancel() calls are
  per-se redundant, so only call TestCancel().

* Added missing override keywords to silent compiler warnings.

* Bumped version (2.1.1.svn54).

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2009 Grigor Iliev *
6 * Copyright (C) 2011-2013 Andreas Persson *
7 * Copyright (C) 2014-2020 Christian Schoenebeck *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
18 * *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program; if not, write to the Free Software *
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
22 * MA 02111-1307 USA *
23 ***************************************************************************/
24
25 #include "AudioOutputDeviceCoreAudio.h"
26
27 #include "../../common/global_private.h"
28
29 namespace LinuxSampler {
30
31 void AudioOutputDeviceCoreAudio::AudioQueueListener (
32 void *inUserData, AudioQueueRef inAQ, AudioQueuePropertyID inID
33 ) {
34 switch(inID) {
35 case kAudioQueueProperty_IsRunning:
36
37 break;
38 case kAudioQueueProperty_CurrentDevice:
39
40 break;
41 }
42 }
43
44 void AudioOutputDeviceCoreAudio::HandleOutputBuffer (
45 void *aqData,
46 AudioQueueRef inAQ,
47 AudioQueueBufferRef inBuffer
48 ) {
49 AQPlayerState* pAqData = (AQPlayerState*) aqData;
50 if (atomic_read(&(pAqData->mIsRunning)) == 0) {
51 AudioQueueFlush(pAqData->mQueue);
52 AudioQueueStop (pAqData->mQueue, true);
53 return;
54 }
55
56 if(atomic_read(&(pAqData->pDevice->restartQueue))) return;
57
58 uint bufferSize = pAqData->pDevice->uiBufferSize;
59
60 // let all connected engines render 'fragmentSize' sample points
61 pAqData->pDevice->RenderAudio(bufferSize);
62
63 Float32* pDataBuf = (Float32*)(inBuffer->mAudioData);
64
65 uint uiCoreAudioChannels = pAqData->pDevice->uiCoreAudioChannels;
66 for (int c = 0; c < uiCoreAudioChannels; c++) {
67 float* in = pAqData->pDevice->Channels[c]->Buffer();
68 for (int i = 0, o = c; i < bufferSize; i++ , o += uiCoreAudioChannels) {
69 pDataBuf[o] = in[i];
70 }
71 }
72
73 inBuffer->mAudioDataByteSize = (uiCoreAudioChannels * 4) * bufferSize;
74
75 OSStatus res = AudioQueueEnqueueBuffer(pAqData->mQueue, inBuffer, 0, NULL);
76 if(res) std::cerr << "AudioQueueEnqueueBuffer: Error " << res << std::endl;
77 }
78
79 void AudioOutputDeviceCoreAudio::DeviceChanged() {
80 dmsg(1,("Restarting audio queue..."));
81 atomic_set(&restartQueue, 1);
82 }
83
84 AudioOutputDeviceCoreAudio::AudioOutputDeviceCoreAudio (
85 std::map<String,DeviceCreationParameter*> Parameters
86 ) : AudioOutputDevice(Parameters), Thread(true, true, 1, 0), CurrentDevice(0) {
87
88 dmsg(2,("AudioOutputDeviceCoreAudio::AudioOutputDeviceCoreAudio()\n"));
89 if(CAAudioDeviceListModel::GetModel()->GetOutputDeviceCount() < 1) {
90 throw Exception("No audio output device found");
91 }
92 atomic_set(&pausedNew, 0);
93 pausedOld = 0;
94 atomic_set(&restartQueue, 0);
95
96 uiCoreAudioChannels = ((DeviceCreationParameterInt*)Parameters["CHANNELS"])->ValueAsInt();
97 uint samplerate = ((DeviceCreationParameterInt*)Parameters["SAMPLERATE"])->ValueAsInt();
98 uiBufferNumber = ((DeviceCreationParameterInt*)Parameters["BUFFERS"])->ValueAsInt();
99 uiBufferSize = ((DeviceCreationParameterInt*)Parameters["BUFFERSIZE"])->ValueAsInt();
100 int device = 0;
101 try { device = ((ParameterDevice*)Parameters["DEVICE"])->GetDeviceIndex(); }
102 catch(Exception x) { }
103
104 CurrentDevice = CAAudioDeviceListModel::GetModel()->GetOutputDevice(device);
105 CurrentDevice.AddListener(this);
106
107 memset (&aqPlayerState.mDataFormat, 0, sizeof(AudioStreamBasicDescription));
108
109 aqPlayerState.mDataFormat.mSampleRate = samplerate;
110 aqPlayerState.mDataFormat.mFormatID = kAudioFormatLinearPCM;
111
112 aqPlayerState.mDataFormat.mFormatFlags =
113 kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsPacked;
114
115 int samplesize = 4;
116 aqPlayerState.mDataFormat.mBytesPerPacket = uiCoreAudioChannels * samplesize;
117 aqPlayerState.mDataFormat.mFramesPerPacket = 1;
118 aqPlayerState.mDataFormat.mBytesPerFrame = uiCoreAudioChannels * samplesize;
119 aqPlayerState.mDataFormat.mChannelsPerFrame = uiCoreAudioChannels;
120 aqPlayerState.mDataFormat.mBitsPerChannel = 8 * samplesize;
121 aqPlayerState.mDataFormat.mReserved = 0;
122
123 aqPlayerState.mBuffers = new AudioQueueBufferRef[uiBufferNumber];
124
125 aqPlayerState.bufferByteSize =
126 MaxSamplesPerCycle() * aqPlayerState.mDataFormat.mBytesPerFrame;
127
128 aqPlayerState.mNumPacketsToRead = MaxSamplesPerCycle();
129
130 aqPlayerState.pDevice = this;
131 aqPlayerState.mQueue = NULL;
132
133 uint fragmentSize = MaxSamplesPerCycle();
134 // create audio channels for this audio device to which the sampler engines can write to
135 for (int i = 0; i < uiCoreAudioChannels; i++) {
136 this->Channels.push_back(new AudioChannel(i, fragmentSize));
137 }
138
139 StartThread();
140
141 if (!((DeviceCreationParameterBool*)Parameters["ACTIVE"])->ValueAsBool()) {
142 Stop();
143 }
144 }
145
146 AudioOutputDeviceCoreAudio::~AudioOutputDeviceCoreAudio() {
147 StopThread();
148
149 atomic_set(&(aqPlayerState.mIsRunning), 0);
150 {
151 LockGuard lock(destroyMutex);
152 AudioQueueDispose(aqPlayerState.mQueue, true);
153 }
154 delete [] aqPlayerState.mBuffers;
155
156 CurrentDevice.RemoveListener(this);
157 }
158
159 String AudioOutputDeviceCoreAudio::Name() {
160 return "COREAUDIO";
161 }
162
163 String AudioOutputDeviceCoreAudio::Description() {
164 return "Apple CoreAudio";
165 }
166
167 String AudioOutputDeviceCoreAudio::Version() {
168 String s = "$Revision$";
169 return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
170 }
171
172 void AudioOutputDeviceCoreAudio::Play() {
173 atomic_set(&pausedNew, 0);
174 }
175
176 bool AudioOutputDeviceCoreAudio::IsPlaying() {
177 return !atomic_read(&pausedNew);
178 }
179
180 void AudioOutputDeviceCoreAudio::Stop() {
181 atomic_set(&pausedNew, 1);
182 }
183
184 uint AudioOutputDeviceCoreAudio::MaxSamplesPerCycle() {
185 return uiBufferSize;
186 }
187
188 uint AudioOutputDeviceCoreAudio::SampleRate() {
189 return aqPlayerState.mDataFormat.mSampleRate;
190 }
191
192 String AudioOutputDeviceCoreAudio::Driver() {
193 return Name();
194 }
195
196 AudioChannel* AudioOutputDeviceCoreAudio::CreateChannel(uint ChannelNr) {
197 // just create a mix channel
198 return new AudioChannel(ChannelNr, Channel(ChannelNr % uiCoreAudioChannels));
199 }
200
201 void AudioOutputDeviceCoreAudio::FillBuffers() {
202 for (int i = 0; i < uiBufferNumber; ++i) {
203 HandleOutputBuffer (
204 &aqPlayerState,
205 aqPlayerState.mQueue,
206 aqPlayerState.mBuffers[i]
207 );
208 }
209 }
210
211 void AudioOutputDeviceCoreAudio::PrimeAudioQueue() {
212 OSStatus res = AudioQueuePrime(aqPlayerState.mQueue, 0, NULL);
213 if(res) {
214 String s = String("AudioQueuePrime: Error ") + ToString(res);
215 throw Exception(s);
216 }
217 }
218
219 void AudioOutputDeviceCoreAudio::CreateAndStartAudioQueue() throw(Exception) {
220 OSStatus res = AudioQueueNewOutput (
221 &aqPlayerState.mDataFormat,
222 HandleOutputBuffer,
223 &aqPlayerState,
224 CFRunLoopGetCurrent(),
225 kCFRunLoopCommonModes,
226 0,
227 &aqPlayerState.mQueue
228 );
229
230 if(res) {
231 String s = String("AudioQueueNewOutput: Error ") + ToString(res);
232 throw Exception(s);
233 }
234
235 CFStringRef devUID = CFStringCreateWithCString (
236 NULL, CurrentDevice.GetUID().c_str(), kCFStringEncodingASCII
237 );
238 res = AudioQueueSetProperty (
239 aqPlayerState.mQueue,
240 kAudioQueueProperty_CurrentDevice,
241 &devUID, sizeof(CFStringRef)
242 );
243 CFRelease(devUID);
244
245 if(res) {
246 String s = String("Failed to set audio device: ") + ToString(res);
247 throw Exception(s);
248 }
249
250 for (int i = 0; i < uiBufferNumber; ++i) {
251 res = AudioQueueAllocateBuffer (
252 aqPlayerState.mQueue,
253 aqPlayerState.bufferByteSize,
254 &aqPlayerState.mBuffers[i]
255 );
256
257 if(res) {
258 String s = String("AudioQueueAllocateBuffer: Error ");
259 throw Exception(s + ToString(res));
260 }
261 }
262
263 res = AudioQueueAddPropertyListener (
264 aqPlayerState.mQueue,
265 kAudioQueueProperty_CurrentDevice,
266 AudioQueueListener,
267 NULL
268 );
269 if(res) std::cerr << "Failed to register device change listener: " << res << std::endl;
270
271 res = AudioQueueAddPropertyListener (
272 aqPlayerState.mQueue,
273 kAudioQueueProperty_IsRunning,
274 AudioQueueListener,
275 NULL
276 );
277 if(res) std::cerr << "Failed to register running listener: " << res << std::endl;
278
279 Float32 gain = 1.0;
280
281 res = AudioQueueSetParameter (
282 aqPlayerState.mQueue,
283 kAudioQueueParam_Volume,
284 gain
285 );
286
287 if(res) std::cerr << "AudioQueueSetParameter: Error " << res << std::endl;
288
289 atomic_set(&(aqPlayerState.mIsRunning), 1);
290 FillBuffers();
291 PrimeAudioQueue();
292
293 res = AudioQueueStart(aqPlayerState.mQueue, NULL);
294 if(res) {
295 String s = String("AudioQueueStart: Error ") + ToString(res);
296 throw Exception(s);
297 }
298 }
299
300 void AudioOutputDeviceCoreAudio::DestroyAudioQueue() {
301 AudioQueueFlush(aqPlayerState.mQueue);
302 AudioQueueStop (aqPlayerState.mQueue, true);
303 AudioQueueDispose(aqPlayerState.mQueue, true);
304 aqPlayerState.mQueue = NULL;
305 }
306
307 /**
308 * Entry point for the thread.
309 */
310 int AudioOutputDeviceCoreAudio::Main() {
311 dmsg(1,("CoreAudio thread started\n"));
312
313 #if DEBUG
314 Thread::setNameOfCaller("CoreAudio");
315 #endif
316
317 OSStatus res;
318 if(aqPlayerState.mQueue == NULL) {
319 /*
320 * Need to be run from this thread because of CFRunLoopGetCurrent()
321 * which returns the CFRunLoop object for the current thread.
322 */
323 try { CreateAndStartAudioQueue(); }
324 catch(Exception e) {
325 std::cerr << "Failed to star audio queue: " + e.Message() << std::endl;
326 return 0;
327 }
328 }
329
330 {
331 LockGuard lock(destroyMutex);
332 do {
333 if(atomic_read(&pausedNew) != pausedOld) {
334 pausedOld = atomic_read(&pausedNew);
335
336 if(pausedOld) {
337 res = AudioQueuePause(aqPlayerState.mQueue);
338 if(res) std::cerr << "AudioQueuePause: Error " << res << std::endl;
339 } else {
340 res = AudioQueuePrime(aqPlayerState.mQueue, 0, NULL);
341 if(res) std::cerr << "AudioQueuePrime: Error " << res << std::endl;
342 res = AudioQueueStart(aqPlayerState.mQueue, NULL);
343 if(res) std::cerr << "AudioQueueStart: Error " << res << std::endl;
344 }
345 }
346
347 if(atomic_read(&restartQueue)) {
348 DestroyAudioQueue();
349 CreateAndStartAudioQueue();
350 atomic_set(&restartQueue, 0);
351 dmsg(1,("Audio queue restarted"));
352 }
353
354 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.2, false);
355 } while (atomic_read(&(aqPlayerState.mIsRunning)));
356 }
357
358 dmsg(2,("CoreAudio thread stopped\n"));
359
360 pthread_exit(NULL);
361 return 0;
362 }
363
364
365 // *************** ParameterDevice ***************
366 // *
367
368 AudioOutputDeviceCoreAudio::ParameterDevice::ParameterDevice() : DeviceCreationParameterString() {
369 InitWithDefault(); // use default device
370 }
371
372 AudioOutputDeviceCoreAudio::ParameterDevice::ParameterDevice(String s)
373 throw (Exception) : DeviceCreationParameterString(s) {
374 }
375
376 String AudioOutputDeviceCoreAudio::ParameterDevice::Description() {
377 return "Output device to be used";
378 }
379
380 bool AudioOutputDeviceCoreAudio::ParameterDevice::Fix() {
381 return true;
382 }
383
384 bool AudioOutputDeviceCoreAudio::ParameterDevice::Mandatory() {
385 return false;
386 }
387
388 std::map<String,DeviceCreationParameter*>
389 AudioOutputDeviceCoreAudio::ParameterDevice::DependsAsParameters() {
390 return std::map<String,DeviceCreationParameter*>(); // no dependencies
391 }
392
393 optional<String>
394 AudioOutputDeviceCoreAudio::ParameterDevice::DefaultAsString(std::map<String,String> Parameters) {
395 CAAudioDeviceListModel* devs = CAAudioDeviceListModel::GetModel();
396 if (devs->GetOutputDeviceCount() < 1) {
397 throw Exception("AudioOutputDeviceCoreAudio: Can't find any output device");
398 }
399 UInt32 idx = devs->GetOutputDeviceIndex(devs->GetDefaultOutputDeviceID());
400 return CreateDeviceName(idx);
401 }
402
403 std::vector<String>
404 AudioOutputDeviceCoreAudio::ParameterDevice::PossibilitiesAsString(std::map<String,String> Parameters) {
405 std::vector<String> deviceNames;
406
407 CAAudioDeviceListModel* devs = CAAudioDeviceListModel::GetModel();
408 for(int i = 0; i < devs->GetOutputDeviceCount(); i++) {
409 if(devs->GetOutputDevice(i).GetChannelNumber() < 1) continue;
410
411 deviceNames.push_back(CreateDeviceName(i));
412 }
413
414 return deviceNames;
415 }
416
417 String AudioOutputDeviceCoreAudio::ParameterDevice::CreateDeviceName(int devIndex) {
418 CAAudioDeviceListModel* devs = CAAudioDeviceListModel::GetModel();
419 // Note that the space " " is used as delimiter to obtain the
420 // device index. See GetDeviceIndex()
421 return ToString(devIndex + 1) + " " + devs->GetOutputDevice(devIndex).GetName();
422 }
423
424 void AudioOutputDeviceCoreAudio::ParameterDevice::OnSetValue(String s) throw (Exception) {
425 // not posssible, as parameter is fix
426 }
427
428 String AudioOutputDeviceCoreAudio::ParameterDevice::Name() {
429 return "DEVICE";
430 }
431
432 int AudioOutputDeviceCoreAudio::ParameterDevice::GetDeviceIndex() {
433 String s = ValueAsString();
434 if(s.empty()) return -1;
435 int n = (int) s.find(' ');
436 s = s.substr(0, n);
437 return ToInt(s) - 1;
438 }
439
440 // *************** ParameterSampleRate ***************
441 // *
442
443 AudioOutputDeviceCoreAudio::ParameterSampleRate::ParameterSampleRate() :
444 AudioOutputDevice::ParameterSampleRate::ParameterSampleRate() {
445
446 }
447
448 AudioOutputDeviceCoreAudio::ParameterSampleRate::ParameterSampleRate(String s) :
449 AudioOutputDevice::ParameterSampleRate::ParameterSampleRate(s) {
450
451 }
452
453 std::map<String,DeviceCreationParameter*>
454 AudioOutputDeviceCoreAudio::ParameterSampleRate::DependsAsParameters() {
455 static ParameterDevice device;
456 std::map<String,DeviceCreationParameter*> dependencies;
457 dependencies[device.Name()] = &device;
458 return dependencies;
459 }
460
461 optional<int>
462 AudioOutputDeviceCoreAudio::ParameterSampleRate::DefaultAsInt(std::map<String,String> Parameters) {
463 dmsg(2,("AudioOutputDeviceCoreAudio::ParameterSampleRate::DefaultAsInt()\n"));
464 ParameterDevice dev(Parameters["DEVICE"]);
465 int samplerate = 44100;
466
467 try {
468 int idx = dev.GetDeviceIndex();
469
470 CAAudioDeviceListModel* devs = CAAudioDeviceListModel::GetModel();
471 samplerate = devs->GetOutputDevice(idx).GetDefaultSamplerate();
472 } catch(Exception e) { }
473
474 return samplerate;
475 }
476
477 std::vector<int>
478 AudioOutputDeviceCoreAudio::ParameterSampleRate::PossibilitiesAsInt(std::map<String,String> Parameters) {
479 ParameterDevice dev(Parameters["DEVICE"]);
480 std::vector<int> srates;
481
482 try {
483 int idx = dev.GetDeviceIndex();
484 CAAudioDeviceListModel* devs = CAAudioDeviceListModel::GetModel();
485 srates = devs->GetOutputDevice(idx).GetNominalSamplerates();
486 } catch(Exception x) { }
487
488 return srates;
489 }
490
491
492 // *************** ParameterChannels ***************
493 // *
494
495 AudioOutputDeviceCoreAudio::ParameterChannels::ParameterChannels() :
496 AudioOutputDevice::ParameterChannels::ParameterChannels() {
497
498 }
499
500 AudioOutputDeviceCoreAudio::ParameterChannels::ParameterChannels(String s) :
501 AudioOutputDevice::ParameterChannels::ParameterChannels(s) {
502
503 }
504
505 optional<int>
506 AudioOutputDeviceCoreAudio::ParameterChannels::DefaultAsInt(std::map<String,String> Parameters) {
507 dmsg(2,("AudioOutputDeviceCoreAudio::ParameterChannels::DefaultAsInt()\n"));
508 ParameterDevice dev(Parameters["DEVICE"]);
509 int chns = 2;
510
511 try {
512 int idx = dev.GetDeviceIndex();
513 CAAudioDeviceListModel* devs = CAAudioDeviceListModel::GetModel();
514 chns = devs->GetOutputDevice(idx).GetChannelNumber();
515 } catch(Exception e) { }
516
517 return chns;
518 }
519
520 std::vector<int>
521 AudioOutputDeviceCoreAudio::ParameterChannels::PossibilitiesAsInt(std::map<String,String> Parameters) {
522 ParameterDevice dev(Parameters["DEVICE"]);
523 std::vector<int> chns;
524
525 try {
526 int idx = dev.GetDeviceIndex();
527 CAAudioDeviceListModel* devs = CAAudioDeviceListModel::GetModel();
528 for(int i = 1; i <= devs->GetOutputDevice(idx).GetChannelNumber(); i++) {
529 chns.push_back(i);
530 }
531 } catch(Exception x) { }
532
533 return chns;
534 }
535
536 // *************** ParameterBuffers ***************
537 // *
538
539 AudioOutputDeviceCoreAudio::ParameterBuffers::ParameterBuffers() : DeviceCreationParameterInt() {
540 InitWithDefault();
541 }
542
543 AudioOutputDeviceCoreAudio::ParameterBuffers::ParameterBuffers(String s)
544 throw (Exception) : DeviceCreationParameterInt(s) {
545 }
546
547 String AudioOutputDeviceCoreAudio::ParameterBuffers::Description() {
548 return "Number of audio buffer";
549 }
550
551 bool AudioOutputDeviceCoreAudio::ParameterBuffers::Fix() {
552 return true;
553 }
554
555 bool AudioOutputDeviceCoreAudio::ParameterBuffers::Mandatory() {
556 return false;
557 }
558
559 std::map<String,DeviceCreationParameter*>
560 AudioOutputDeviceCoreAudio::ParameterBuffers::DependsAsParameters() {
561 return std::map<String,DeviceCreationParameter*>();
562 }
563
564 optional<int>
565 AudioOutputDeviceCoreAudio::ParameterBuffers::DefaultAsInt(std::map<String,String> Parameters) {
566 return 3;
567 }
568
569 optional<int>
570 AudioOutputDeviceCoreAudio::ParameterBuffers::RangeMinAsInt(std::map<String,String> Parameters) {
571 return 2;
572 }
573
574 optional<int>
575 AudioOutputDeviceCoreAudio::ParameterBuffers::RangeMaxAsInt(std::map<String,String> Parameters) {
576 return 16;
577 }
578
579 std::vector<int>
580 AudioOutputDeviceCoreAudio::ParameterBuffers::PossibilitiesAsInt(std::map<String,String> Parameters) {
581 return std::vector<int>();
582 }
583
584 void AudioOutputDeviceCoreAudio::ParameterBuffers::OnSetValue(int i) throw (Exception) {
585 // not posssible, as parameter is fix
586 }
587
588 String AudioOutputDeviceCoreAudio::ParameterBuffers::Name() {
589 return "BUFFERS";
590 }
591
592 // *************** ParameterBufferSize ***************
593 // *
594
595 AudioOutputDeviceCoreAudio::ParameterBufferSize::ParameterBufferSize() : DeviceCreationParameterInt() {
596 InitWithDefault();
597 }
598
599 AudioOutputDeviceCoreAudio::ParameterBufferSize::ParameterBufferSize(String s)
600 throw (Exception) : DeviceCreationParameterInt(s) {
601 }
602
603 String AudioOutputDeviceCoreAudio::ParameterBufferSize::Description() {
604 return "Size of the audio buffer in sample frames";
605 }
606
607 bool AudioOutputDeviceCoreAudio::ParameterBufferSize::Fix() {
608 return true;
609 }
610
611 bool AudioOutputDeviceCoreAudio::ParameterBufferSize::Mandatory() {
612 return false;
613 }
614
615 std::map<String,DeviceCreationParameter*>
616 AudioOutputDeviceCoreAudio::ParameterBufferSize::DependsAsParameters() {
617 return std::map<String,DeviceCreationParameter*>();
618 }
619
620 optional<int>
621 AudioOutputDeviceCoreAudio::ParameterBufferSize::DefaultAsInt(std::map<String,String> Parameters) {
622 return 256;
623 }
624
625 optional<int>
626 AudioOutputDeviceCoreAudio::ParameterBufferSize::RangeMinAsInt(std::map<String,String> Parameters) {
627 return 32;
628 }
629
630 optional<int>
631 AudioOutputDeviceCoreAudio::ParameterBufferSize::RangeMaxAsInt(std::map<String,String> Parameters) {
632 return 4096;
633 }
634
635 std::vector<int>
636 AudioOutputDeviceCoreAudio::ParameterBufferSize::PossibilitiesAsInt(std::map<String,String> Parameters) {
637 return std::vector<int>();
638 }
639
640 void AudioOutputDeviceCoreAudio::ParameterBufferSize::OnSetValue(int i) throw (Exception) {
641 // not posssible, as parameter is fix
642 }
643
644 String AudioOutputDeviceCoreAudio::ParameterBufferSize::Name() {
645 return "BUFFERSIZE";
646 }
647 } // namespace LinuxSampler

Properties

Name Value
svn:keywords Revision

  ViewVC Help
Powered by ViewVC