forked from AlexBelchUK/PortAudioBindingsForDart
-
Notifications
You must be signed in to change notification settings - Fork 0
/
port_audio.dart
1729 lines (1518 loc) · 60.2 KB
/
port_audio.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
///
/// Port Audio Mappings
///
library port_audio;
import 'dart:convert';
import 'dart:ffi';
import 'dart:io' show Platform;
import 'dart:isolate';
import 'package:ffi/ffi.dart';
///
/// Mapping class to native audio library
///
class PortAudio {
static bool _loaded = false;
// Port Audio Helper Library
static late int Function(Pointer<Void>) _PaGetVersion;
static late Pointer<Utf8> Function(Pointer<Void>) _PaGetVersionText;
static late Pointer<VersionInfo> Function(Pointer<Void>) _PaGetVersionInfo;
static late Pointer<Utf8> Function(int) _PaGetErrorText;
static late int Function(Pointer<Void>) _PaInitialize;
static late int Function(Pointer<Void>) _PaTerminate;
static late int Function(Pointer<Void>) _PaGetHostApiCount;
static late int Function(Pointer<Void>) _PaGetDefaultHostApi;
static late Pointer<HostApiInfo> Function(int) _PaGetHostApiInfo;
static late int Function(int) _PaHostApiTypeIdToHostApiIndex;
static late int Function(int, int) _PaHostApiDeviceIndexToDeviceIndex;
static late Pointer<HostErrorInfo> Function(Pointer<Void>) _PaGetLastHostErrorInfo;
static late int Function(Pointer<Void>) _PaGetDeviceCount;
static late int Function(Pointer<Void>) _PaGetDefaultInputDevice;
static late int Function(Pointer<Void>) _PaGetDefaultOutputDevice;
static late Pointer<DeviceInfo> Function(int) _PaGetDeviceInfo;
static late int Function(Pointer<StreamParameters>, Pointer<StreamParameters>, double)
_PaIsFormatSupported;
static late int Function(
Pointer<Pointer<Void>>,
Pointer<StreamParameters>,
Pointer<StreamParameters>,
double,
int,
int,
Pointer<NativeFunction<StreamCallback>>,
Pointer<Void>) _PaOpenStream;
static late int Function(
Pointer<Pointer<Void>>,
int,
int,
int,
double,
int,
Pointer<NativeFunction<StreamCallback>>,
Pointer<Void>) _PaOpenDefaultStream;
static late int Function(Pointer<Void>) _PaCloseStream;
static late int Function(Pointer<Void>, Pointer<NativeFunction<StreamFinishedCallback>>)
_PaSetStreamFinishedCallback;
static late int Function(Pointer<Void>) _PaStartStream;
static late int Function(Pointer<Void>) _PaStopStream;
static late int Function(Pointer<Void>) _PaAbortStream;
static late int Function(Pointer<Void>) _PaIsStreamStopped;
static late int Function(Pointer<Void>) _PaIsStreamActive;
static late Pointer<StreamInfo> Function(Pointer<Void>) _PaGetStreamInfo;
static late double Function(Pointer<Void>) _PaGetStreamTime;
static late double Function(Pointer<Void>) _PaGetStreamCpuLoad;
static late int Function(Pointer<Void>, Pointer<Void>, int) _PaReadStream;
static late int Function(Pointer<Void>, Pointer<Void>, int) _PaWriteStream;
static late int Function(Pointer<Void>) _PaGetStreamReadAvailable;
static late int Function(Pointer<Void>) _PaGetStreamWriteAvailable;
static late int Function(int) _PaGetSampleSize;
static late void Function(int) _PaSleep;
// Port Audio Helper Library
static late Pointer<NativeFunction<StreamCallback>> Function(int) _PahGetStreamCallback;
static late void Function(int) _PahSetStreamResult;
static late Pointer<NativeFunction<StreamFinishedCallback>> Function(int) _PahGetStreamFinishedCallback;
// Callbacks
///
/// Contructor loads the library and looks up functions
/// according to their function signtature and name
///
const PortAudio();
static void _load() {
var bits = 'x64';
if (sizeOf<IntPtr>() == 4) {
bits = 'x86';
}
// Port Audio Library ----------------------------------------------------
String paPath = '';
if (Platform.environment['PORT_AUDIO_LIBRARY'] != null) {
paPath = Platform.environment['PORT_AUDIO_LIBRARY']!;
} else if (Platform.isWindows) {
paPath = 'native/windows/portaudio_' + bits + '.dll';
} else if (Platform.isMacOS) {
paPath = 'native/mac/libportaudio_' + bits + '.dynlib';
} else if (Platform.isLinux) {
paPath = 'native/linux/libportaudio_' + bits + '.so';
} else {
throw Exception(
'PortAudio: Unsupported platform, try specifying environment variable PORT_AUDIO_LIBRARY');
}
paPath = "/usr/lib/libportaudio.so";
final paLib = DynamicLibrary.open(paPath);
_PaGetVersion = paLib
.lookup<NativeFunction<Int32 Function(Pointer<Void>)>>('Pa_GetVersion')
.asFunction();
_PaGetVersionText = paLib
.lookup<NativeFunction<Pointer<Utf8> Function(Pointer<Void>)>>(
'Pa_GetVersionText')
.asFunction();
_PaGetVersionInfo = paLib
.lookup<NativeFunction<Pointer<VersionInfo> Function(Pointer<Void>)>>(
'Pa_GetVersionInfo')
.asFunction();
_PaGetErrorText = paLib
.lookup<NativeFunction<Pointer<Utf8> Function(Int32)>>(
'Pa_GetErrorText')
.asFunction();
_PaInitialize = paLib
.lookup<NativeFunction<Int32 Function(Pointer<Void>)>>('Pa_Initialize')
.asFunction();
_PaTerminate = paLib
.lookup<NativeFunction<Int32 Function(Pointer<Void>)>>('Pa_Terminate')
.asFunction();
_PaGetHostApiCount = paLib
.lookup<NativeFunction<Int32 Function(Pointer<Void>)>>('Pa_GetHostApiCount')
.asFunction();
_PaGetDefaultHostApi = paLib
.lookup<NativeFunction<Int32 Function(Pointer<Void>)>>('Pa_GetDefaultHostApi')
.asFunction();
_PaGetHostApiInfo = paLib
.lookup<NativeFunction<Pointer<HostApiInfo> Function(Int32)>>(
'Pa_GetHostApiInfo')
.asFunction();
_PaHostApiTypeIdToHostApiIndex = paLib
.lookup<NativeFunction<Int32 Function(Int32)>>(
'Pa_HostApiTypeIdToHostApiIndex')
.asFunction();
_PaHostApiDeviceIndexToDeviceIndex = paLib
.lookup<NativeFunction<Int32 Function(Int32, Int32)>>(
'Pa_HostApiDeviceIndexToDeviceIndex')
.asFunction();
_PaGetLastHostErrorInfo = paLib
.lookup<NativeFunction<Pointer<HostErrorInfo> Function(Pointer<Void>)>>(
'Pa_GetLastHostErrorInfo')
.asFunction();
_PaGetDeviceCount = paLib
.lookup<NativeFunction<Int32 Function(Pointer<Void>)>>('Pa_GetDeviceCount')
.asFunction();
_PaGetDefaultInputDevice = paLib
.lookup<NativeFunction<Int32 Function(Pointer<Void>)>>(
'Pa_GetDefaultInputDevice')
.asFunction();
_PaGetDefaultOutputDevice = paLib
.lookup<NativeFunction<Int32 Function(Pointer<Void>)>>(
'Pa_GetDefaultOutputDevice')
.asFunction();
_PaGetDeviceInfo = paLib
.lookup<NativeFunction<Pointer<DeviceInfo> Function(Int32)>>(
'Pa_GetDeviceInfo')
.asFunction();
_PaIsFormatSupported = paLib
.lookup<
NativeFunction<
Int32 Function(Pointer<StreamParameters>,
Pointer<StreamParameters>, Double)>>('Pa_IsFormatSupported')
.asFunction();
_PaOpenStream = paLib
.lookup<
NativeFunction<
Int32 Function(
Pointer<Pointer<Void>>,
Pointer<StreamParameters>,
Pointer<StreamParameters>,
Double,
Int32,
Int32,
Pointer<NativeFunction<StreamCallback>>,
Pointer<Void>)>>('Pa_OpenStream')
.asFunction();
_PaOpenDefaultStream = paLib
.lookup<
NativeFunction<
Int32 Function(
Pointer<Pointer<Void>>,
Int32,
Int32,
Int32,
Double,
Int32,
Pointer<NativeFunction<StreamCallback>>,
Pointer<Void>)>>('Pa_OpenDefaultStream')
.asFunction();
_PaCloseStream = paLib
.lookup<NativeFunction<Int32 Function(Pointer<Void>)>>('Pa_CloseStream')
.asFunction();
_PaSetStreamFinishedCallback = paLib
.lookup<
NativeFunction<
Int32 Function(Pointer<Void>,
Pointer<NativeFunction<StreamFinishedCallback>>)>>(
'Pa_SetStreamFinishedCallback')
.asFunction();
_PaStartStream = paLib
.lookup<NativeFunction<Int32 Function(Pointer<Void>)>>('Pa_StartStream')
.asFunction();
_PaStopStream = paLib
.lookup<NativeFunction<Int32 Function(Pointer<Void>)>>('Pa_StopStream')
.asFunction();
_PaAbortStream = paLib
.lookup<NativeFunction<Int32 Function(Pointer<Void>)>>('Pa_AbortStream')
.asFunction();
_PaIsStreamStopped = paLib
.lookup<NativeFunction<Int32 Function(Pointer<Void>)>>(
'Pa_IsStreamStopped')
.asFunction();
_PaIsStreamActive = paLib
.lookup<NativeFunction<Int32 Function(Pointer<Void>)>>(
'Pa_IsStreamActive')
.asFunction();
_PaGetStreamInfo = paLib
.lookup<NativeFunction<Pointer<StreamInfo> Function(Pointer<Void>)>>(
'Pa_GetStreamInfo')
.asFunction();
_PaGetStreamTime = paLib
.lookup<NativeFunction<Double Function(Pointer<Void>)>>(
'Pa_GetStreamTime')
.asFunction();
_PaGetStreamCpuLoad = paLib
.lookup<NativeFunction<Double Function(Pointer<Void>)>>(
'Pa_GetStreamCpuLoad')
.asFunction();
_PaReadStream = paLib
.lookup<
NativeFunction<
Int32 Function(
Pointer<Void>, Pointer<Void>, Int32)>>('Pa_ReadStream')
.asFunction();
_PaWriteStream = paLib
.lookup<
NativeFunction<
Int32 Function(
Pointer<Void>, Pointer<Void>, Int32)>>('Pa_WriteStream')
.asFunction();
_PaGetStreamReadAvailable = paLib
.lookup<NativeFunction<Int32 Function(Pointer<Void>)>>(
'Pa_GetStreamReadAvailable')
.asFunction();
_PaGetStreamWriteAvailable = paLib
.lookup<NativeFunction<Int32 Function(Pointer<Void>)>>(
'Pa_GetStreamWriteAvailable')
.asFunction();
_PaGetSampleSize = paLib
.lookup<NativeFunction<Int32 Function(Int32)>>('Pa_GetSampleSize')
.asFunction();
_PaSleep = paLib
.lookup<NativeFunction<Void Function(Int32)>>('Pa_Sleep')
.asFunction();
// Port Audio Helper Library ---------------------------------------------
var pahPath = '';
if (Platform.environment['PORT_AUDIO_HELPER_LIBRARY'] != null) {
pahPath = Platform.environment['PORT_AUDIO_HELPER_LIBRARY']!;
} else if (Platform.isWindows) {
pahPath = 'native/windows/port_audio_helper_' + bits + '.dll';
} else if (Platform.isMacOS) {
pahPath = 'native/mac/libportaudiohelper_' + bits + '.dynlib';
} else if (Platform.isLinux) {
pahPath = 'native/linux/libportaudiohelper_' + bits + '.so';
} else {
throw Exception(
'PortAudio: Unsupported platform, try specifying environment variable PORT_AUDIO_HELPER_LIBRARY');
}
pahPath = "lib/libport_audio.so";
final pahLib = DynamicLibrary.open(pahPath);
_PahGetStreamCallback = pahLib
.lookup<NativeFunction<Pointer<NativeFunction<StreamCallback>> Function(Int64)>>('Pah_GetStreamCallback')
.asFunction();
_PahSetStreamResult = pahLib
.lookup<NativeFunction<Void Function(Int64)>>('Pah_SetStreamResult')
.asFunction();
_PahGetStreamFinishedCallback = pahLib
.lookup<NativeFunction<Pointer<NativeFunction<StreamFinishedCallback>> Function(Int64)>>('Pah_GetStreamFinishedCallback')
.asFunction();
_loaded = true;
}
///
/// Retrieve the release number of the currently running PortAudio build.
/// For example, for version "19.5.1" this will return 0x00130501.
///
static int getVersion() {
if (! _loaded) {
_load();
}
return _PaGetVersion(nullptr);
}
///
/// Retrieve a textual description of the current PortAudio build,
/// e.g. "PortAudio V19.5.0-devel, revision 1952M".
///
/// The format of the text may change in the future. Do not try to parse the
/// returned string.
///
/// As of 19.5.0, use GetVersionInfo()->versionText instead.
///
static String getVersionText() {
if (! _loaded) {
_load();
}
var textPtr = _PaGetVersionText(nullptr);
return textPtr.toDartString();
}
///
/// Retrieve version information for the currently running PortAudio build.
/// A class instance to an immutable PaVersionInfo structure.
///
/// This function can be called at any time. It does not require PortAudio
/// to be initialized. The structure pointed to is statically allocated.
///
/// See PaVersionInfo
///
static VersionInfo getVersionInfo() {
if (! _loaded) {
_load();
}
return _PaGetVersionInfo(nullptr).ref;
}
///
/// Translate the supplied PortAudio error code into a human readable
/// message.
///
static String getErrorText(int errorCode) {
if (! _loaded) {
_load();
}
var textPtr = _PaGetErrorText(errorCode);
return textPtr.toDartString();
}
///
/// Library initialization function - call this before using PortAudio.
/// This function initializes internal data structures and prepares underlying
/// host APIs for use. With the exception of GetVersion(), PGetVersionText()
/// and GetErrorText(), this function MUST be called before using any other
/// PortAudio API functions.
///
/// If Initialize() is called multiple times, each successful
/// call must be matched with a corresponding call to Terminate().
/// Pairs of calls to Initialize()/Terminate() may overlap, and are not
/// required to be fully nested.
///
/// Note that if Initialize() returns an error code, Terminate() should
/// NOT be called.
/// NoError if successful, otherwise an error code indicating the cause
/// of failure.
///
/// See Terminate
///
static int initialize() {
if (! _loaded) {
_load();
}
return _PaInitialize(nullptr);
}
/// Library termination function - call this when finished using PortAudio.
/// This function deallocates all resources allocated by PortAudio since it was
/// initialized by a call to Initialize(). In cases where Initialise() has
/// been called multiple times, each call must be matched with a corresponding call
/// to Terminate(). The final matching call to Terminate() will automatically
/// close any PortAudio streams that are still open.
///
/// Terminate() MUST be called before exiting a program which uses PortAudio.
/// Failure to do so may result in serious resource leaks, such as audio devices
/// not being available until the next reboot.
///
/// return NoError if successful, otherwise an error code indicating the cause
/// of failure.
///
/// See Initialize
///
static int terminate() {
if (! _loaded) {
_load();
}
return _PaTerminate(nullptr);
}
///
/// Retrieve the number of available host APIs. Even if a host API is
/// available it may have no devices available.
///
/// Return a non-negative value indicating the number of available host APIs
/// or, a PaErrorCode (which are always negative) if PortAudio is not initialized
/// or an error is encountered.
///
static int getHostApiCount() {
if (! _loaded) {
_load();
}
return _PaGetHostApiCount(nullptr);
}
///
/// Retrieve the index of the default host API. The default host API will be
/// the lowest common denominator host API on the current platform and is
/// unlikely to provide the best performance.
///
/// Return a non-negative value ranging from 0 to (GetHostApiCount()-1)
/// indicating the default host API index or, a PaErrorCode (which are always
/// negative) if PortAudio is not initialized or an error is encountered.
///
static int getDefaultHostApi() {
if (! _loaded) {
_load();
}
return _PaGetDefaultHostApi(nullptr);
}
///
/// Retrieve a pointer to a structure containing information about a specific
/// host Api.
///
/// [hostApi] A valid host API index ranging from 0 to (GetHostApiCount()-1)
///
/// Return a pointer to an immutable PaHostApiInfo structure describing
/// a specific host API. If the hostApi parameter is out of range or an error
/// is encountered, the function returns NULL.
///
/// The returned structure is owned by the PortAudio implementation and must not
/// be manipulated or freed. The pointer is only guaranteed to be valid between
/// calls to Initialize() and Terminate().
///
static HostApiInfo getHostApiInfo(int hostApi) {
if (! _loaded) {
_load();
}
return _PaGetHostApiInfo(hostApi).ref;
}
///
/// Convert a static host API unique identifier, into a runtime
/// host API index.
/// [type] A unique host API identifier belonging to the PaHostApiTypeId
/// enumeration.
///
/// Return a valid PaHostApiIndex ranging from 0 to (GetHostApiCount()-1) or,
/// a PaErrorCode (which are always negative) if PortAudio is not initialized
/// or an error is encountered.
///
/// The hostApiNotFound error code indicates that the host API specified by the
/// type parameter is not available.
///
static int hostApiTypeIdToHostApiIndex(int type) {
if (! _loaded) {
_load();
}
return _PaHostApiTypeIdToHostApiIndex(type);
}
///
/// Convert a host-API-specific device index to standard PortAudio device index.
/// This function may be used in conjunction with the deviceCount field of
/// PaHostApiInfo to enumerate all devices for the specified host API.
///
/// [hostApi] A valid host API index ranging from 0 to (GetHostApiCount()-1)
///
/// [hostApiDeviceIndex] A valid per-host device index in the range
/// 0 to (GetHostApiInfo(hostApi)->deviceCount-1)
///
/// Return a non-negative PaDeviceIndex ranging from 0 to (GetDeviceCount()-1)
/// or, a PaErro rCode (which are always negative) if PortAudio is not initialized
/// or an error is encountered.
///
/// A invalidHostApi error code indicates that the host API index specified by
/// the hostApi parameter is out of range.
///
/// A invalidDevice error code indicates that the hostApiDeviceIndex parameter
/// is out of range.
///
static int hostApiDeviceIndexToDeviceIndex(int hostApi, int hostApiDeviceIndex) {
if (! _loaded) {
_load();
}
return _PaHostApiDeviceIndexToDeviceIndex(hostApi, hostApiDeviceIndex);
}
///
/// Return information about the last host error encountered. The error
/// information returned by GetLastHostErrorInfo() will never be modified
/// asynchronously by errors occurring in other PortAudio owned threads
/// (such as the thread that manages the stream callback.)
///
/// This function is provided as a last resort, primarily to enhance debugging
/// by providing clients with access to all available error information.
///
/// Return a pointer to an immutable structure constraining information about
/// the host error. The values in this structure will only be valid if a
/// PortAudio function has previously returned the unanticipatedHostError
/// error code.
static HostErrorInfo getLastHostErrorInfo() {
if (! _loaded) {
_load();
}
return _PaGetLastHostErrorInfo(nullptr).ref;
}
///
/// Retrieve the number of available devices. The number of available devices
/// may be zero.
///
/// Return a non-negative value indicating the number of available devices or,
/// a PaErrorCode (which are always negative) if PortAudio is not initialized
/// or an error is encountered.
///
static int getDeviceCount() {
if (! _loaded) {
_load();
}
return _PaGetDeviceCount(nullptr);
}
///
/// Retrieve the index of the default input device. The result can be
/// used in the inputDevice parameter to OpenStream().
/// Return The default input device index for the default host API, or noDevice
/// if no default input device is available or an error was encountered.
///
static int getDefaultInputDevice() {
if (! _loaded) {
_load();
}
return _PaGetDefaultInputDevice(nullptr);
}
///
/// Retrieve the index of the default output device. The result can be
/// used in the outputDevice parameter to OpenStream().
///
/// Return The default output device index for the default host API, or noDevice
/// if no default output device is available or an error was encountered.
///
/// Note
/// On the PC, the user can specify a default device by
/// setting an environment variable. For example, to use device #1.
/// <pre>
/// set PA_RECOMMENDED_OUTPUT_DEVICE=1
/// </pre>
///
static int getDefaultOutputDevice() {
if (! _loaded) {
_load();
}
return _PaGetDefaultOutputDevice(nullptr);
}
///
/// Retrieve a pointer to a PaDeviceInfo structure containing information
/// about the specified device.
/// Return a pointer to an immutable PaDeviceInfo structure. If the device
/// parameter is out of range the function returns NULL.
///
/// [device] A valid device index in the range 0 to (GetDeviceCount()-1)
///
/// Note PortAudio manages the memory referenced by the returned pointer,
/// the client must not manipulate or free the memory. The pointer is only
/// guaranteed to be valid between calls to Initialize() and Terminate().
///
static DeviceInfo getDeviceInfo(int device) {
if (! _loaded) {
_load();
}
return _PaGetDeviceInfo(device).ref;
}
///
/// Determine whether it would be possible to open a stream with the specified
/// parameters.
/// [inputParameters] A structure that describes the input parameters used to
/// open a stream. The suggestedLatency field is ignored. See PaStreamParameters
/// for a description of these parameters. inputParameters must be NULL for
/// output-only streams.
///
/// [outputParameters] A structure that describes the output parameters used
/// to open a stream. The suggestedLatency field is ignored. See PaStreamParameters
/// for a description of these parameters. outputParameters must be NULL for
/// input-only streams.
///
/// [sampleRate] The required sampleRate. For full-duplex streams it is the
/// sample rate for both input and output
///
/// Returns 0 if the format is supported, and an error code indicating why
/// the format is not supported otherwise. The constant formatIsSupported is
/// provided to compare with the return value for success.
///
static int isFormatSupported(Pointer<StreamParameters>? inputParameters,
Pointer<StreamParameters>? outputParameters, double sampleRate) {
if (! _loaded) {
_load();
}
return _PaIsFormatSupported(
inputParameters ?? nullptr, outputParameters ?? nullptr, sampleRate);
}
/// Opens a stream for either input, output or both.
///
/// [stream] The address of a PaStream pointer which will receive
/// a pointer to the newly opened stream.
/// [inputParameters] A structure that describes the input parameters used by
/// the opened stream. See PaStreamParameters for a description of these parameters.
/// inputParameters must be NULL for output-only streams.
///
/// [outputParameters] A structure that describes the output parameters used by
/// the opened stream. See PaStreamParameters for a description of these parameters.
/// outputParameters must be NULL for input-only streams.
///
/// [sampleRate] The desired sampleRate. For full-duplex streams it is the
/// sample rate for both input and output
///
/// [framesPerBuffer] The number of frames passed to the stream callback
/// function, or the preferred block granularity for a blocking read/write stream.
/// The special value framesPerBufferUnspecified (0) may be used to request that
/// the stream callback will receive an optimal (and possibly varying) number of
/// frames based on host requirements and the requested latency settings.
/// Note: With some host APIs, the use of non-zero framesPerBuffer for a callback
/// stream may introduce an additional layer of buffering which could introduce
/// additional latency. PortAudio guarantees that the additional latency
/// will be kept to the theoretical minimum however, it is strongly recommended
/// that a non-zero framesPerBuffer value only be used when your algorithm
/// requires a fixed number of frames per stream callback.
///
/// [streamFlags] Flags which modify the behavior of the streaming process.
/// This parameter may contain a combination of flags ORed together. Some flags may
/// only be relevant to certain buffer formats.
///
/// [streamCallback] A pointer to a client supplied function that is responsible
/// for processing and filling input and output buffers. If this parameter is NULL
/// the stream will be opened in 'blocking read/write' mode. In blocking mode,
/// the client can receive sample data using ReadStream and write sample data
/// using WriteStream, the number of samples that may be read or written
/// without blocking is returned by GetStreamReadAvailable and
/// GetStreamWriteAvailable respectively.
///
/// [userData] A client supplied pointer which is passed to the stream callback
/// function. It could for example, contain a pointer to instance data necessary
/// for processing the audio buffers. This parameter is ignored if streamCallback
/// is NULL.
///
/// Return
/// Upon success OpenStream() returns noError and places a pointer to a
/// valid PaStream in the stream argument. The stream is inactive (stopped).
/// If a call to OpenStream() fails, a non-zero error code is returned (see
/// PaError for possible error codes) and the value of stream is invalid.
///
static int openStream(
Pointer<Pointer<Void>> stream,
Pointer<StreamParameters> inputParameters,
Pointer<StreamParameters> outputParameters,
double sampleRate,
int framesPerBuffer,
int streamFlags,
SendPort? sendPort,
Pointer<Void> userData) {
if (! _loaded) {
_load();
}
Pointer<NativeFunction<StreamCallback>> streamCallback = nullptr;
if (sendPort != null) {
streamCallback = _PahGetStreamCallback(sendPort.nativePort);
}
return _PaOpenStream(
stream,
inputParameters ?? nullptr,
outputParameters ?? nullptr,
sampleRate,
framesPerBuffer,
streamFlags,
streamCallback,
userData ?? nullptr);
}
/// A simplified version of OpenStream() that opens the default input
/// and/or output devices.
///
/// [stream] The address of a PaStream pointer which will receive
/// a pointer to the newly opened stream.
///
/// [numInputChannels] The number of channels of sound that will be supplied
/// to the stream callback or returned by ReadStream. It can range from 1 to
/// the value of maxInputChannels in the PaDeviceInfo record for the default input
/// device. If 0 the stream is opened as an output-only stream.
///
/// [numOutputChannels] The number of channels of sound to be delivered to the
/// stream callback or passed to WriteStream. It can range from 1 to the value
/// of maxOutputChannels in the PaDeviceInfo record for the default output device.
/// If 0 the stream is opened as an output-only stream.
///
/// [sampleFormat] The sample format of both the input and output buffers
/// provided to the callback or passed to and from ReadStream and WriteStream.
/// sampleFormat may be any of the formats described by the PaSampleFormat
/// enumeration.
///
/// [sampleRate] Same as OpenStream parameter of the same name.
/// [framesPerBuffer] Same as OpenStream parameter of the same name.
/// [streamCallback] Same as OpenStream parameter of the same name.
/// [userData] Same as OpenStream parameter of the same name.
///
/// Return As for OpenStream
///
static int openDefaultStream(
Pointer<Pointer<Void>> stream,
int numInputChannels,
int numOutputChannels,
int sampleFormat,
double sampleRate,
int framesPerBuffer,
SendPort? sendPort,
Pointer<Void>? userData) {
if (! _loaded) {
_load();
}
var streamCallback ;
if (sendPort != null) {
streamCallback = _PahGetStreamCallback(sendPort.nativePort);
} else {
streamCallback = nullptr;
}
return _PaOpenDefaultStream(
stream,
numInputChannels,
numOutputChannels,
sampleFormat,
sampleRate,
framesPerBuffer,
streamCallback,
userData ?? nullptr);
}
///
/// Call the return function, passing result code
///
static void setStreamResult(int result) {
if (! _loaded) {
_load();
}
_PahSetStreamResult(result);
}
///
/// Closes an audio stream. If the audio stream is active it
/// discards any pending buffers as if AbortStream() had been called.
///
static int closeStream(Pointer<Pointer<Void>> stream) {
if (! _loaded) {
_load();
}
return _PaCloseStream(stream.value);
}
///
/// Register a stream finished callback function which will be called when the
/// stream becomes inactive. See the description of PaStreamFinishedCallback for
/// further details about when the callback will be called.
///
/// [stream] a pointer to a PaStream that is in the stopped state - if the
/// stream is not stopped, the stream's finished callback will remain unchanged
/// and an error code will be returned.
///
/// [streamFinishedCallback] a pointer to a function with the same signature
/// as PaStreamFinishedCallback, that will be called when the stream becomes
/// inactive. Passing NULL for this parameter will un-register a previously
/// registered stream finished callback function.
///
/// Return on success returns noError, otherwise an error code indicating the cause
/// of the error.
///
static int setStreamFinishedCallback(Pointer<Pointer<Void>> stream,
SendPort? sendPort) {
if (! _loaded) {
_load();
}
var streamFinishedCallback;
if (sendPort != null) {
streamFinishedCallback = _PahGetStreamFinishedCallback(sendPort.nativePort);
} else {
streamFinishedCallback = nullptr;
}
return _PaSetStreamFinishedCallback(
stream.value, streamFinishedCallback);
}
///
/// Commences audio processing.
///
static int startStream(Pointer<Pointer<Void>> stream) {
if (! _loaded) {
_load();
}
return _PaStartStream(stream.value);
}
///
/// Terminates audio processing. It waits until all pending
/// audio buffers have been played before it returns.
///
static int stopStream(Pointer<Pointer<Void>> stream) {
if (! _loaded) {
_load();
}
return _PaStopStream(stream.value);
}
///
/// Terminates audio processing immediately without waiting for pending
/// buffers to complete.
///
static int abortStream(Pointer<Pointer<Void>> stream) {
if (! _loaded) {
_load();
}
return _PaAbortStream(stream.value);
}
///
/// Determine whether the stream is stopped.
/// A stream is considered to be stopped prior to a successful call to
/// StartStream and after a successful call to StopStream or AbortStream.
/// If a stream callback returns a value other than continue the stream is NOT
/// considered to be stopped.
///
/// Returns one (1) when the stream is stopped, zero (0) when
/// the stream is running or, a PaErrorCode (which are always negative) if
/// PortAudio is not initialized or an error is encountered.
///
static int isStreamStopped(Pointer<Pointer<Void>> stream) {
if (! _loaded) {
_load();
}
return _PaIsStreamStopped(stream.value);
}
///
/// Determine whether the stream is active.
/// A stream is active after a successful call to StartStream(), until it
/// becomes inactive either as a result of a call to StopStream() or
/// AbortStream(), or as a result of a return value other than continue from
/// the stream callback. In the latter case, the stream is considered inactive
/// after the last buffer has finished playing.
///
/// Returns one (1) when the stream is active (ie playing or recording
/// audio), zero (0) when not playing or, a PaErrorCode (which are always negative)
/// if PortAudio is not initialized or an error is encountered.
///
static int isStreamActive(Pointer<Pointer<Void>> stream) {
if (! _loaded) {
_load();
}
return _PaIsStreamActive(stream.value);
}
///
/// Retrieve a pointer to a PaStreamInfo structure containing information
/// about the specified stream.
/// Return A pointer to an immutable PaStreamInfo structure. If the stream
/// parameter is invalid, or an error is encountered, the function returns NULL.
///
/// [stream] A pointer to an open stream previously created with OpenStream.
///
/// Note PortAudio manages the memory referenced by the returned pointer,
/// the client must not manipulate or free the memory. The pointer is only
/// guaranteed to be valid until the specified stream is closed.
///
static StreamInfo getStreamInfo(Pointer<Pointer<Void>> stream) {
if (! _loaded) {
_load();
}
return _PaGetStreamInfo(stream.value).ref;
}
///
/// Returns the current time in seconds for a stream according to the same clock used
/// to generate callback PaStreamCallbackTimeInfo timestamps. The time values are
/// monotonically increasing and have unspecified origin.
///
/// GetStreamTime returns valid time values for the entire life of the stream,
/// from when the stream is opened until it is closed. Starting and stopping the stream
/// does not affect the passage of time returned by GetStreamTime.
///
/// This time may be used for synchronizing other events to the audio stream, for
/// example synchronizing audio to MIDI.
///
/// Return The stream's current time in seconds, or 0 if an error occurred.
///
static double getStreamTime(Pointer<Pointer<Void>> stream) {
if (! _loaded) {
_load();
}
return _PaGetStreamTime(stream.value);
}
///
/// Retrieve CPU usage information for the specified stream.
/// The "CPU Load" is a fraction of total CPU time consumed by a callback stream's
/// audio processing routines including, but not limited to the client supplied
/// stream callback. This function does not work with blocking read/write streams.
///
/// This function may be called from the stream callback function or the
/// application.
///
/// Return
/// A floating point value, typically between 0.0 and 1.0, where 1.0 indicates
/// that the stream callback is consuming the maximum number of CPU cycles possible
/// to maintain real-time operation. A value of 0.5 would imply that PortAudio and