Music Box
This commit is contained in:
parent
76a5e8fca1
commit
98bf101060
67
Music Box/Music_box.ino
Normal file
67
Music Box/Music_box.ino
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#define SizeRegisterModules 20
|
||||||
|
#include "musics.h"
|
||||||
|
#include "QB.h"
|
||||||
|
#include "QBmusics.h"
|
||||||
|
|
||||||
|
int IDarg = 0;
|
||||||
|
String ParsedCommand[SizeRegisterModules];
|
||||||
|
|
||||||
|
int adding;
|
||||||
|
|
||||||
|
void ShowError(String errorMessage){
|
||||||
|
Serial.println("Error: \n "+errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShowMessage(String type, String Message){
|
||||||
|
Serial.println("["+type+"] "+Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
char getCharCommand(){
|
||||||
|
if (Serial.available() > 0) {
|
||||||
|
char cmdraw = Serial.read();
|
||||||
|
if (cmdraw > 0) return cmdraw;
|
||||||
|
}
|
||||||
|
return '?';
|
||||||
|
}
|
||||||
|
|
||||||
|
void mainL(String *args){
|
||||||
|
if(args[0] == "play") {
|
||||||
|
String prom = args[2];
|
||||||
|
int data = prom.toInt();
|
||||||
|
if(args[2] == "") {
|
||||||
|
Serial.println("Введите пин!");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(args[1] == "mario") {
|
||||||
|
mario(data,false);
|
||||||
|
}
|
||||||
|
if(args[1] == "Bells") {
|
||||||
|
bell(data,false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(9600);
|
||||||
|
ShowMessage("Note","Type ';' to indicate the end of command, and then press 'Enter'");
|
||||||
|
Serial.print("\n \n \n \n>");
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
char CharCommand = getCharCommand();
|
||||||
|
if (CharCommand != ';' && CharCommand != '?'){
|
||||||
|
Serial.print(CharCommand);
|
||||||
|
if (CharCommand == ' '){
|
||||||
|
IDarg++;
|
||||||
|
}else{
|
||||||
|
ParsedCommand[IDarg] += CharCommand;
|
||||||
|
}
|
||||||
|
}else if(CharCommand == ';'){
|
||||||
|
Serial.println(" ");
|
||||||
|
mainL(ParsedCommand);
|
||||||
|
IDarg = 0;
|
||||||
|
for (int i = 0;i<=20;i++) {ParsedCommand[i]="";}
|
||||||
|
Serial.print(">");
|
||||||
|
}
|
||||||
|
}
|
262
Music Box/QB.h
Normal file
262
Music Box/QB.h
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
#include "QBmusics.h"
|
||||||
|
int freq[7][12] = {
|
||||||
|
{65, 69, 73, 78, 82, 87, 92, 98, 104, 110, 117, 123}, //0 = Большая октава
|
||||||
|
{131, 139, 147, 156, 165, 175, 185, 196, 208, 220, 233, 247}, //1 = Малая октава
|
||||||
|
{262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494}, //2 = 1-я октава
|
||||||
|
{523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 932, 988}, //3 = 2-я октава
|
||||||
|
{1047, 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661, 1760, 1865, 1976}, //4 = 3-я октава
|
||||||
|
{2093, 2218, 2349, 2489, 2637, 2794, 2960, 3136, 3322, 3520, 3729, 3951}, //5 = 4-я октава
|
||||||
|
{4186, 4435, 4699, 4978, 5274, 5588, 5920, 6272, 6645, 7040, 7459, 7902}, //6 = 5-я октава
|
||||||
|
};
|
||||||
|
int extractNumber(int& myNumber, char Muz[], int& curPosition)
|
||||||
|
{
|
||||||
|
int digitsNumber=0;
|
||||||
|
int curDigit=0;
|
||||||
|
myNumber=0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if ((Muz[curPosition]> 47) && (Muz[curPosition]<58)) // Коды ASCII цифр '0' == 48 , "9' == 57
|
||||||
|
{
|
||||||
|
curDigit=Muz[curPosition]-48;
|
||||||
|
digitsNumber++;
|
||||||
|
myNumber=myNumber*10+curDigit;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return digitsNumber;
|
||||||
|
}
|
||||||
|
curPosition++;
|
||||||
|
}while(Muz[curPosition]!= '\0');
|
||||||
|
return digitsNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pointsCount(char Muz[], int& curPosition)
|
||||||
|
{
|
||||||
|
int pointsNumber=0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (Muz[curPosition]== '.')
|
||||||
|
{
|
||||||
|
pointsNumber++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return pointsNumber;
|
||||||
|
}
|
||||||
|
curPosition++;
|
||||||
|
}while(Muz[curPosition]!= '\0');
|
||||||
|
return pointsNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Qb_PLAY(int SoundPin,char Muz[])
|
||||||
|
{
|
||||||
|
static int generalOktava;
|
||||||
|
int oktava;
|
||||||
|
static int tempo=120; // Задание темпа или четвертных нот, которые исполняются в минуту. n от 32 до 255. По умолчанию 120
|
||||||
|
int Nota=0;
|
||||||
|
int curPosition, curNota4;
|
||||||
|
unsigned long currentNotaPauseDuration;
|
||||||
|
unsigned long currentNotaDuration;
|
||||||
|
unsigned long pauseDuration;
|
||||||
|
int takt=240000/tempo;
|
||||||
|
bool isNota;
|
||||||
|
bool isPause;
|
||||||
|
int pointsNum=0;
|
||||||
|
float generalNotaMultipl=0.875;
|
||||||
|
static float NotaLong;
|
||||||
|
float curMultipl;
|
||||||
|
float tempFlo;
|
||||||
|
float curPause;
|
||||||
|
unsigned long tempLong;
|
||||||
|
int i=0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
isNota=false;
|
||||||
|
isPause=false;
|
||||||
|
oktava=generalOktava;
|
||||||
|
switch(Muz[i]){
|
||||||
|
case '\0':{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'C':{
|
||||||
|
Nota=0;
|
||||||
|
isNota=true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'D':{
|
||||||
|
Nota=2;
|
||||||
|
isNota=true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'E':{
|
||||||
|
Nota=4;
|
||||||
|
isNota=true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'F':{
|
||||||
|
Nota=5;
|
||||||
|
isNota=true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'G':{
|
||||||
|
Nota=7;
|
||||||
|
isNota=true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'A':{
|
||||||
|
Nota=9;
|
||||||
|
isNota=true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'B':{
|
||||||
|
Nota=11;
|
||||||
|
isNota=true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'N':{// Nнота Играет определенную ноту (0 - 84) в диапазоне семи октав (0 - пауза).
|
||||||
|
curPosition=i+1;
|
||||||
|
if (extractNumber(curNota4, Muz, curPosition)){
|
||||||
|
i=curPosition-1;
|
||||||
|
if (curNota4){
|
||||||
|
curNota4--;
|
||||||
|
oktava=curNota4 / 12;
|
||||||
|
Nota=curNota4 % 12;
|
||||||
|
isNota=true;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
isPause=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'O':{ //Oоктава Задает текущую октаву (0 - 6).
|
||||||
|
curPosition=i+1;
|
||||||
|
if (extractNumber(oktava, Muz, curPosition)){
|
||||||
|
i=curPosition-1;
|
||||||
|
generalOktava=oktava;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '>':{
|
||||||
|
generalOktava++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '<':{
|
||||||
|
generalOktava--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'M':{
|
||||||
|
switch(Muz[i+1]){
|
||||||
|
case 'N':{ //MN Нормаль. Каждая нота звучит 7/8 времени, заданного в команде L
|
||||||
|
generalNotaMultipl=0.875; // =7/8
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'L':{ //ML Легато. Каждая нота звучит полный интервал времени, заданного в команде L
|
||||||
|
generalNotaMultipl=1.0;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'S':{ //MS Стаккато. Каждая нота звучит 3/4 времени, заданного в команде L
|
||||||
|
generalNotaMultipl=0.75; // =3/4
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'F':{ //MF Режим непосредственного исполнения. Т.е. на время проигрывания ноты программа приостанавливается. Используется по умолчанию
|
||||||
|
i++; //Сдвигаем точку чтения и ничего не делаем.
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'B':{ //MB проигрывние в буффер
|
||||||
|
i++; //Сдвигаем точку чтения и ничего не делаем.
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'L':{ //Lразмер Задает длительность каждой ноты (1 - 64). L1 - целая нота, L2 - 1/2 ноты и т.д.
|
||||||
|
curPosition=i+1;
|
||||||
|
if (extractNumber(curNota4, Muz, curPosition)){
|
||||||
|
i=curPosition-1;
|
||||||
|
tempFlo=float(curNota4);
|
||||||
|
NotaLong=1/tempFlo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'T':{ //Tтемп Задает темп исполнения в четвертях в минуту (32-255).По умолчанию 120
|
||||||
|
curPosition=i+1;
|
||||||
|
if (extractNumber(tempo, Muz, curPosition)){
|
||||||
|
i=curPosition-1;
|
||||||
|
takt=240000/tempo; // миллисекунд на 1 целую ноту. 240000= 60 сек * 1000 мсек/сек *4 четвертей в ноте
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'P':{ //Pпауза Задает паузу (1 - 64). P1 - пауза в целую ноту, P2 - пауза в 1/2 ноты и т.д.
|
||||||
|
curPosition=i+1;
|
||||||
|
if (extractNumber(curNota4, Muz, curPosition)){
|
||||||
|
tempFlo=float(curNota4);
|
||||||
|
curPause=1/tempFlo;
|
||||||
|
i=curPosition-1;
|
||||||
|
isPause=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ' ':{ //Есть в некоторых текстах. Вероятно это пауза длительностью в текущую ноту
|
||||||
|
curPause= NotaLong;
|
||||||
|
isPause=true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (isNota){
|
||||||
|
switch(Muz[i+1]){
|
||||||
|
case '#':{ // диез
|
||||||
|
Nota++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '+':{ // диез
|
||||||
|
Nota++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '-':{ // бемоль
|
||||||
|
Nota--;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
curPosition=i+1;
|
||||||
|
if (extractNumber(curNota4, Muz, curPosition)){
|
||||||
|
currentNotaDuration=takt/curNota4;
|
||||||
|
i=curPosition-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (oktava<0) oktava=0;
|
||||||
|
if (oktava>6) oktava=6;
|
||||||
|
if (isNota || isPause){
|
||||||
|
curPosition=i+1;
|
||||||
|
pointsNum=pointsCount(Muz, curPosition);
|
||||||
|
if (pointsNum) i=curPosition-1;
|
||||||
|
curMultipl=1.0;
|
||||||
|
for (int j=1; j<=pointsNum; j++) {
|
||||||
|
curMultipl= curMultipl * 1.5;
|
||||||
|
}
|
||||||
|
currentNotaPauseDuration=(takt*NotaLong);
|
||||||
|
}
|
||||||
|
if (isNota){
|
||||||
|
curMultipl=curMultipl*generalNotaMultipl;
|
||||||
|
currentNotaDuration= (currentNotaPauseDuration*curMultipl);
|
||||||
|
if (Nota<0) Nota=0;
|
||||||
|
if (Nota>11) Nota=11;
|
||||||
|
tempLong= freq[oktava][Nota];
|
||||||
|
tone(SoundPin,tempLong,currentNotaDuration);
|
||||||
|
delay(currentNotaPauseDuration);
|
||||||
|
}
|
||||||
|
if (isPause){
|
||||||
|
pauseDuration=takt*curPause*curMultipl;
|
||||||
|
delay(pauseDuration);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
} while (Muz[i]!= '\0');
|
||||||
|
}
|
10
Music Box/QBmusics.h
Normal file
10
Music Box/QBmusics.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include "QB.h"
|
||||||
|
#include "musics.h"
|
||||||
|
void bell(int pin, boolean next){
|
||||||
|
Qb_PLAY (pin,"MNT255L4O2DBAGL2D.L8DDL4DBAGL2E.L4EE>C<BAL1F+L4>DDC<A");
|
||||||
|
Qb_PLAY (pin,"L1BL4DBAGL2D.L8DDL4DBAGL2E.L4EE>C<BA>DDDDEDC<AL2G.P4L4B");
|
||||||
|
Qb_PLAY (pin,"BL2BL4BBL2BL4B>D<G.L8AL1BL4>CCC.L8CL4C<BBL8BBL4BAABL2A");
|
||||||
|
Qb_PLAY (pin,">DL4<BBL2BL4BBL2BL4B>D<G.L8AL1BL4>CCC.L8CL4C<BBL8BBL4>D");
|
||||||
|
Qb_PLAY (pin,"DC<AL1G");
|
||||||
|
}
|
||||||
|
|
4
Music Box/musics.h
Normal file
4
Music Box/musics.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#include "QBmusics.h"
|
||||||
|
//bells
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user