Skip to content

Instantly share code, notes, and snippets.

@alkhimey
Created August 22, 2019 19:07
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alkhimey/a705d563aaa9a470332e7ad5487d7d0e to your computer and use it in GitHub Desktop.
Save alkhimey/a705d563aaa9a470332e7ad5487d7d0e to your computer and use it in GitHub Desktop.
Code for playing music on ESP8266 using the PCM5102 chip
#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