arduino-audio-tools
All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Modules Pages
WM8960Stream.h
1#pragma once
2
3#include "AudioTools/CoreAudio/AudioStreams.h"
4#include "AudioTools/CoreAudio/AudioI2S/I2SStream.h"
5#include "mtb_wm8960.h" // https://github.com/pschatzmann/arduino-wm8960
6
7namespace audio_tools {
8
14class WM8960Config : public I2SConfig {
15 public:
16 WM8960Config() : I2SConfig() {}
18 sample_rate = 44100;
19 channels = 2;
20 bits_per_sample = 16;
21 }
23 float default_volume = 0.6;
25 bool vs1053_enable_pll = true;
27 uint32_t vs1053_mclk_hz = 0;
29 TwoWire *wire=nullptr;
31 bool vs1053_dump = false;
33 uint32_t i2c_retry_count = 0;
34 // optional features: use bitmask with WM8960_FEATURE_MICROPHONE,WM8960_FEATURE_HEADPHONE,WM8960_FEATURE_SPEAKER
35 int8_t features = -1;
36
37};
38
46class WM8960Stream : public AudioStream {
47
48public:
49
50 WM8960Stream() = default;
51
52 WM8960Config defaultConfig(RxTxMode mode=TX_MODE) {
53 TRACED();
54 WM8960Config c(mode);
55 return c;
56 }
57
60 cfg = c;
61 begin(c);
62 }
63
65 cfg.copyFrom(c);
66 begin(cfg);
67 }
68
70 bool begin() {
71 return begin(cfg);
72 }
73
75 bool begin(WM8960Config config) {
76 TRACEI();
77 cfg = config;
78
79 // setup wm8960
80 if (!init(cfg.rx_tx_mode)){
81 LOGE("init");
82 return false;
83 }
85 if (!mtb_wm8960_activate()){
86 LOGE("mtb_wm8960_activate");
87 return false;
88 }
89 if (!configure_clocking()){
90 LOGE("configure_clocking");
91 return false;
92 }
93 if (config.vs1053_dump){
94 mtb_wm8960_dump();
95 }
96
97 // setup output
98 i2s.begin(cfg);
99
100 return true;
101 }
102
104 void end(){
105 TRACEI();
106 i2s.end();
107 mtb_wm8960_deactivate();
108 mtb_wm8960_free();
109 }
110
112 bool setVolume(float vol){
113 // make sure that value is between 0 and 1
114 setVolumeIn(vol);
115 setVolumeOut(vol);
116 return true;
117 }
118
119 void setVolumeIn(float vol){
120 adjustInputVolume(vol);
121 }
122
123 void setVolumeOut(float vol){
124 setOutputVolume(vol);
125 }
126
128 float volumeIn() {
129 return volume_in;
130 }
131
132 float volumeOut() {
133 return volume_out;
134 }
135
136 size_t readBytes (uint8_t *data, size_t size) override{
137 return i2s.readBytes(data, size);
138 }
139
140 size_t write (const uint8_t *data, size_t size) override {
141 return i2s.write(data, size);
142 }
143
144protected:
145 WM8960Config cfg;
146 I2SStream i2s;
147 float volume_in;
148 float volume_out;
149
150 void adjustInputVolume(float vol){
151 if (vol>1.0f) {
152 volume_in = 1.0f;
153 volumeError(vol);
154 } else if (vol<0.0f){
155 volume_in = 0.0f;
156 volumeError(vol);
157 } else {
158 volume_in = vol;
159 }
160 int vol_int = map(volume_in*100, 0, 100, 0 ,30);
161 mtb_wm8960_adjust_input_volume(vol_int);
162 }
163
164 void setOutputVolume(float vol){
165 if (vol>1.0f) {
166 volume_out = 1.0f;
167 volumeError(vol);
168 } else if (vol<0.0f){
169 volume_out = 0.0f;
170 volumeError(vol);
171 } else {
172 volume_out = vol;
173 }
174 int vol_int = volume_out==0.0? 0 : map(volume_out*100, 0, 100, 30 ,0x7F);
175 mtb_wm8960_set_output_volume(vol_int);
176 }
177
178 bool init(RxTxMode mode){
179 mtb_wm8960_set_write_retry_count(cfg.i2c_retry_count);
180 // define wire object
181 mtb_wm8960_set_wire(cfg.wire);
182
183 // init features if not defined depending on mode
184 if (cfg.features==-1){
185 switch(mode){
186 case RX_MODE:
187 cfg.features = WM8960_FEATURE_MICROPHONE1;
188 break;
189 case TX_MODE:
190 cfg.features = WM8960_FEATURE_HEADPHONE | WM8960_FEATURE_SPEAKER;
191 break;
192 case RXTX_MODE:
193 cfg.features = WM8960_FEATURE_MICROPHONE1 | WM8960_FEATURE_HEADPHONE | WM8960_FEATURE_SPEAKER;
194 break;
195 }
196 LOGW("Setup features: %d", cfg.features);
197 }
198 return mtb_wm8960_init(cfg.features);
199 }
200
201 bool configure_clocking(){
202 if (cfg.vs1053_mclk_hz==0){
203 // just pick a multiple of the sample rate
204 cfg.vs1053_mclk_hz = 512 * cfg.sample_rate;
205 }
206 if (!mtb_wm8960_configure_clocking(cfg.vs1053_mclk_hz, cfg.vs1053_enable_pll, sampleRate(cfg.sample_rate), wordLength(cfg.bits_per_sample), modeMasterSlave(cfg.is_master))){
207 LOGE("mtb_wm8960_configure_clocking");
208 return false;
209 }
210 return true;
211 }
212
213 mtb_wm8960_adc_dac_sample_rate_t sampleRate(int rate){
214 switch(rate){
215 case 48000:
216 return WM8960_ADC_DAC_SAMPLE_RATE_48_KHZ;
217 case 44100:
218 return WM8960_ADC_DAC_SAMPLE_RATE_44_1_KHZ;
219 case 32000:
220 return WM8960_ADC_DAC_SAMPLE_RATE_32_KHZ;
221 case 24000:
222 return WM8960_ADC_DAC_SAMPLE_RATE_24_KHZ;
223 case 22050:
224 return WM8960_ADC_DAC_SAMPLE_RATE_22_05_KHZ;
225 case 16000:
226 return WM8960_ADC_DAC_SAMPLE_RATE_16_KHZ;
227 case 12000:
228 return WM8960_ADC_DAC_SAMPLE_RATE_12_KHZ;
229 case 11025:
230 return WM8960_ADC_DAC_SAMPLE_RATE_11_025_KHZ;
231 case 8018:
232 return WM8960_ADC_DAC_SAMPLE_RATE_8_018_KHZ;
233 case 8000:
234 return WM8960_ADC_DAC_SAMPLE_RATE_8_KHZ;
235 default:
236 LOGE("Unsupported rate: %d",rate);
237 return WM8960_ADC_DAC_SAMPLE_RATE_44_1_KHZ;
238 }
239 }
240
241 mtb_wm8960_word_length_t wordLength(int bits){
242 switch(bits){
243 case 16:
244 return WM8960_WL_16BITS;
245 case 20:
246 return WM8960_WL_20BITS;
247 case 24:
248 return WM8960_WL_24BITS;
249 case 32:
250 return WM8960_WL_32BITS;
251 default:
252 LOGE("Unsupported bits: %d", bits);
253 return WM8960_WL_16BITS;
254 }
255 }
256
258 mtb_wm8960_mode_t modeMasterSlave(bool microcontroller_is_master){
259 return microcontroller_is_master ? WM8960_MODE_SLAVE : WM8960_MODE_MASTER;
260 }
261
262 void volumeError(float vol){
263 LOGE("Invalid volume %f", vol);
264 }
265};
266
267}
Base class for all Audio Streams. It support the boolean operator to test if the object is ready with...
Definition BaseStream.h:119
Configuration for ESP32 legacy i2s.
Definition I2SConfigESP32.h:23
RxTxMode rx_tx_mode
public settings
Definition I2SConfigESP32.h:59
virtual size_t readBytes(uint8_t *data, size_t len) override
Reads the audio data.
Definition I2SStream.h:125
virtual size_t write(const uint8_t *data, size_t len)
Writes the audio data to I2S.
Definition I2SStream.h:118
void end()
Stops the I2S interface.
Definition I2SStream.h:85
Configuration for WM8960.
Definition WM8960Stream.h:14
bool vs1053_enable_pll
enalbel pll for wm8960 - default is true
Definition WM8960Stream.h:25
TwoWire * wire
Define wire if we do not use the default Wire object.
Definition WM8960Stream.h:29
uint32_t i2c_retry_count
Number of i2c write retry on fail: 0 = endless until success.
Definition WM8960Stream.h:33
bool vs1053_dump
Dump registers.
Definition WM8960Stream.h:31
uint32_t vs1053_mclk_hz
masterclock rate for wm8960 - default is 0
Definition WM8960Stream.h:27
float default_volume
Volume that is used on start (range 0.0 to 1.0)
Definition WM8960Stream.h:23
Stream for reading and writing audio data using the WM8960 Codec Chip You need to install https://git...
Definition WM8960Stream.h:46
mtb_wm8960_mode_t modeMasterSlave(bool microcontroller_is_master)
if microcontroller is master then module is slave
Definition WM8960Stream.h:258
float volumeIn()
provides the volume
Definition WM8960Stream.h:128
void setAudioInfo(AudioInfo c)
Defines the input AudioInfo.
Definition WM8960Stream.h:64
bool begin()
Starts with the default config or restarts.
Definition WM8960Stream.h:70
bool begin(WM8960Config config)
Starts with the indicated configuration.
Definition WM8960Stream.h:75
void setAudioInfo(WM8960Config c)
defines the default configuration that is used with the next begin()
Definition WM8960Stream.h:59
void end()
Stops the processing and releases the memory.
Definition WM8960Stream.h:104
bool setVolume(float vol)
Sets both input and output volume value (from 0 to 1.0)
Definition WM8960Stream.h:112
RxTxMode
The Microcontroller is the Audio Source (TX_MODE) or Audio Sink (RX_MODE). RXTX_MODE is Source and Si...
Definition AudioTypes.h:28
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
long map(long x, long in_min, long in_max, long out_min, long out_max)
Maps input to output values.
Definition NoArduino.h:188
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:53
void copyFrom(AudioInfo info)
Same as set.
Definition AudioTypes.h:103
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:55
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:57
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:59