Skip to content

Commit feb8eb9

Browse files
committed
audiosample: convert to use a protocol
This eases addition of new sample sources, since the manual virtual function dispatch functions are just calls via a protocol
1 parent 238e121 commit feb8eb9

File tree

9 files changed

+94
-85
lines changed

9 files changed

+94
-85
lines changed

shared-bindings/audiocore/RawSample.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,20 @@ STATIC const mp_rom_map_elem_t audioio_rawsample_locals_dict_table[] = {
180180
};
181181
STATIC MP_DEFINE_CONST_DICT(audioio_rawsample_locals_dict, audioio_rawsample_locals_dict_table);
182182

183+
STATIC const audiosample_p_t audioio_rawsample_proto = {
184+
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample)
185+
.sample_rate = (audiosample_sample_rate_fun)common_hal_audioio_rawsample_get_sample_rate,
186+
.bits_per_sample = (audiosample_bits_per_sample_fun)common_hal_audioio_rawsample_get_bits_per_sample,
187+
.channel_count = (audiosample_channel_count_fun)common_hal_audioio_rawsample_get_channel_count,
188+
.reset_buffer = (audiosample_reset_buffer_fun)audioio_rawsample_reset_buffer,
189+
.get_buffer = (audiosample_get_buffer_fun)audioio_rawsample_get_buffer,
190+
.get_buffer_structure = (audiosample_get_buffer_structure_fun)audioio_rawsample_get_buffer_structure,
191+
};
192+
183193
const mp_obj_type_t audioio_rawsample_type = {
184194
{ &mp_type_type },
185195
.name = MP_QSTR_RawSample,
186196
.make_new = audioio_rawsample_make_new,
187197
.locals_dict = (mp_obj_dict_t*)&audioio_rawsample_locals_dict,
198+
.protocol = &audioio_rawsample_proto,
188199
};

shared-bindings/audiocore/RawSample.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ void common_hal_audioio_rawsample_construct(audioio_rawsample_obj_t* self,
3939
void common_hal_audioio_rawsample_deinit(audioio_rawsample_obj_t* self);
4040
bool common_hal_audioio_rawsample_deinited(audioio_rawsample_obj_t* self);
4141
uint32_t common_hal_audioio_rawsample_get_sample_rate(audioio_rawsample_obj_t* self);
42+
uint8_t common_hal_audioio_rawsample_get_bits_per_sample(audioio_rawsample_obj_t* self);
43+
uint8_t common_hal_audioio_rawsample_get_channel_count(audioio_rawsample_obj_t* self);
4244
void common_hal_audioio_rawsample_set_sample_rate(audioio_rawsample_obj_t* self, uint32_t sample_rate);
4345

4446
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_RAWSAMPLE_H

shared-bindings/audiocore/WaveFile.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,21 @@ STATIC const mp_rom_map_elem_t audioio_wavefile_locals_dict_table[] = {
206206
};
207207
STATIC MP_DEFINE_CONST_DICT(audioio_wavefile_locals_dict, audioio_wavefile_locals_dict_table);
208208

209+
STATIC const audiosample_p_t audioio_wavefile_proto = {
210+
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample)
211+
.sample_rate = (audiosample_sample_rate_fun)common_hal_audioio_wavefile_get_sample_rate,
212+
.bits_per_sample = (audiosample_bits_per_sample_fun)common_hal_audioio_wavefile_get_bits_per_sample,
213+
.channel_count = (audiosample_channel_count_fun)common_hal_audioio_wavefile_get_channel_count,
214+
.reset_buffer = (audiosample_reset_buffer_fun)audioio_wavefile_reset_buffer,
215+
.get_buffer = (audiosample_get_buffer_fun)audioio_wavefile_get_buffer,
216+
.get_buffer_structure = (audiosample_get_buffer_structure_fun)audioio_wavefile_get_buffer_structure,
217+
};
218+
219+
209220
const mp_obj_type_t audioio_wavefile_type = {
210221
{ &mp_type_type },
211222
.name = MP_QSTR_WaveFile,
212223
.make_new = audioio_wavefile_make_new,
213224
.locals_dict = (mp_obj_dict_t*)&audioio_wavefile_locals_dict,
225+
.protocol = &audioio_wavefile_proto,
214226
};

shared-bindings/audiomixer/Mixer.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,9 +291,20 @@ STATIC const mp_rom_map_elem_t audiomixer_mixer_locals_dict_table[] = {
291291
};
292292
STATIC MP_DEFINE_CONST_DICT(audiomixer_mixer_locals_dict, audiomixer_mixer_locals_dict_table);
293293

294+
STATIC const audiosample_p_t audiomixer_mixer_proto = {
295+
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample)
296+
.sample_rate = (audiosample_sample_rate_fun)common_hal_audiomixer_mixer_get_sample_rate,
297+
.bits_per_sample = (audiosample_bits_per_sample_fun)common_hal_audiomixer_mixer_get_bits_per_sample,
298+
.channel_count = (audiosample_channel_count_fun)common_hal_audiomixer_mixer_get_channel_count,
299+
.reset_buffer = (audiosample_reset_buffer_fun)audiomixer_mixer_reset_buffer,
300+
.get_buffer = (audiosample_get_buffer_fun)audiomixer_mixer_get_buffer,
301+
.get_buffer_structure = (audiosample_get_buffer_structure_fun)audiomixer_mixer_get_buffer_structure,
302+
};
303+
294304
const mp_obj_type_t audiomixer_mixer_type = {
295305
{ &mp_type_type },
296306
.name = MP_QSTR_Mixer,
297307
.make_new = audiomixer_mixer_make_new,
298308
.locals_dict = (mp_obj_dict_t*)&audiomixer_mixer_locals_dict,
309+
.protocol = &audiomixer_mixer_proto,
299310
};

shared-bindings/audiomixer/Mixer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,7 @@ bool common_hal_audiomixer_mixer_deinited(audiomixer_mixer_obj_t* self);
4747

4848
bool common_hal_audiomixer_mixer_get_playing(audiomixer_mixer_obj_t* self);
4949
uint32_t common_hal_audiomixer_mixer_get_sample_rate(audiomixer_mixer_obj_t* self);
50+
uint8_t common_hal_audiomixer_mixer_get_channel_count(audiomixer_mixer_obj_t* self);
51+
uint8_t common_hal_audiomixer_mixer_get_bits_per_sample(audiomixer_mixer_obj_t* self);
5052

5153
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOMIXER_MIXER_H

shared-module/audiocore/RawSample.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ void common_hal_audioio_rawsample_set_sample_rate(audioio_rawsample_obj_t* self,
6060
uint32_t sample_rate) {
6161
self->sample_rate = sample_rate;
6262
}
63+
uint8_t common_hal_audioio_rawsample_get_bits_per_sample(audioio_rawsample_obj_t* self) {
64+
return self->bits_per_sample;
65+
}
66+
uint8_t common_hal_audioio_rawsample_get_channel_count(audioio_rawsample_obj_t* self) {
67+
return self->channel_count;
68+
}
6369

6470
void audioio_rawsample_reset_buffer(audioio_rawsample_obj_t* self,
6571
bool single_channel,

shared-module/audiocore/__init__.c

Lines changed: 13 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -36,103 +36,37 @@
3636
#include "shared-module/audiomixer/Mixer.h"
3737

3838
uint32_t audiosample_sample_rate(mp_obj_t sample_obj) {
39-
if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
40-
audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
41-
return sample->sample_rate;
42-
} else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
43-
audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
44-
return file->sample_rate;
45-
#if CIRCUITPY_AUDIOMIXER
46-
} else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) {
47-
audiomixer_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj);
48-
return mixer->sample_rate;
49-
#endif
50-
}
51-
return 16000;
39+
const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj);
40+
return proto->sample_rate(MP_OBJ_TO_PTR(sample_obj));
5241
}
5342

5443
uint8_t audiosample_bits_per_sample(mp_obj_t sample_obj) {
55-
if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
56-
audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
57-
return sample->bits_per_sample;
58-
} else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
59-
audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
60-
return file->bits_per_sample;
61-
#if CIRCUITPY_AUDIOMIXER
62-
} else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) {
63-
audiomixer_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj);
64-
return mixer->bits_per_sample;
65-
#endif
66-
}
67-
return 8;
44+
const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj);
45+
return proto->bits_per_sample(MP_OBJ_TO_PTR(sample_obj));
6846
}
6947

7048
uint8_t audiosample_channel_count(mp_obj_t sample_obj) {
71-
if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
72-
audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
73-
return sample->channel_count;
74-
} else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
75-
audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
76-
return file->channel_count;
77-
#if CIRCUITPY_AUDIOMIXER
78-
} else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) {
79-
audiomixer_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj);
80-
return mixer->channel_count;
81-
#endif
82-
}
83-
return 1;
49+
const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj);
50+
return proto->channel_count(MP_OBJ_TO_PTR(sample_obj));
8451
}
8552

8653
void audiosample_reset_buffer(mp_obj_t sample_obj, bool single_channel, uint8_t audio_channel) {
87-
if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
88-
audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
89-
audioio_rawsample_reset_buffer(sample, single_channel, audio_channel);
90-
} else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
91-
audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
92-
audioio_wavefile_reset_buffer(file, single_channel, audio_channel);
93-
#if CIRCUITPY_AUDIOMIXER
94-
} else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) {
95-
audiomixer_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
96-
audiomixer_mixer_reset_buffer(file, single_channel, audio_channel);
97-
#endif
98-
}
54+
const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj);
55+
proto->reset_buffer(MP_OBJ_TO_PTR(sample_obj));
9956
}
10057

10158
audioio_get_buffer_result_t audiosample_get_buffer(mp_obj_t sample_obj,
10259
bool single_channel,
10360
uint8_t channel,
10461
uint8_t** buffer, uint32_t* buffer_length) {
105-
if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
106-
audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
107-
return audioio_rawsample_get_buffer(sample, single_channel, channel, buffer, buffer_length);
108-
} else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
109-
audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
110-
return audioio_wavefile_get_buffer(file, single_channel, channel, buffer, buffer_length);
111-
#if CIRCUITPY_AUDIOMIXER
112-
} else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) {
113-
audiomixer_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
114-
return audiomixer_mixer_get_buffer(file, single_channel, channel, buffer, buffer_length);
115-
#endif
116-
}
117-
return GET_BUFFER_DONE;
62+
const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj);
63+
return proto->get_buffer(MP_OBJ_TO_PTR(sample_obj), single_channel, channel, buffer, buffer_length);
11864
}
11965

12066
void audiosample_get_buffer_structure(mp_obj_t sample_obj, bool single_channel,
12167
bool* single_buffer, bool* samples_signed,
12268
uint32_t* max_buffer_length, uint8_t* spacing) {
123-
if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
124-
audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
125-
audioio_rawsample_get_buffer_structure(sample, single_channel, single_buffer,
126-
samples_signed, max_buffer_length, spacing);
127-
} else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
128-
audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
129-
audioio_wavefile_get_buffer_structure(file, single_channel, single_buffer, samples_signed,
130-
max_buffer_length, spacing);
131-
#if CIRCUITPY_AUDIOMIXER
132-
} else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) {
133-
audiomixer_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
134-
audiomixer_mixer_get_buffer_structure(file, single_channel, single_buffer, samples_signed,
135-
max_buffer_length, spacing);
136-
#endif
137-
}
69+
const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj);
70+
proto->get_buffer_structure(MP_OBJ_TO_PTR(sample_obj), single_channel, single_buffer,
71+
samples_signed, max_buffer_length, spacing);
13872
}

shared-module/audiocore/__init__.h

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,22 +31,45 @@
3131
#include <stdint.h>
3232

3333
#include "py/obj.h"
34+
#include "py/proto.h"
3435

3536
typedef enum {
3637
GET_BUFFER_DONE, // No more data to read
3738
GET_BUFFER_MORE_DATA, // More data to read.
3839
GET_BUFFER_ERROR, // Error while reading data.
3940
} audioio_get_buffer_result_t;
4041

41-
uint32_t audiosample_sample_rate(mp_obj_t sample_obj);
42-
uint8_t audiosample_bits_per_sample(mp_obj_t sample_obj);
43-
uint8_t audiosample_channel_count(mp_obj_t sample_obj);
44-
void audiosample_reset_buffer(mp_obj_t sample_obj, bool single_channel, uint8_t audio_channel);
45-
audioio_get_buffer_result_t audiosample_get_buffer(mp_obj_t sample_obj,
42+
typedef uint32_t (*audiosample_sample_rate_fun)(void* sample_obj);
43+
typedef uint8_t (*audiosample_bits_per_sample_fun)(void* sample_obj);
44+
typedef uint8_t (*audiosample_channel_count_fun)(void* sample_obj);
45+
typedef void (*audiosample_reset_buffer_fun)(void* sample_obj);
46+
typedef audioio_get_buffer_result_t (*audiosample_get_buffer_fun)(void* sample_obj,
47+
bool single_channel, uint8_t channel, uint8_t** buffer,
48+
uint32_t* buffer_length);
49+
typedef void (*audiosample_get_buffer_structure_fun)(void* sample_obj,
50+
bool single_channel, bool* single_buffer,
51+
bool* samples_signed, uint32_t *max_buffer_length,
52+
uint8_t* spacing);
53+
54+
typedef struct _audiosample_p_t {
55+
MP_PROTOCOL_HEAD // MP_QSTR_protocol_audiosample
56+
audiosample_sample_rate_fun sample_rate;
57+
audiosample_bits_per_sample_fun bits_per_sample;
58+
audiosample_channel_count_fun channel_count;
59+
audiosample_reset_buffer_fun reset_buffer;
60+
audiosample_get_buffer_fun get_buffer;
61+
audiosample_get_buffer_structure_fun get_buffer_structure;
62+
} audiosample_p_t;
63+
64+
uint32_t audiosample_sample_rate(void* sample_obj);
65+
uint8_t audiosample_bits_per_sample(void* sample_obj);
66+
uint8_t audiosample_channel_count(void* sample_obj);
67+
void audiosample_reset_buffer(void* sample_obj, bool single_channel, uint8_t audio_channel);
68+
audioio_get_buffer_result_t audiosample_get_buffer(void* sample_obj,
4669
bool single_channel,
4770
uint8_t channel,
4871
uint8_t** buffer, uint32_t* buffer_length);
49-
void audiosample_get_buffer_structure(mp_obj_t sample_obj, bool single_channel,
72+
void audiosample_get_buffer_structure(void* sample_obj, bool single_channel,
5073
bool* single_buffer, bool* samples_signed,
5174
uint32_t* max_buffer_length, uint8_t* spacing);
5275

shared-module/audiomixer/Mixer.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@ uint32_t common_hal_audiomixer_mixer_get_sample_rate(audiomixer_mixer_obj_t* sel
7676
return self->sample_rate;
7777
}
7878

79+
uint8_t common_hal_audiomixer_mixer_get_channel_count(audiomixer_mixer_obj_t* self) {
80+
return self->channel_count;
81+
}
82+
83+
uint8_t common_hal_audiomixer_mixer_get_bits_per_sample(audiomixer_mixer_obj_t* self) {
84+
return self->bits_per_sample;
85+
}
86+
7987
bool common_hal_audiomixer_mixer_get_playing(audiomixer_mixer_obj_t* self) {
8088
for (uint8_t v = 0; v < self->voice_count; v++) {
8189
if (common_hal_audiomixer_mixervoice_get_playing(MP_OBJ_TO_PTR(self->voice[v]))) {

0 commit comments

Comments
 (0)