@@ -132,15 +132,14 @@ class RTTTLOutput : public AudioOutput {
132132 addNotifyAudioChange (out);
133133 }
134134
135-
136135 /* *
137136 * @brief Start the RTTTL stream: we start with
138137 * parsing the title and defaults
139138 * @return True if initialization was
140139 * successful.
141140 */
142- bool begin () override {
143- if (p_generator){
141+ bool begin () override {
142+ if (p_generator) {
144143 p_generator->begin (audioInfo ());
145144 }
146145 is_start = true ;
@@ -163,12 +162,16 @@ class RTTTLOutput : public AudioOutput {
163162 // / RTTTL string
164163 int getDefaultBpm () const { return m_bpm; }
165164
166- // / Writes RTTTL data to the parser and plays
167- // / the notes
165+ // / Writes RTTTL data to the parser and plays the notes
168166 size_t write (const uint8_t * data, size_t len) override {
169- LOGD (" write: %d" ,len);
167+ LOGD (" write: %d" , len);
170168 ring_buffer.resize (len);
171169 ring_buffer.writeArray (const_cast <uint8_t *>(data), len);
170+ // If we haven't started yet and we find a ':', we need to call begin()
171+ if (!is_start && find_byte (data, len, ' :' ) >= 0 ) {
172+ begin ();
173+ }
174+ // start parsing of new rtttl string
172175 if (is_start) {
173176 // parse rtttl string
174177 parse_title ();
@@ -188,14 +191,13 @@ class RTTTLOutput : public AudioOutput {
188191 // / milliseconds
189192 // / - midiNote: MIDI note number (0-127)
190193 void setNoteCallback (
191- std::function<void (float freqHz, int durationMs, int midiNote, void *ref)> cb) {
194+ std::function<void (float freqHz, int durationMs, int midiNote, void * ref)>
195+ cb) {
192196 noteCallback = cb;
193197 }
194198
195199 // Provide reference for callback
196- void setReference (void * ref) {
197- reference = ref;
198- }
200+ void setReference (void * ref) { reference = ref; }
199201
200202 protected:
201203 MusicalNotes m_notes;
@@ -210,9 +212,18 @@ class RTTTLOutput : public AudioOutput {
210212 int m_duration{4 };
211213 int m_bpm{120 };
212214 float m_msec_semi{750 };
213- void * reference = nullptr ;
215+ void * reference = nullptr ;
214216 std::function<void (float , int , int , void *)> noteCallback;
215217
218+ int find_byte (const uint8_t * haystack, size_t haystack_len, uint8_t needle) {
219+ for (size_t i = 0 ; i < haystack_len; i++) {
220+ if (haystack[i] == needle) {
221+ return i; // Return the index of the first match
222+ }
223+ }
224+ return -1 ; // Return -1 if the byte is not found
225+ }
226+
216227 void play_note (float freq, int msec, int midi = -1 ) {
217228 // invoke the optional callback first
218229 LOGI (" play_note: freq=%.2f Hz, msec=%d, midi=%d" , freq, msec, midi);
@@ -232,7 +243,7 @@ class RTTTLOutput : public AudioOutput {
232243 open -= toCopy;
233244 delay (1 );
234245 }
235- }
246+ }
236247
237248 char next_char () {
238249 uint8_t c;
@@ -249,8 +260,7 @@ class RTTTLOutput : public AudioOutput {
249260 for (; m_actual != ' :' && m_actual != ' \0 ' ; next_char ()) {
250261 m_title += m_actual;
251262 }
252- if (!m_title.isEmpty ())
253- LOGI (" title: %s" , m_title.c_str ());
263+ if (!m_title.isEmpty ()) LOGI (" title: %s" , m_title.c_str ());
254264 }
255265
256266 int parse_num () {
0 commit comments