We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
There was an error while loading. Please reload this page.
1 parent bda9aa2 commit d6fef32Copy full SHA for d6fef32
9 files changed
include/audio.h
@@ -189,6 +189,14 @@ audio_device_t *mixer_device(void);
189
*/
190
void mixer_idle(void);
191
192
+void mixer_stop_stream(mixer_stream_t* ch);
193
+
194
+void mixer_pause_stream(mixer_stream_t* ch);
195
196
+void mixer_resume_stream(mixer_stream_t* ch);
197
198
+bool mixer_stream_is_paused(mixer_stream_t* ch);
199
200
/**
201
* @brief Convert a memory-resident WAV into 44.1 kHz stereo S16_LE
202
*
@@ -253,3 +261,4 @@ size_t wav_size_to_samples(size_t length);
253
261
* @return Size in bytes of the decoded buffer
254
262
255
263
size_t wav_samples_to_size(size_t samples);
264
include/basic/audio.h
@@ -0,0 +1,19 @@
1
+#pragma once
2
+#include <kernel.h>
3
+#include <audio.h>
4
5
+int64_t assign_stream(struct basic_ctx* ctx);
6
7
+bool release_stream(struct basic_ctx* ctx, int64_t stream_id);
8
9
+mixer_stream_t* get_stream(struct basic_ctx* ctx, int64_t stream_id);
10
11
+void stream_statement(struct basic_ctx* ctx);
12
13
+void sound_statement(struct basic_ctx* ctx);
14
15
+int64_t basic_decibels(struct basic_ctx* ctx);
16
17
+void sound_list_free_all(struct basic_ctx *ctx);
18
19
+void stream_list_free_all(struct basic_ctx *ctx);
include/basic/context.h
@@ -7,6 +7,7 @@
#include <stdbool.h>
#include "tokenizer.h"
#include "buddy_allocator.h"
+#include "audio.h"
typedef struct {
uint16_t source_port;
@@ -17,6 +18,12 @@ typedef struct {
struct queued_udp_packet* next;
} queued_udp_packet;
20
21
+typedef struct basic_sound_t {
22
+ int16_t *pcm; /* interleaved S16LE */
23
+ size_t frames; /* stereo frames */
24
+ struct basic_sound_t* next; /* Next */
25
+} basic_sound_t;
26
27
28
* @brief BASIC program context.
29
@@ -331,6 +338,11 @@ typedef struct basic_ctx {
331
338
buddy_allocator_t* allocator;
332
339
333
340
queued_udp_packet last_packet;
341
342
+ mixer_stream_t* audio_streams[64];
343
344
+ basic_sound_t* sounds;
345
334
346
} basic_ctx;
335
347
336
348
include/basic/tokenizer.h
@@ -188,8 +188,19 @@ typedef void (*keyword_handler_t)(struct basic_ctx*);
188
T(SOCKBINREAD, STMT, sockbinread_statement) /* 116 */ \
T(BINREAD, STMT, readbinary_statement) /* 117 */ \
T(BINWRITE, STMT, writebinary_statement) /* 118 */ \
- T(GRAPHPRINT, STMT, graphprint_statement) /* 118 */ \
- T(VDU, STMT, vdu_statement) /* 118 */ \
+ T(GRAPHPRINT, STMT, graphprint_statement) /* 119 */ \
+ T(VDU, STMT, vdu_statement) /* 120 */ \
+ T(STREAM, STMT, stream_statement) /* 121 */ \
+ T(CREATE, STMT, NULL) /* 122 */ \
+ T(DESTROY, STMT, NULL) /* 123 */ \
+ T(SOUND, STMT, sound_statement) /* 124 */ \
+ T(VOLUME, STMT, NULL) /* 125 */ \
+ T(PLAY, STMT, NULL) /* 126 */ \
+ T(STOP, STMT, NULL) /* 127 */ \
+ T(PAUSE, STMT, NULL) /* 128 */ \
+ T(LOAD, STMT, NULL) /* 129 */ \
+ T(UNLOAD, STMT, NULL) /* 130 */ \
203
204
205
GENERATE_ENUM_LIST(TOKEN, token_t)
206
src/audio/mixer.c
@@ -26,6 +26,7 @@ struct mixer_stream {
uint32_t queued_frames; /* total frames queued across chunks */
uint16_t gain_q8_8; /* 256 == 1.0 */
bool muted;
+ bool paused;
30
bool in_use;
31
uint32_t chunk_frames; /* preferred chunk allocation size (frames) */
32
};
@@ -43,6 +44,7 @@ typedef struct {
43
44
45
/* Idle registration state */
46
bool idle_registered;
47
48
} mixer_state_t;
49
50
static mixer_state_t mix;
@@ -168,6 +170,7 @@ mixer_stream_t *mixer_create_stream(void) {
168
170
ch->queued_frames = 0;
169
171
ch->gain_q8_8 = 256u; /* 1.0 */
172
ch->muted = false;
173
+ ch->paused = false;
174
ch->in_use = true;
175
ch->chunk_frames = 2048u; /* ~42.7 ms @ 48 kHz */
176
return ch;
@@ -177,11 +180,30 @@ mixer_stream_t *mixer_create_stream(void) {
177
180
return NULL;
178
181
}
179
182
-void mixer_free_stream(mixer_stream_t *ch) {
183
+void mixer_pause_stream(mixer_stream_t *ch) {
184
if (!ch) {
185
return;
186
187
+ ch->paused = true;
+}
+void mixer_resume_stream(mixer_stream_t *ch) {
+ if (!ch) {
+ return;
+ }
+bool mixer_stream_is_paused(mixer_stream_t* ch) {
+ return false;
+ return ch->paused;
+void mixer_stop_stream(mixer_stream_t* ch) {
207
/* Drop any queued audio */
208
chunk_t *p = ch->head;
209
while (p) {
@@ -193,6 +215,14 @@ void mixer_free_stream(mixer_stream_t *ch) {
215
ch->head = NULL;
216
ch->tail = NULL;
217
218
219
220
+void mixer_free_stream(mixer_stream_t *ch) {
221
222
223
224
225
+ mixer_stop_stream(ch);
226
ch->in_use = false;
227
228
@@ -293,7 +323,7 @@ void mixer_idle(void)
293
323
/* mix stream into this block */
294
324
for (uint32_t c = 0; c < mix.streams_cap; c++) {
295
325
struct mixer_stream *ch = &mix.streams[c];
296
- if (!ch->in_use || ch->muted || !ch->head) {
326
+ if (!ch->in_use || ch->muted || !ch->head || ch->paused) {
297
327
continue;
298
328
299
329
0 commit comments