Uses 1456K of libraries. Click here for Pure Java version (11937L/65K).
1 | !7 |
2 | |
3 | cm LiveFFT > DynImageSurface { |
4 | volatile bool enabled = true; |
5 | switchable bool normalize = false; |
6 | switchable double windowSize = 1; // seconds |
7 | switchable int overlap = 2; |
8 | switchable int frameBits = 10; // frameSize 1024 |
9 | |
10 | switchable double preMult = 3.5; |
11 | switchable int brightness = -300; |
12 | switchable int contrast = 187; |
13 | |
14 | switchable int downSampling = 1; |
15 | |
16 | transient Q q; |
17 | transient L<short[]> buffer = synchroList(); |
18 | transient volatile int bufferSize; |
19 | transient int neededSamples; |
20 | transient Clip clip; |
21 | transient short[] fromData; |
22 | transient IF1<Double> colorizer = x -> (brightness+contrast*log1p(abs(preMult*x)))/255; |
23 | |
24 | visualize { |
25 | if (!hasImage()) setImage( |
26 | whiteImage(audio_estimatedFrequencyImageWidth(windowSize), audio_frequencyImageHeight())); |
27 | ret centerAndSouthWithMargins(super.visualizeWithDoubleBuffering(), |
28 | jvstackWithSpacing( |
29 | makeForm( |
30 | "Window Size" := dm_doubleSlider windowSize(0, 2), |
31 | "Frame Bits" := dm_intSlider frameBits(1, 12), |
32 | Downsampling := dm_intSlider downSampling(1, 8), |
33 | Overlap := dm_intSlider overlap(1, 16), |
34 | PreMult := dm_doubleSlider preMult(0, 50), |
35 | Brightness := dm_intSlider brightness(-300, 200), |
36 | Contrast := dm_intSlider contrast(0, 300)), |
37 | jrightalignedline(dm_fieldCheckBox enabled()) |
38 | )); |
39 | } |
40 | |
41 | void onNewWindowSize { |
42 | neededSamples = iround(windowSize*44100); |
43 | buffer.clear(); |
44 | bufferSize = 0; |
45 | } |
46 | |
47 | start { |
48 | dm_watchFieldAndNow windowSize(r onNewWindowSize); |
49 | |
50 | q = dm_startQ(); |
51 | dm_addAudioListener(voidfunc(short[] _data) { |
52 | if (!enabled) ret; |
53 | short[] data = _data; |
54 | data = dm_audioInputIsStereo() |
55 | ? mixStereoShortArrayToMono(data) |
56 | : cloneShortArray(data); |
57 | if (normalize) data = normalizeShortArray(data); |
58 | buffer.add(data); |
59 | bufferSize += l(data); |
60 | |
61 | if (bufferSize >= neededSamples) { |
62 | bufferSize -= neededSamples; |
63 | final L<short[]> salvaged = cloneList(buffer); |
64 | buffer.clear(); |
65 | if (bufferSize > 0) { |
66 | buffer.add(lastNShorts(bufferSize, last(salvaged))); |
67 | replaceLastElement(salvaged, dropLastNShorts(bufferSize, last(salvaged))); |
68 | } |
69 | |
70 | q.add(r { |
71 | short[] data = concatShortArrays(salvaged); |
72 | data = linearlyShortenArray(data, iround(l(data)/downSampling)); |
73 | ShortArrayInputStream stream = new(data); |
74 | stream.bigEndian = true; |
75 | clip = spectro_clipFromMonoInputStream(stream, 1 << frameBits, overlap); |
76 | vmBus_send newAudioFrequencyClip(clip); |
77 | BWImage img = clipToFrequencyImage(clip, colorizer); |
78 | vmBus_send newAudioFrequencyImage(img); |
79 | vmBus_send newAudioFrequencyImageFromData(img, _data); |
80 | setImage(img); |
81 | fromData = _data; |
82 | }); |
83 | } |
84 | }); |
85 | } |
86 | } |
Began life as a copy of #1019274
download show line numbers debug dex old transpilations
Travelled to 3 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx
No comments. add comment
Snippet ID: | #1031900 |
Snippet name: | Live Audio FFT with more options |
Eternal ID of this version: | #1031900/7 |
Text MD5: | 08846e0c3cce09ec4e13d1cd34c61ea6 |
Transpilation MD5: | bf8430f65d35daec0842356dcd86ce4e |
Author: | stefan |
Category: | javax / audio recognition |
Type: | JavaX source code (Dynamic Module) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2021-07-24 07:01:23 |
Source code size: | 2984 bytes / 86 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 170 / 753 |
Version history: | 6 change(s) |
Referenced in: | [show references] |