@@ -125,7 +125,7 @@ different.
125
125
First, we require the dfpwm module and call @{cc.audio.dfpwm.make_decoder} to construct a new decoder. This decoder
126
126
accepts blocks of DFPWM data and converts it to a list of 8-bit amplitudes, which we can then play with our speaker.
127
127
128
- As mentioned to above, @{speaker.playAudio} accepts at most 128×1024 samples in one go. DFPMW uses a single bit for each
128
+ As mentioned above, @{speaker.playAudio} accepts at most 128×1024 samples in one go. DFPMW uses a single bit for each
129
129
sample, which means we want to process our audio in chunks of 16×1024 bytes (16KiB). In order to do this, we use
130
130
@{io.lines}, which provides a nice way to loop over chunks of a file. You can of course just use @{fs.open} and
131
131
@{fs.BinaryReadHandle.read} if you prefer.
@@ -136,22 +136,22 @@ You can mix together samples from different streams by adding their amplitudes,
136
136
samples, etc...
137
137
138
138
Let's put together a small demonstration here. We're going to add a small delay effect to the song above, so that you
139
- hear a faint echo about a second later.
139
+ hear a faint echo a second and a half later.
140
140
141
141
In order to do this, we'll follow a format similar to the previous example, decoding the audio and then playing it.
142
142
However, we'll also add some new logic between those two steps, which loops over every sample in our chunk of audio, and
143
- adds the sample from one second ago to it.
143
+ adds the sample from 1.5 seconds ago to it.
144
144
145
- For this, we'll need to keep track of the last 48k samples - exactly one seconds worth of audio. We can do this using a
145
+ For this, we'll need to keep track of the last 72k samples - exactly 1.5 seconds worth of audio. We can do this using a
146
146
[ Ring Buffer] , which helps makes things a little more efficient.
147
147
148
148
``` lua {data-peripheral=speaker}
149
149
local dfpwm = require (" cc.audio.dfpwm" )
150
150
local speaker = peripheral .find (" speaker" )
151
151
152
- -- Speakers play at 48kHz, so one second is 48k samples. We first fill our buffer
152
+ -- Speakers play at 48kHz, so 1.5 seconds is 72k samples. We first fill our buffer
153
153
-- with 0s, as there's nothing to echo at the start of the track!
154
- local samples_i , samples_n = 1 , 48000
154
+ local samples_i , samples_n = 1 , 48000 * 1.5
155
155
local samples = {}
156
156
for i = 1 , samples_n do samples [i ] = 0 end
157
157
@@ -162,7 +162,7 @@ for chunk in io.lines("data/example.dfpwm", 16 * 1024) do
162
162
for i = 1 , # buffer do
163
163
local original_value = buffer [i ]
164
164
165
- -- Replace this sample with its current amplitude plus the amplitude from one second ago.
165
+ -- Replace this sample with its current amplitude plus the amplitude from 1.5 seconds ago.
166
166
-- We scale both to ensure the resulting value is still between -128 and 127.
167
167
buffer [i ] = original_value * 0.6 + samples [samples_i ] * 0.4
168
168
@@ -175,6 +175,11 @@ for chunk in io.lines("data/example.dfpwm", 16 * 1024) do
175
175
while not speaker .playAudio (buffer ) do
176
176
os .pullEvent (" speaker_audio_empty" )
177
177
end
178
+
179
+ -- The audio processing above can be quite slow and preparing the first batch of audio
180
+ -- may timeout the computer. We sleep to avoid this.
181
+ -- There's definitely better ways of handling this - this is just an example!
182
+ sleep (0.05 )
178
183
end
179
184
```
180
185
0 commit comments