Encouraged by the happy ending of the Swinging Needles project, I decided to revisit an earlier audio spectrum analyzer. This time, instead of programmatically processing analog signals, I used a VS1053 plugin to let the chip do the Fourier stuff.
Before even starting to read actual frequency band values, I wanted to test my sketch by reading the plugin’s default frequency settings from VS1053’s memory. However, some of these readings made no sense at all, up to the point that I suspected a faulty chip. It took me some time to find out that the chip needs a few seconds of audio input before it will tell you something useful, even if it concerns a fixed setting like number of frequency bands.
Once the above mystery was solved, things became very straightforward. What a versatile chip this VS1053 is! While playing a 320 Kbps internet radio station, it can easily handle 14 frequency bands and let an esp8266 at 160 MHz show the results on a 128×64 Oled display.
Running the test sketch (without amplifier/speakers).
Here’s the sketch that I wrote for testing: a fixed-station internet radio (no metadata, no audio buffer), just to show a 14 band spectrum analyzer on a 128×64 SH1106 Oled display. Used pins are for the rather rare Wemos D1 R1, so you’ll probably have to change them.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
// Spectrum analyzer plugin demo on a 128x64 monochrome OLED display (SH1106). // Uses the plugin's 14 default frequency bins: // 50, 79, 126, 200, 317, 504, 800, 1270, 2016, 3200, 5080, 8063, 12800, and 20319 Hz #include "plugin.h" // spectrum analyzer plugin #include <brzo_i2c.h> #include "SH1106Brzo.h" #include <SPI.h> #include <Adafruit_VS1053.h> #include <ESP8266WiFi.h> SH1106Brzo display(0x3c, D14, D15); // address, SDA, SCL #define BASE 0x1800 char* ssid = "<your_SSID"; const char* password = "<your_WiFi_password"; const char *host = "icecast.omroep.nl"; const char *path = "/radio4-bb-mp3"; int httpPort = 80; uint32_t val; int waarde,piek; uint8_t mp3buff[32]; int loopcounter = 0; // defines are for the old Wemos D1 R1; change these for your board #define VS1053_RESET -1 // connect RST pins of ESP and VS1053 #define VS1053_CS D10 #define VS1053_DCS D2 // labeled 'XDCS' #define VS1053_DREQ D9 Adafruit_VS1053 musicPlayer = Adafruit_VS1053(VS1053_RESET, VS1053_CS, VS1053_DCS, VS1053_DREQ); WiFiClient client; void drawBin(int bin_nr, int waarde, int piek) { display.setColor(WHITE); display.fillRect(9 * bin_nr - 6, 63 - 2 * waarde, 6, 2 * waarde); display.fillRect(9 * bin_nr - 6, 63 - 2 * piek, 6, 1); } void setup() { display.init(); display.flipScreenVertically(); display.clear(); Serial.begin(115200); // for debugging delay(5); if (! musicPlayer.begin()) { // initialise the music player while (1) delay(10); } Serial.println("VS1053 started"); delay(1000); musicPlayer.applyPatch(plugin, PLUGIN_SIZE); delay(200); yield(); musicPlayer.setVolume(50, 50); delay(200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); } if (!client.connect(host, httpPort)) { return; } client.print(String("GET ") + path + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n"); } void loop() { loopcounter++; if (musicPlayer.readyForData()) { if (client.available() > 0) { uint8_t bytesread = client.read(mp3buff, 32); musicPlayer.playData(mp3buff, bytesread); } } else { if (loopcounter >= 2000) { // being nice to the chip here... loopcounter = 0; musicPlayer.sciWrite(VS1053_REG_WRAMADDR, BASE + 4); delay(2); display.clear(); for (int b = 0; b < 14; b++) { val = musicPlayer.sciRead(VS1053_REG_WRAM); delay(2); waarde = val & 63; piek = (val>>6) & 63; drawBin(b, waarde, piek); } display.display(); } } } |
This is the content of the plugin.h file that needs to be in the directory of the sketch:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
#ifndef SKIP_PLUGIN_VARNAME PROGMEM const unsigned short plugin[] = { /* Compressed plugin */ #endif 0x0007, 0x0001, 0x8050, 0x0006, 0x0018, 0x3613, 0x0024, 0x3e00, /* 0 */ 0x3801, 0x0000, 0x16d7, 0xf400, 0x55c0, 0x0000, 0x0c17, 0xf400, /* 8 */ 0x57c0, 0x0007, 0x9257, 0xb080, 0x0024, 0x3f00, 0x0024, 0x2000, /* 10 */ 0x0000, 0x36f0, 0x1801, 0x2800, 0x31c0, 0x0007, 0x0001, 0x805c, /* 18 */ 0x0006, 0x00d6, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, /* 20 */ 0x3615, 0x0024, 0x0000, 0x800a, 0x3e10, 0x3801, 0x0006, 0x0000, /* 28 */ 0x3e10, 0xb803, 0x0000, 0x0303, 0x3e11, 0x3805, 0x3e11, 0xb807, /* 30 */ 0x3e14, 0x3812, 0xb884, 0x130c, 0x3410, 0x4024, 0x4112, 0x10d0, /* 38 */ 0x4010, 0x008c, 0x4010, 0x0024, 0xf400, 0x4012, 0x3000, 0x3840, /* 40 */ 0x3009, 0x3801, 0x0000, 0x0041, 0xfe02, 0x0024, 0x2900, 0x8200, /* 48 */ 0x48b2, 0x0024, 0x36f3, 0x0844, 0x6306, 0x8845, 0xae3a, 0x8840, /* 50 */ 0xbf8e, 0x8b41, 0xac32, 0xa846, 0xffc8, 0xabc7, 0x3e01, 0x7800, /* 58 */ 0xf400, 0x4480, 0x6090, 0x0024, 0x6090, 0x0024, 0xf400, 0x4015, /* 60 */ 0x3009, 0x3446, 0x3009, 0x37c7, 0x3009, 0x1800, 0x3009, 0x3844, /* 68 */ 0x48b3, 0xe1e0, 0x4882, 0x4040, 0xfeca, 0x0024, 0x5ac2, 0x0024, /* 70 */ 0x5a52, 0x0024, 0x4cc2, 0x0024, 0x48ba, 0x4040, 0x4eea, 0x4801, /* 78 */ 0x4eca, 0x9800, 0xff80, 0x1bc1, 0xf1eb, 0xe3e2, 0xf1ea, 0x184c, /* 80 */ 0x4c8b, 0xe5e4, 0x48be, 0x9804, 0x488e, 0x41c6, 0xfe82, 0x0024, /* 88 */ 0x5a8e, 0x0024, 0x525e, 0x1b85, 0x4ffe, 0x0024, 0x48b6, 0x41c6, /* 90 */ 0x4dd6, 0x48c7, 0x4df6, 0x0024, 0xf1d6, 0x0024, 0xf1d6, 0x0024, /* 98 */ 0x4eda, 0x0024, 0x0000, 0x0fc3, 0x2900, 0x8200, 0x4e82, 0x0024, /* a0 */ 0x4084, 0x130c, 0x0006, 0x0100, 0x3440, 0x4024, 0x4010, 0x0024, /* a8 */ 0xf400, 0x4012, 0x3200, 0x4024, 0xb132, 0x0024, 0x4214, 0x0024, /* b0 */ 0xf224, 0x0024, 0x6230, 0x0024, 0x0001, 0x0001, 0x2800, 0x2b49, /* b8 */ 0x0000, 0x0024, 0xf400, 0x40c2, 0x3200, 0x0024, 0xff82, 0x0024, /* c0 */ 0x48b2, 0x0024, 0xb130, 0x0024, 0x6202, 0x0024, 0x003f, 0xf001, /* c8 */ 0x2800, 0x2e51, 0x0000, 0x1046, 0xfe64, 0x0024, 0x48be, 0x0024, /* d0 */ 0x2800, 0x2f40, 0x3a01, 0x8024, 0x3200, 0x0024, 0xb010, 0x0024, /* d8 */ 0xc020, 0x0024, 0x3a00, 0x0024, 0x36f4, 0x1812, 0x36f1, 0x9807, /* e0 */ 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f0, 0x1801, 0x3405, 0x9014, /* e8 */ 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, /* f0 */ 0x0007, 0x0001, 0x80c7, 0x0006, 0x01ae, 0x3e12, 0xb817, 0x3e12, /* f8 */ 0x3815, 0x3e05, 0xb814, 0x3625, 0x0024, 0x0000, 0x800a, 0x3e10, /* 100 */ 0x7802, 0x3e10, 0xf804, 0x3e11, 0x7810, 0x3e14, 0x7813, 0x0006, /* 108 */ 0x0051, 0x3e13, 0xf80e, 0x3e13, 0x4024, 0x3009, 0x3840, 0x3009, /* 110 */ 0x3852, 0x2911, 0xf140, 0x0006, 0x06d0, 0x3100, 0x5bd2, 0x0006, /* 118 */ 0xc351, 0x3009, 0x1bc0, 0x3009, 0x0402, 0x6126, 0x0024, 0x0006, /* 120 */ 0x00d1, 0x2800, 0x4d45, 0x0000, 0x0024, 0x0006, 0x0011, 0xb882, /* 128 */ 0x184c, 0x3009, 0x3850, 0x0006, 0x0010, 0x3009, 0x3800, 0x2914, /* 130 */ 0xbec0, 0x0000, 0x1800, 0x0006, 0x0010, 0xb882, 0x0024, 0x2915, /* 138 */ 0x7ac0, 0x0000, 0x1700, 0x0000, 0x0301, 0x3900, 0x5bc0, 0x0006, /* 140 */ 0xc351, 0x3009, 0x1bd0, 0x3009, 0x0404, 0x0006, 0x0051, 0x2800, /* 148 */ 0x3d40, 0x3901, 0x0024, 0x4448, 0x0401, 0x4192, 0x0024, 0x6498, /* 150 */ 0x2401, 0x001f, 0x4001, 0x6412, 0x0024, 0x0006, 0x0011, 0x2800, /* 158 */ 0x3c91, 0x0000, 0x058e, 0x2400, 0x4c4e, 0x0000, 0x0013, 0x0006, /* 160 */ 0x0051, 0x0006, 0x1a03, 0x3100, 0x4024, 0xf212, 0x44c4, 0x4346, /* 168 */ 0x0024, 0xf400, 0x40d5, 0x3500, 0x8024, 0x612a, 0x0024, 0x0000, /* 170 */ 0x0024, 0x2800, 0x4c91, 0x0000, 0x0024, 0x3613, 0x0024, 0x3100, /* 178 */ 0x3800, 0x2915, 0x7dc0, 0xf200, 0x0024, 0x003f, 0xfec2, 0x4082, /* 180 */ 0x4411, 0x3113, 0x1bc0, 0xa122, 0x0024, 0x0000, 0x2002, 0x6124, /* 188 */ 0x2401, 0x0000, 0x1002, 0x2800, 0x4648, 0x0000, 0x0024, 0x003f, /* 190 */ 0xf802, 0x3100, 0x4024, 0xb124, 0x0024, 0x2800, 0x4c00, 0x3900, /* 198 */ 0x8024, 0x6124, 0x0024, 0x0000, 0x0802, 0x2800, 0x4888, 0x0000, /* 1a0 */ 0x0024, 0x003f, 0xfe02, 0x3100, 0x4024, 0xb124, 0x0024, 0x2800, /* 1a8 */ 0x4c00, 0x3900, 0x8024, 0x6124, 0x0024, 0x0000, 0x0402, 0x2800, /* 1b0 */ 0x4ac8, 0x0000, 0x0024, 0x003f, 0xff02, 0x3100, 0x4024, 0xb124, /* 1b8 */ 0x0024, 0x2800, 0x4c00, 0x3900, 0x8024, 0x6124, 0x0401, 0x003f, /* 1c0 */ 0xff82, 0x2800, 0x4c08, 0xb124, 0x0024, 0x3900, 0x8024, 0xb882, /* 1c8 */ 0x8c4c, 0x3830, 0x4024, 0x0006, 0x0091, 0x3904, 0xc024, 0x0006, /* 1d0 */ 0x00d1, 0x0000, 0x0013, 0x3100, 0x904c, 0x4202, 0x0024, 0x39f0, /* 1d8 */ 0x4024, 0x3100, 0x4024, 0x3c00, 0x4024, 0xf400, 0x44c1, 0x34f0, /* 1e0 */ 0x8024, 0x6126, 0x0024, 0x0006, 0x06d0, 0x2800, 0x5b98, 0x4294, /* 1e8 */ 0x0024, 0x2400, 0x5b42, 0x0000, 0x0024, 0xf400, 0x4411, 0x3123, /* 1f0 */ 0x0024, 0x3100, 0x8024, 0x4202, 0x0024, 0x4182, 0x2401, 0x0000, /* 1f8 */ 0x2002, 0x2800, 0x5b49, 0x0000, 0x0024, 0x3013, 0x184c, 0x30f0, /* 200 */ 0x7852, 0x6124, 0xb850, 0x0006, 0x0001, 0x2800, 0x55c8, 0x4088, /* 208 */ 0x44c2, 0x4224, 0x0024, 0x4122, 0x0024, 0x4122, 0x0024, 0xf400, /* 210 */ 0x4051, 0x2900, 0x7200, 0x0000, 0x5708, 0x4224, 0x0024, 0x4122, /* 218 */ 0x0024, 0x4122, 0x0024, 0x2900, 0x6780, 0xf400, 0x4051, 0x0002, /* 220 */ 0x0002, 0x3009, 0x1bd0, 0x3023, 0x1bd2, 0x30e0, 0x4024, 0x6124, /* 228 */ 0x0024, 0x0000, 0x0024, 0x2800, 0x5b48, 0x0000, 0x0024, 0x3613, /* 230 */ 0x0024, 0x3e14, 0xc024, 0x2900, 0x1700, 0x3e14, 0x0024, 0x36e3, /* 238 */ 0x008c, 0x30e0, 0x8024, 0x6822, 0x4411, 0x3123, 0x0024, 0x3900, /* 240 */ 0x4024, 0x3033, 0x0c4c, 0x0006, 0x0011, 0x6892, 0x04c2, 0xa122, /* 248 */ 0x0402, 0x6126, 0x0024, 0x0006, 0x0093, 0x2800, 0x64c1, 0x0000, /* 250 */ 0x0024, 0xb882, 0x184c, 0x3413, 0x3812, 0x0006, 0x00d2, 0x3a00, /* 258 */ 0x5bd2, 0x3300, 0x4024, 0x0000, 0x0013, 0x3c00, 0x4024, 0xf400, /* 260 */ 0x44c1, 0x34f0, 0x8024, 0x6126, 0x0024, 0x0006, 0x0111, 0x2800, /* 268 */ 0x64d8, 0x4294, 0x0024, 0x2400, 0x6482, 0x0000, 0x0024, 0x0003, /* 270 */ 0xf001, 0x3101, 0x0024, 0xb412, 0x0024, 0x0028, 0x0001, 0x2800, /* 278 */ 0x6485, 0x6144, 0x0024, 0x0004, 0x0002, 0x2800, 0x6441, 0x4422, /* 280 */ 0x0024, 0x0000, 0x1002, 0x6422, 0x0024, 0x2800, 0x6480, 0x3900, /* 288 */ 0x4024, 0x3900, 0x4024, 0x3113, 0x0c4c, 0x36f3, 0x4024, 0x36f3, /* 290 */ 0xd80e, 0x36f4, 0x5813, 0x36f1, 0x5810, 0x36f0, 0xd804, 0x36f0, /* 298 */ 0x5802, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, /* 2a0 */ 0x0000, 0x36f2, 0x9817, 0x0007, 0x0001, 0x1868, 0x0006, 0x000f, /* 2a8 */ 0x0032, 0x004f, 0x007e, 0x00c8, 0x013d, 0x01f8, 0x0320, 0x04f6, /* 2b0 */ 0x07e0, 0x0c80, 0x13d8, 0x1f7f, 0x3200, 0x4f5f, 0x61a8, 0x0006, /* 2b8 */ 0x8008, 0x0000, 0x0007, 0x0001, 0x819e, 0x0006, 0x0054, 0x3e12, /* 2c0 */ 0xb814, 0x0000, 0x800a, 0x3e10, 0x3801, 0x3e10, 0xb803, 0x3e11, /* 2c8 */ 0x7806, 0x3e11, 0xf813, 0x3e13, 0xf80e, 0x3e13, 0x4024, 0x3e04, /* 2d0 */ 0x7810, 0x449a, 0x0040, 0x0001, 0x0003, 0x2800, 0x70c4, 0x4036, /* 2d8 */ 0x03c1, 0x0003, 0xffc2, 0xb326, 0x0024, 0x0018, 0x0042, 0x4326, /* 2e0 */ 0x4495, 0x4024, 0x40d2, 0x0000, 0x0180, 0xa100, 0x4090, 0x0010, /* 2e8 */ 0x0fc2, 0x4204, 0x0024, 0xbc82, 0x4091, 0x459a, 0x0024, 0x0000, /* 2f0 */ 0x0054, 0x2800, 0x6fc4, 0xbd86, 0x4093, 0x2400, 0x6f85, 0xfe01, /* 2f8 */ 0x5e0c, 0x5c43, 0x5f2d, 0x5e46, 0x020c, 0x5c56, 0x8a0c, 0x5e53, /* 300 */ 0x5e0c, 0x5c43, 0x5f2d, 0x5e46, 0x020c, 0x5c56, 0x8a0c, 0x5e52, /* 308 */ 0x0024, 0x4cb2, 0x4405, 0x0018, 0x0044, 0x654a, 0x0024, 0x2800, /* 310 */ 0x7dc0, 0x36f4, 0x5810, 0x0007, 0x0001, 0x81c8, 0x0006, 0x0080, /* 318 */ 0x3e12, 0xb814, 0x0000, 0x800a, 0x3e10, 0x3801, 0x3e10, 0xb803, /* 320 */ 0x3e11, 0x7806, 0x3e11, 0xf813, 0x3e13, 0xf80e, 0x3e13, 0x4024, /* 328 */ 0x3e04, 0x7810, 0x449a, 0x0040, 0x0000, 0x0803, 0x2800, 0x7c84, /* 330 */ 0x30f0, 0x4024, 0x0fff, 0xfec2, 0xa020, 0x0024, 0x0fff, 0xff02, /* 338 */ 0xa122, 0x0024, 0x4036, 0x0024, 0x0000, 0x1fc2, 0xb326, 0x0024, /* 340 */ 0x0010, 0x4002, 0x4326, 0x4495, 0x4024, 0x40d2, 0x0000, 0x0180, /* 348 */ 0xa100, 0x4090, 0x0010, 0x0042, 0x4204, 0x0024, 0xbc82, 0x4091, /* 350 */ 0x459a, 0x0024, 0x0000, 0x0054, 0x2800, 0x7b84, 0xbd86, 0x4093, /* 358 */ 0x2400, 0x7b45, 0xfe01, 0x5e0c, 0x5c43, 0x5f2d, 0x5e46, 0x0024, /* 360 */ 0x5c56, 0x0024, 0x5e53, 0x5e0c, 0x5c43, 0x5f2d, 0x5e46, 0x0024, /* 368 */ 0x5c56, 0x0024, 0x5e52, 0x0024, 0x4cb2, 0x4405, 0x0010, 0x4004, /* 370 */ 0x654a, 0x9810, 0x0000, 0x0144, 0xa54a, 0x1bd1, 0x0006, 0x0013, /* 378 */ 0x3301, 0xc444, 0x687e, 0x2005, 0xad76, 0x8445, 0x4ed6, 0x8784, /* 380 */ 0x36f3, 0x64c2, 0xac72, 0x8785, 0x4ec2, 0xa443, 0x3009, 0x2440, /* 388 */ 0x3009, 0x2741, 0x36f3, 0xd80e, 0x36f1, 0xd813, 0x36f1, 0x5806, /* 390 */ 0x36f0, 0x9803, 0x36f0, 0x1801, 0x2000, 0x0000, 0x36f2, 0x9814, /* 398 */ 0x0007, 0x0001, 0x8208, 0x0006, 0x000e, 0x4c82, 0x0024, 0x0000, /* 3a0 */ 0x0024, 0x2000, 0x0005, 0xf5c2, 0x0024, 0x0000, 0x0980, 0x2000, /* 3a8 */ 0x0000, 0x6010, 0x0024, 0x000a, 0x0001, 0x0050, #define PLUGIN_SIZE 950 #ifndef SKIP_PLUGIN_VARNAME }; #endif |