Uses 911K of libraries. Click here for Pure Java version (7093L/36K).
1 | !7 |
2 | |
3 | import static x30_pkg.x30_util.VF1; |
4 | import javax.sound.sampled.AudioFormat; |
5 | |
6 | cmodule APlayAudioOutput > DynPrintLog { |
7 | switchable int bufSizeMS = 200; |
8 | switchable int sampleRate = 44100; |
9 | switchable int channels = 2; // only 2 is tested |
10 | switchable int bits = 16; |
11 | switchable float gain = 1; |
12 | switchable bool registerService; |
13 | |
14 | transient L<VF1<double[]>> sources = notifyingList(r setNumSources); |
15 | transient SimpleLiveValue<Int> numSources = new(Int, 0); |
16 | transient StreamSoundToAPlay loop; |
17 | transient int bufSizeInFrames; |
18 | transient short[] buffer; |
19 | |
20 | visualize { |
21 | ret centerAndSouth(super.visualize(), |
22 | withLeftAndRightMargin(vstackWithSpacing( |
23 | withLabel("Volume (0-200%):", liveSliderZeroToOne(gain/2, voidfunc(float f) { setField(gain := f*2) })), |
24 | jrightalignedline(withLabel("Sound sources:", jLiveValueLabel(numSources))) |
25 | ))); |
26 | } |
27 | |
28 | start { |
29 | ownResource(loop = new StreamSoundToAPlay); |
30 | copyFields(module(), loop, 'sampleRate, 'channels, 'bits, 'bufSizeMS); |
31 | bufSizeInFrames = msToSamples_int(bufSizeMS, sampleRate); |
32 | buffer = new short[bufSizeInFrames*2]; |
33 | fillBuffer(); |
34 | loop.start(); |
35 | loop.writeSamples(buffer); |
36 | doEveryAndNow(bufSizeMS, r { |
37 | fillBuffer(); |
38 | loop.writeSamples(buffer); |
39 | }); |
40 | |
41 | dm_registerAs audioOutputModule(); |
42 | |
43 | if (registerService) |
44 | dm_registerService('playWAVAndWait, func(S method, O[] args) -> bool { |
45 | temp enter(); |
46 | callMC(f dm_playWAV, args); |
47 | true; |
48 | }); |
49 | } |
50 | |
51 | void fillBuffer enter { |
52 | VF1<VF1<double[]>> vfRemoveSource = voidfunc(VF1<double[]> source) { |
53 | removeSource(source) |
54 | }; |
55 | |
56 | double[] pair = new double[2]; |
57 | for i over buffer: { |
58 | audio_makeSampleFromSources(sources, pair, gain, vfRemoveSource); |
59 | buffer[i++] = clipShort(pair[0]); |
60 | buffer[i] = clipShort(pair[1]); |
61 | } |
62 | } |
63 | |
64 | void setNumSources { numSources.set(l(sources)); } |
65 | |
66 | // hold audio sources during reload |
67 | |
68 | O _getReloadData() { ret sources; } |
69 | void _setReloadData(L<VF1<double[]>> sources) { addAll(this.sources, sources); } |
70 | |
71 | // API |
72 | |
73 | void addSource(VF1<double[]> source) { |
74 | sources.add(source); |
75 | print("Audio source added."); |
76 | } |
77 | |
78 | void removeSource(VF1<double[]> source) { |
79 | sources.remove(source); |
80 | print("Audio source removed."); |
81 | } |
82 | |
83 | AudioFormat getAudioFormat() { ret new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, sampleRate, bits, channels, channels*bits/2, sampleRate, false); } |
84 | |
85 | long samplesPlayed() { ret loop.frameCounter; } |
86 | } |
Began life as a copy of #1016699
download show line numbers debug dex old transpilations
Travelled to 7 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv
No comments. add comment
Snippet ID: | #1027007 |
Snippet name: | Audio Output using aplay [dev.] |
Eternal ID of this version: | #1027007/5 |
Text MD5: | 18465ff50ead49ba99642cdc01f5fa06 |
Transpilation MD5: | 2cc043245e8067c17d23de77b71dcdc4 |
Author: | stefan |
Category: | javax / audio |
Type: | JavaX source code (Dynamic Module) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2020-02-06 23:14:32 |
Source code size: | 2628 bytes / 86 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 279 / 396 |
Version history: | 4 change(s) |
Referenced in: | [show references] |