Libraryless. Click here for Pure Java version (6459L/37K).
1 | // We're a a bit confused about whether the time coordinates are double |
2 | // or int. (Probably int.) |
3 | persistable sclass SlidingWindow implements IAudioSample { |
4 | // general params |
5 | double sampleRate = 48000; |
6 | int channels; |
7 | |
8 | // length of window |
9 | int length; // in samples per channel |
10 | |
11 | // start of window |
12 | int start; |
13 | |
14 | // at which index in data array is our first value? |
15 | int boundaryIndex; // in data |
16 | |
17 | // Here they are: the partial sums of the 16 bit audio samples |
18 | // in an array of 6-byte integers. Channels are stored interleaved. |
19 | HalfLongs data; |
20 | |
21 | // query original sound (channel, time -> short-range) |
22 | IQuerySound sound; |
23 | |
24 | public double sampleRate() { ret sampleRate; } |
25 | public int channels() { ret channels; } |
26 | public DoubleRange bounds() { ret DoubleRange(start, start+length); } |
27 | |
28 | // Get an entry of the sum table - allow for out-of-bounds |
29 | // requests (those just default to silence). |
30 | @Override public double readSumTable(int channel, int i) { |
31 | // do the first shift |
32 | i -= start; |
33 | |
34 | ret getEntry(channel, i); |
35 | } |
36 | |
37 | long getEntry(int channel, int i) { |
38 | if (i < 0) ret 0; |
39 | i = min(i, length-1); |
40 | |
41 | // do the second shift |
42 | i = (i+boundaryIndex) % length; |
43 | ret data.get(i*channels+channel); |
44 | } |
45 | |
46 | void setEntry(int channel, int i, long l) { |
47 | // do the shift |
48 | i = (i+boundaryIndex) % length; |
49 | data.set(i*channels+channel, l); |
50 | } |
51 | |
52 | // constructor - perform integration of the raw audio data |
53 | *(int *channels, double *sampleRate, IQuerySound *sound, |
54 | int *start, int *length) { |
55 | grab(); |
56 | } |
57 | |
58 | short getSample_short(int channel, double relTime) { |
59 | ret clampToShort(iround(sound.getSample(channel, start+relTime))); |
60 | } |
61 | |
62 | void grab { |
63 | assertTrue(length > 0); |
64 | if (l(data) != length*channels) |
65 | data = new HalfLongs(length*channels); |
66 | long[] sums = new[channels]; |
67 | for i to length: |
68 | for c to channels: |
69 | setEntry(c, i, sums[c] += getSample_short(c, i)); |
70 | } |
71 | |
72 | void moveTo(int newStart) { |
73 | shiftRight(newStart-start); |
74 | } |
75 | |
76 | void moveToCenter(int t) { |
77 | moveTo(max(start, t-length/2)); |
78 | } |
79 | |
80 | void shiftRight(int n default 1) { |
81 | if (n == 0) ret; |
82 | assertTrue(n >= 0); |
83 | |
84 | int oldEnd = ifloor(end()); |
85 | start += n; |
86 | boundaryIndex = mod(boundaryIndex+n, length); |
87 | |
88 | int overlap = max(0, oldEnd-ifloor(start)); |
89 | |
90 | if (overlap == 0) |
91 | grab(); |
92 | else |
93 | for (int i = overlap; i < length; i++) |
94 | try { |
95 | for c to channels: |
96 | setEntry(c, i, getEntry(c, i-1) + getSample_short(c, i)); |
97 | } on fail { |
98 | printVars(+i, +start, +n, +length); |
99 | } |
100 | } |
101 | } |
Began life as a copy of #1032980
download show line numbers debug dex old transpilations
Travelled to 3 computer(s): bhatertpkbcr, ekrmjmnbrukm, mqqgnosmbjvj
No comments. add comment
Snippet ID: | #1032981 |
Snippet name: | SlidingWindow - audio window with fixed size |
Eternal ID of this version: | #1032981/42 |
Text MD5: | 876fc4aa4bfa16d5e276b76c163fdf72 |
Transpilation MD5: | f767beb45a6ed0458506970c42a03315 |
Author: | stefan |
Category: | javax / audio analysis |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2021-10-18 05:27:51 |
Source code size: | 2760 bytes / 101 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 261 / 469 |
Version history: | 41 change(s) |
Referenced in: | [show references] |