1
1
#pragma once
2
2
3
- #include " Arduino.h" // for ESP.getPsramSize()
3
+ #include < stdint.h>
4
+ #include < sys/time.h>
5
+
6
+ #include " Arduino.h" // for ESP.getPsramSize()
4
7
#include " AudioTools.h"
5
8
#include " SnapCommon.h"
6
9
#include " SnapConfig.h"
7
10
#include " SnapLogger.h"
8
11
#include " SnapTime.h"
9
12
#include " SnapTimeSync.h"
10
- #include < stdint.h>
11
- #include < sys/time.h>
12
13
13
14
class SnapProcessor ;
15
+ class SnapProcessorRTOS ;
16
+
14
17
/* *
15
18
* @brief Simple Output Class which uses the AudioTools to build an output chain
16
19
* with volume control and a resampler
@@ -21,18 +24,16 @@ class SnapProcessor;
21
24
**/
22
25
23
26
class SnapOutput : public AudioInfoSupport {
24
- friend SnapProcessor;
25
- public:
26
- // singleton: only access via instance class method
27
- SnapOutput () {
28
- // audio_info.sample_rate = 48000;
29
- // audio_info.channels = 2;
30
- // audio_info.bits_per_sample = 16;
31
- }
27
+ friend SnapProcessor;
28
+ friend SnapProcessorRTOS;
29
+
30
+ public:
31
+ SnapOutput () = default ;
32
32
33
33
// / Starts the processing which is also starting the the dsp_i2s_task_handler
34
34
// / task
35
35
virtual bool begin () {
36
+ ESP_LOGI (TAG, " begin" );
36
37
is_sync_started = false ;
37
38
return audioBegin ();
38
39
}
@@ -41,7 +42,8 @@ friend SnapProcessor;
41
42
virtual size_t write (const uint8_t *data, size_t size) {
42
43
ESP_LOGD (TAG, " %zu" , size);
43
44
// only start to proces data after we received codec header
44
- if (!is_audio_begin_called){
45
+ if (!is_audio_begin_called) {
46
+ ESP_LOGI (TAG, " not started" );
45
47
return 0 ;
46
48
}
47
49
@@ -86,54 +88,51 @@ friend SnapProcessor;
86
88
87
89
// / Defines the audio output chain to the final output
88
90
void setOutput (AudioOutput &output) {
89
- this ->out = &output; // final output
91
+ this ->out = &output; // final output
90
92
resample.setStream (output);
91
- vol_stream.setStream (resample); // adjust volume
93
+ vol_stream.setStream (resample); // adjust volume
92
94
timed_stream.setStream (vol_stream);
93
- decoder_stream.setStream (&timed_stream); // decode to pcm
95
+ decoder_stream.setStream (&timed_stream); // decode to pcm
94
96
}
95
97
98
+ AudioOutput &getOutput () { return *out; }
99
+
96
100
// / Defines the decoder class
97
101
void setDecoder (AudioDecoder &dec) { decoder_stream.setDecoder (&dec); }
98
102
103
+ AudioDecoder &getDecoder () { return decoder_stream.decoder (); }
104
+
99
105
// / setup of all audio objects
100
106
void setAudioInfo (AudioInfo info) {
101
107
ESP_LOGI (TAG, " sample_rate: %d, channels: %d, bits: %d" , info.sample_rate ,
102
108
info.channels , info.bits_per_sample );
103
109
audio_info = info;
104
- if (is_audio_begin_called){
110
+ if (is_audio_begin_called) {
105
111
vol_stream.setAudioInfo (info);
106
112
out->setAudioInfo (info);
107
113
timed_stream.setAudioInfo (info);
108
114
}
109
115
}
110
116
111
- AudioInfo audioInfo (){
112
- return audio_info;
113
- }
117
+ AudioInfo audioInfo () { return audio_info; }
114
118
115
119
// / Defines the time synchronization logic
116
- void setSnapTimeSync (SnapTimeSync &timeSync){
117
- p_snap_time_sync = &timeSync;
118
- }
120
+ void setSnapTimeSync (SnapTimeSync &timeSync) { p_snap_time_sync = &timeSync; }
119
121
120
- // do nothing
121
- virtual void doLoop () {}
122
+ SnapTimeSync &snapTimeSync () { return *p_snap_time_sync; }
122
123
123
- SnapTimeSync& snapTimeSync () {
124
- return *p_snap_time_sync;
125
- }
124
+ bool isStarted () { return is_audio_begin_called; }
126
125
127
- protected:
126
+ protected:
128
127
const char *TAG = " SnapOutput" ;
129
128
AudioOutput *out = nullptr ;
130
129
AudioInfo audio_info;
131
130
EncodedAudioStream decoder_stream;
132
131
VolumeStream vol_stream;
133
132
ResampleStream resample;
134
133
TimedStream timed_stream;
135
- float vol = 1.0 ; // volume in the range 0.0 - 1.0
136
- float vol_factor = 1.0 ; //
134
+ float vol = 1.0 ; // volume in the range 0.0 - 1.0
135
+ float vol_factor = 1.0 ; //
137
136
bool is_mute = false ;
138
137
SnapAudioHeader header;
139
138
SnapTime &snap_time = SnapTime::instance();
@@ -144,9 +143,10 @@ friend SnapProcessor;
144
143
145
144
// / setup of all audio objects
146
145
bool audioBegin () {
147
-
148
- if ( out == nullptr )
146
+ if (out == nullptr ) {
147
+ ESP_LOGI (TAG, " out is null " );
149
148
return false ;
149
+ }
150
150
151
151
// open volume control: allow amplification
152
152
auto vol_cfg = vol_stream.defaultConfig ();
@@ -178,7 +178,6 @@ friend SnapProcessor;
178
178
return true ;
179
179
}
180
180
181
-
182
181
// / to speed up or slow down playback
183
182
void setPlaybackFactor (float fact) { resample.setStepSize (fact); }
184
183
@@ -193,8 +192,7 @@ friend SnapProcessor;
193
192
194
193
void audioEnd () {
195
194
ESP_LOGD (TAG, " start" );
196
- if (out == nullptr )
197
- return ;
195
+ if (out == nullptr ) return ;
198
196
out->end ();
199
197
}
200
198
@@ -210,19 +208,18 @@ friend SnapProcessor;
210
208
// / ignored - update playback speed
211
209
bool synchronizePlayback () {
212
210
bool result = true ;
213
- SnapTimeSync& ts = *p_snap_time_sync;
211
+ SnapTimeSync & ts = *p_snap_time_sync;
214
212
215
213
// calculate how long we need to wait to playback the audio
216
214
auto delay_ms = getDelayMs ();
217
215
218
216
if (!is_sync_started) {
219
-
220
217
ts.begin (audio_info.sample_rate );
221
218
222
219
// start audio when first package in the future becomes valid
223
220
result = synchronizeOnStart (delay_ms);
224
221
} else {
225
- // provide the actual delay to the synch
222
+ // provide the actual delay to the synch
226
223
ts.updateActualDelay (delay_ms);
227
224
228
225
if (ts.isSync ()) {
0 commit comments