Created
August 22, 2019 19:07
-
-
Save alkhimey/a705d563aaa9a470332e7ad5487d7d0e to your computer and use it in GitHub Desktop.
Code for playing music on ESP8266 using the PCM5102 chip
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "ESP8266WiFi.h" | |
#include "i2s.h" | |
#include "i2s_reg.h" | |
#define RATE 44100 | |
#define SINE_SAMPLES 512 | |
const int c = 261; | |
const int d = 294; | |
const int e = 329; | |
const int f = 349; | |
const int g = 391; | |
const int gS = 415; | |
const int a = 440; | |
const int aS = 455; | |
const int b = 466; | |
const int cH = 523; | |
const int cSH = 554; | |
const int dH = 587; | |
const int dSH = 622; | |
const int eH = 659; | |
const int fH = 698; | |
const int fSH = 740; | |
const int gH = 784; | |
const int gSH = 830; | |
const int aH = 880; | |
int16_t sine[SINE_SAMPLES] = { | |
0x0000, 0x0192, 0x0325, 0x04b8, 0x064a, 0x07dd, 0x096f, 0x0b00, | |
0x0c92, 0x0e22, 0x0fb2, 0x1142, 0x12d1, 0x145f, 0x15ec, 0x1779, | |
0x1905, 0x1a8f, 0x1c19, 0x1da1, 0x1f29, 0x20af, 0x2234, 0x23b7, | |
0x253a, 0x26ba, 0x283a, 0x29b7, 0x2b33, 0x2cae, 0x2e27, 0x2f9d, | |
0x3113, 0x3286, 0x33f7, 0x3566, 0x36d3, 0x383e, 0x39a7, 0x3b0e, | |
0x3c72, 0x3dd4, 0x3f34, 0x4091, 0x41eb, 0x4343, 0x4499, 0x45ec, | |
0x473c, 0x4889, 0x49d4, 0x4b1b, 0x4c60, 0x4da2, 0x4ee1, 0x501d, | |
0x5155, 0x528b, 0x53bd, 0x54ec, 0x5618, 0x5741, 0x5866, 0x5987, | |
0x5aa6, 0x5bc0, 0x5cd7, 0x5deb, 0x5efb, 0x6007, 0x6110, 0x6214, | |
0x6315, 0x6413, 0x650c, 0x6601, 0x66f3, 0x67e0, 0x68c9, 0x69af, | |
0x6a90, 0x6b6d, 0x6c46, 0x6d1b, 0x6deb, 0x6eb8, 0x6f80, 0x7044, | |
0x7103, 0x71be, 0x7274, 0x7327, 0x73d4, 0x747e, 0x7522, 0x75c2, | |
0x765e, 0x76f5, 0x7787, 0x7815, 0x789e, 0x7923, 0x79a3, 0x7a1e, | |
0x7a94, 0x7b06, 0x7b73, 0x7bdb, 0x7c3e, 0x7c9d, 0x7cf6, 0x7d4b, | |
0x7d9b, 0x7de6, 0x7e2c, 0x7e6e, 0x7eaa, 0x7ee2, 0x7f14, 0x7f42, | |
0x7f6b, 0x7f8f, 0x7fae, 0x7fc8, 0x7fdd, 0x7fed, 0x7ff8, 0x7ffe, | |
0x7fff, 0x7ffc, 0x7ff3, 0x7fe5, 0x7fd3, 0x7fbb, 0x7f9f, 0x7f7d, | |
0x7f57, 0x7f2c, 0x7efc, 0x7ec6, 0x7e8c, 0x7e4e, 0x7e0a, 0x7dc1, | |
0x7d74, 0x7d21, 0x7cca, 0x7c6e, 0x7c0d, 0x7ba7, 0x7b3d, 0x7ace, | |
0x7a5a, 0x79e1, 0x7963, 0x78e1, 0x785a, 0x77cf, 0x773f, 0x76aa, | |
0x7611, 0x7573, 0x74d0, 0x7429, 0x737e, 0x72ce, 0x721a, 0x7161, | |
0x70a4, 0x6fe2, 0x6f1c, 0x6e52, 0x6d84, 0x6cb1, 0x6bda, 0x6aff, | |
0x6a20, 0x693d, 0x6855, 0x676a, 0x667a, 0x6587, 0x6490, 0x6394, | |
0x6295, 0x6193, 0x608c, 0x5f81, 0x5e73, 0x5d62, 0x5c4c, 0x5b33, | |
0x5a17, 0x58f7, 0x57d4, 0x56ad, 0x5583, 0x5455, 0x5324, 0x51f1, | |
0x50b9, 0x4f7f, 0x4e42, 0x4d02, 0x4bbe, 0x4a78, 0x492f, 0x47e3, | |
0x4694, 0x4543, 0x43ee, 0x4298, 0x413e, 0x3fe2, 0x3e84, 0x3d23, | |
0x3bc0, 0x3a5b, 0x38f3, 0x3789, 0x361d, 0x34af, 0x333f, 0x31cc, | |
0x3058, 0x2ee2, 0x2d6a, 0x2bf1, 0x2a76, 0x28f9, 0x277a, 0x25fa, | |
0x2479, 0x22f6, 0x2172, 0x1fec, 0x1e65, 0x1cdd, 0x1b54, 0x19ca, | |
0x183f, 0x16b3, 0x1526, 0x1398, 0x120a, 0x107a, 0x0eea, 0x0d5a, | |
0x0bc9, 0x0a38, 0x08a6, 0x0714, 0x0581, 0x03ef, 0x025c, 0x00c9, | |
0xff36, 0xfda3, 0xfc10, 0xfa7e, 0xf8eb, 0xf759, 0xf5c7, 0xf436, | |
0xf2a5, 0xf115, 0xef85, 0xedf5, 0xec67, 0xead9, 0xe94c, 0xe7c0, | |
0xe635, 0xe4ab, 0xe322, 0xe19a, 0xe013, 0xde8d, 0xdd09, 0xdb86, | |
0xda05, 0xd885, 0xd706, 0xd589, 0xd40e, 0xd295, 0xd11d, 0xcfa7, | |
0xce33, 0xccc0, 0xcb50, 0xc9e2, 0xc876, 0xc70c, 0xc5a4, 0xc43f, | |
0xc2dc, 0xc17b, 0xc01d, 0xbec1, 0xbd67, 0xbc11, 0xbabc, 0xb96b, | |
0xb81c, 0xb6d0, 0xb587, 0xb441, 0xb2fd, 0xb1bd, 0xb080, 0xaf46, | |
0xae0e, 0xacdb, 0xabaa, 0xaa7c, 0xa952, 0xa82b, 0xa708, 0xa5e8, | |
0xa4cc, 0xa3b3, 0xa29d, 0xa18c, 0xa07e, 0x9f73, 0x9e6c, 0x9d6a, | |
0x9c6b, 0x9b6f, 0x9a78, 0x9985, 0x9895, 0x97aa, 0x96c2, 0x95df, | |
0x9500, 0x9425, 0x934e, 0x927b, 0x91ad, 0x90e3, 0x901d, 0x8f5b, | |
0x8e9e, 0x8de5, 0x8d31, 0x8c81, 0x8bd6, 0x8b2f, 0x8a8c, 0x89ee, | |
0x8955, 0x88c0, 0x8830, 0x87a5, 0x871e, 0x869c, 0x861e, 0x85a5, | |
0x8531, 0x84c2, 0x8458, 0x83f2, 0x8391, 0x8335, 0x82de, 0x828b, | |
0x823e, 0x81f5, 0x81b1, 0x8173, 0x8139, 0x8103, 0x80d3, 0x80a8, | |
0x8082, 0x8060, 0x8044, 0x802c, 0x801a, 0x800c, 0x8003, 0x8000, | |
0x8001, 0x8007, 0x8012, 0x8022, 0x8037, 0x8051, 0x8070, 0x8094, | |
0x80bd, 0x80eb, 0x811d, 0x8155, 0x8191, 0x81d3, 0x8219, 0x8264, | |
0x82b4, 0x8309, 0x8362, 0x83c1, 0x8424, 0x848c, 0x84f9, 0x856b, | |
0x85e1, 0x865c, 0x86dc, 0x8761, 0x87ea, 0x8878, 0x890a, 0x89a1, | |
0x8a3d, 0x8add, 0x8b81, 0x8c2b, 0x8cd8, 0x8d8b, 0x8e41, 0x8efc, | |
0x8fbb, 0x907f, 0x9147, 0x9214, 0x92e4, 0x93b9, 0x9492, 0x956f, | |
0x9650, 0x9736, 0x981f, 0x990c, 0x99fe, 0x9af3, 0x9bec, 0x9cea, | |
0x9deb, 0x9eef, 0x9ff8, 0xa104, 0xa214, 0xa328, 0xa43f, 0xa559, | |
0xa678, 0xa799, 0xa8be, 0xa9e7, 0xab13, 0xac42, 0xad74, 0xaeaa, | |
0xafe2, 0xb11e, 0xb25d, 0xb39f, 0xb4e4, 0xb62b, 0xb776, 0xb8c3, | |
0xba13, 0xbb66, 0xbcbc, 0xbe14, 0xbf6e, 0xc0cb, 0xc22b, 0xc38d, | |
0xc4f1, 0xc658, 0xc7c1, 0xc92c, 0xca99, 0xcc08, 0xcd79, 0xceec, | |
0xd062, 0xd1d8, 0xd351, 0xd4cc, 0xd648, 0xd7c5, 0xd945, 0xdac5, | |
0xdc48, 0xddcb, 0xdf50, 0xe0d6, 0xe25e, 0xe3e6, 0xe570, 0xe6fa, | |
0xe886, 0xea13, 0xeba0, 0xed2e, 0xeebd, 0xf04d, 0xf1dd, 0xf36d, | |
0xf4ff, 0xf690, 0xf822, 0xf9b5, 0xfb47, 0xfcda, 0xfe6d, 0xffff | |
}; | |
/** | |
* Outputs a sine waveover I2S of the requested frequency for the | |
* requested duration of milliseconds. | |
*/ | |
void writeNote(uint32 freq, uint32 duration) | |
{ | |
if (freq == 0 || duration == 0) { | |
return; | |
} | |
// Number of samples required for the requested duration | |
uint32 totalSamples = (RATE * duration) / 1000; | |
// Number of samples in full period of a sine wave for that particular frequency | |
uint32 samplesPerPeriod = RATE / freq; | |
// Round down total samples to an integer number of sine periods | |
totalSamples = (totalSamples / samplesPerPeriod) * samplesPerPeriod; | |
for (uint32 i = 0; i < totalSamples; i++) { | |
uint32 sampleIdx = map(i % samplesPerPeriod, 0, samplesPerPeriod, 0, SINE_SAMPLES); | |
i2s_write_lr( sine[sampleIdx], sine[sampleIdx]); | |
} | |
delay(50); | |
} | |
void setup() { | |
system_update_cpu_freq(160); | |
i2s_begin(); | |
i2s_set_rate(RATE); | |
} | |
/* Notes are adapted form https://gist.github.com/nicksort/4736535 */ | |
void loop() | |
{ | |
//Play first section | |
firstSection(); | |
//Play second section | |
secondSection(); | |
//Variant 1 | |
writeNote(f, 250); | |
writeNote(gS, 500); | |
writeNote(f, 350); | |
writeNote(a, 125); | |
writeNote(cH, 500); | |
writeNote(a, 375); | |
writeNote(cH, 125); | |
writeNote(eH, 650); | |
delay(500); | |
//Repeat second section | |
secondSection(); | |
//Variant 2 | |
writeNote(f, 250); | |
writeNote(gS, 500); | |
writeNote(f, 375); | |
writeNote(cH, 125); | |
writeNote(a, 500); | |
writeNote(f, 375); | |
writeNote(cH, 125); | |
writeNote(a, 650); | |
delay(650); | |
} | |
void firstSection() | |
{ | |
writeNote(a, 500); | |
writeNote(a, 500); | |
writeNote(a, 500); | |
writeNote(f, 350); | |
writeNote(cH, 150); | |
writeNote(a, 500); | |
writeNote(f, 350); | |
writeNote(cH, 150); | |
writeNote(a, 650); | |
delay(500); | |
writeNote(eH, 500); | |
writeNote(eH, 500); | |
writeNote(eH, 500); | |
writeNote(fH, 350); | |
writeNote(cH, 150); | |
writeNote(gS, 500); | |
writeNote(f, 350); | |
writeNote(cH, 150); | |
writeNote(a, 650); | |
delay(500); | |
} | |
void secondSection() | |
{ | |
writeNote(aH, 500); | |
writeNote(a, 300); | |
writeNote(a, 150); | |
writeNote(aH, 500); | |
writeNote(gSH, 325); | |
writeNote(gH, 175); | |
writeNote(fSH, 125); | |
writeNote(fH, 125); | |
writeNote(fSH, 250); | |
delay(325); | |
writeNote(aS, 250); | |
writeNote(dSH, 500); | |
writeNote(dH, 325); | |
writeNote(cSH, 175); | |
writeNote(cH, 125); | |
writeNote(b, 125); | |
writeNote(cH, 250); | |
delay(350); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment