Skip to content

Commit d6fef32

Browse files
BASIC audio keywords; documentation coming soon
1 parent bda9aa2 commit d6fef32

File tree

9 files changed

+374
-8
lines changed

9 files changed

+374
-8
lines changed

include/audio.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,14 @@ audio_device_t *mixer_device(void);
189189
*/
190190
void mixer_idle(void);
191191

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+
192200
/**
193201
* @brief Convert a memory-resident WAV into 44.1 kHz stereo S16_LE
194202
*
@@ -253,3 +261,4 @@ size_t wav_size_to_samples(size_t length);
253261
* @return Size in bytes of the decoded buffer
254262
*/
255263
size_t wav_samples_to_size(size_t samples);
264+

include/basic/audio.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <stdbool.h>
88
#include "tokenizer.h"
99
#include "buddy_allocator.h"
10+
#include "audio.h"
1011

1112
typedef struct {
1213
uint16_t source_port;
@@ -17,6 +18,12 @@ typedef struct {
1718
struct queued_udp_packet* next;
1819
} queued_udp_packet;
1920

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+
2027
/**
2128
* @brief BASIC program context.
2229
*
@@ -331,6 +338,11 @@ typedef struct basic_ctx {
331338
buddy_allocator_t* allocator;
332339

333340
queued_udp_packet last_packet;
341+
342+
mixer_stream_t* audio_streams[64];
343+
344+
basic_sound_t* sounds;
345+
334346
} basic_ctx;
335347

336348
/**

include/basic/tokenizer.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,19 @@ typedef void (*keyword_handler_t)(struct basic_ctx*);
188188
T(SOCKBINREAD, STMT, sockbinread_statement) /* 116 */ \
189189
T(BINREAD, STMT, readbinary_statement) /* 117 */ \
190190
T(BINWRITE, STMT, writebinary_statement) /* 118 */ \
191-
T(GRAPHPRINT, STMT, graphprint_statement) /* 118 */ \
192-
T(VDU, STMT, vdu_statement) /* 118 */ \
191+
T(GRAPHPRINT, STMT, graphprint_statement) /* 119 */ \
192+
T(VDU, STMT, vdu_statement) /* 120 */ \
193+
T(STREAM, STMT, stream_statement) /* 121 */ \
194+
T(CREATE, STMT, NULL) /* 122 */ \
195+
T(DESTROY, STMT, NULL) /* 123 */ \
196+
T(SOUND, STMT, sound_statement) /* 124 */ \
197+
T(VOLUME, STMT, NULL) /* 125 */ \
198+
T(PLAY, STMT, NULL) /* 126 */ \
199+
T(STOP, STMT, NULL) /* 127 */ \
200+
T(PAUSE, STMT, NULL) /* 128 */ \
201+
T(LOAD, STMT, NULL) /* 129 */ \
202+
T(UNLOAD, STMT, NULL) /* 130 */ \
203+
193204

194205
GENERATE_ENUM_LIST(TOKEN, token_t)
195206

src/audio/mixer.c

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ struct mixer_stream {
2626
uint32_t queued_frames; /* total frames queued across chunks */
2727
uint16_t gain_q8_8; /* 256 == 1.0 */
2828
bool muted;
29+
bool paused;
2930
bool in_use;
3031
uint32_t chunk_frames; /* preferred chunk allocation size (frames) */
3132
};
@@ -43,6 +44,7 @@ typedef struct {
4344

4445
/* Idle registration state */
4546
bool idle_registered;
47+
4648
} mixer_state_t;
4749

4850
static mixer_state_t mix;
@@ -168,6 +170,7 @@ mixer_stream_t *mixer_create_stream(void) {
168170
ch->queued_frames = 0;
169171
ch->gain_q8_8 = 256u; /* 1.0 */
170172
ch->muted = false;
173+
ch->paused = false;
171174
ch->in_use = true;
172175
ch->chunk_frames = 2048u; /* ~42.7 ms @ 48 kHz */
173176
return ch;
@@ -177,11 +180,30 @@ mixer_stream_t *mixer_create_stream(void) {
177180
return NULL;
178181
}
179182

180-
void mixer_free_stream(mixer_stream_t *ch) {
183+
void mixer_pause_stream(mixer_stream_t *ch) {
181184
if (!ch) {
182185
return;
183186
}
184187

188+
ch->paused = true;
189+
}
190+
191+
void mixer_resume_stream(mixer_stream_t *ch) {
192+
if (!ch) {
193+
return;
194+
}
195+
196+
ch->paused = false;
197+
}
198+
199+
bool mixer_stream_is_paused(mixer_stream_t* ch) {
200+
if (!ch) {
201+
return false;
202+
}
203+
return ch->paused;
204+
}
205+
206+
void mixer_stop_stream(mixer_stream_t* ch) {
185207
/* Drop any queued audio */
186208
chunk_t *p = ch->head;
187209
while (p) {
@@ -193,6 +215,14 @@ void mixer_free_stream(mixer_stream_t *ch) {
193215
ch->head = NULL;
194216
ch->tail = NULL;
195217
ch->queued_frames = 0;
218+
}
219+
220+
void mixer_free_stream(mixer_stream_t *ch) {
221+
if (!ch) {
222+
return;
223+
}
224+
225+
mixer_stop_stream(ch);
196226
ch->in_use = false;
197227
}
198228

@@ -293,7 +323,7 @@ void mixer_idle(void)
293323
/* mix stream into this block */
294324
for (uint32_t c = 0; c < mix.streams_cap; c++) {
295325
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) {
297327
continue;
298328
}
299329

0 commit comments

Comments
 (0)