2828#include " microbithal.h"
2929#include " MicroBitDevice.h"
3030
31+ #define MIN (a, b ) ((a) < (b) ? (a) : (b))
32+
3133extern " C" void microbit_hal_level_detector_callback (int );
3234
3335static void level_detector_event_handler (Event evt) {
3436 microbit_hal_level_detector_callback (evt.value );
3537}
3638
39+ class MyStreamRecording : public DataSink
40+ {
41+ public:
42+ DataSource &upStream;
43+
44+ public:
45+ uint8_t *dest;
46+ size_t dest_pos;
47+ size_t dest_max;
48+ bool request_stop;
49+
50+ MyStreamRecording (DataSource &source);
51+ virtual ~MyStreamRecording ();
52+
53+ virtual int pullRequest ();
54+ };
55+
56+ MyStreamRecording::MyStreamRecording ( DataSource &source ) : upStream( source )
57+ {
58+ }
59+
60+ MyStreamRecording::~MyStreamRecording ()
61+ {
62+ }
63+
64+ int MyStreamRecording::pullRequest ()
65+ {
66+ ManagedBuffer data = this ->upStream .pull ();
67+
68+ size_t n = MIN ((size_t )data.length (), this ->dest_max - this ->dest_pos );
69+ if (n == 0 || this ->request_stop ) {
70+ this ->upStream .disconnect ();
71+ this ->request_stop = false ;
72+ } else {
73+ // Copy and convert signed 8-bit to unsigned 8-bit data.
74+ const uint8_t *src = data.getBytes ();
75+ uint8_t *dest = this ->dest + this ->dest_pos ;
76+ for (size_t i = 0 ; i < n; ++i) {
77+ *dest++ = *src++ + 128 ;
78+ }
79+ this ->dest_pos += n;
80+ }
81+
82+ return DEVICE_OK;
83+ }
84+
85+ static MyStreamRecording *recording = NULL ;
86+ static SplitterChannel *splitterChannel = NULL ;
87+
3788extern " C" {
3889
3990static bool microphone_init_done = false ;
@@ -59,4 +110,42 @@ int microbit_hal_microphone_get_level(void) {
59110 return value;
60111}
61112
113+ void microbit_hal_microphone_start_recording (uint8_t *buf, size_t len, int rate) {
114+ if (splitterChannel == NULL ) {
115+ splitterChannel = uBit.audio .splitter ->createChannel ();
116+ splitterChannel->setFormat (DATASTREAM_FORMAT_8BIT_UNSIGNED);
117+ // Increase sample period to 64us, so we can get our desired rate.
118+ splitterChannel->requestSampleRate (1000000 / 64 );
119+ }
120+ splitterChannel->requestSampleRate (rate);
121+
122+ if (recording == NULL ) {
123+ recording = new MyStreamRecording (*splitterChannel);
124+ } else {
125+ if (microbit_hal_microphone_is_recording ()) {
126+ microbit_hal_microphone_stop_recording ();
127+ while (microbit_hal_microphone_is_recording ()) {
128+ microbit_hal_idle ();
129+ }
130+ }
131+ }
132+
133+ recording->dest = buf;
134+ recording->dest_pos = 0 ;
135+ recording->dest_max = len;
136+ recording->request_stop = false ;
137+
138+ splitterChannel->connect (*recording);
139+ }
140+
141+ bool microbit_hal_microphone_is_recording (void ) {
142+ return recording != NULL && splitterChannel->isConnected ();
143+ }
144+
145+ void microbit_hal_microphone_stop_recording (void ) {
146+ if (recording != NULL ) {
147+ recording->request_stop = true ;
148+ }
149+ }
150+
62151}
0 commit comments