Code Monkey home page Code Monkey logo

mmlmusicpwm's Introduction

MmlMusicPWM

Arduino library to play MML music using a piezo speaker on an output pin. Implemented using the MmlMusic base library.

Introduction

MmlMusicPWM provides a means to play Music Macro Language sequences asynchronously. Where the Arduino tone() function allows for playing one single note, the MmlMusicPWM::play() method can play an entire music score.
It produces sound by means of a PWM signal on an output pin, which can be connected to a piezo speaker, or via an amplifier to a regular speaker. The music is played using a timer interrupt routine that changes the PWM frequency according the specific notes being played. This means we can do other things while the music keeps playing!

Device independant base class

This library is an extension to the MmlMusic base library. It is implemented as a child class of the device independant MmlMusic class. That class requires additional code via either a callback function or the implementation of a child class to implement the actual production of sound.

Support for different MCUs

This library supports playing MML music on different MCUs such as ESP8266, ATmega 328, 168 and ATtiny85. Depending on the MCU, it uses different timers and interrupts to produce the sound and to schedule playback of notes and silences. The music will keep on playing using a timer interrupt. On the ESP8266 the Ticker library is used. For ATmega 328/168 a Timer2 interrupt is used and a replacement method for tone() is provided. On the ATtiny85 resources are limited. There a Timer1 interrupt is used, which impacts regular PWM output.
BTW: The MmlMusic Tone example shows how to play notes without using a timer interrupt.

Installation/Usage

The library can be downloaded and installed as an Arduino library using the Sketch|Library menu. Just add the zipfile library and the enclosed examples should appear in the menu automatically.

Initialisation outside of Setup():

  // include header and initialize class
  #include <MmlMusicPWM.h>
  MmlMusicPWM music();

Then to play music, call the play method where you want:

music.play("T240 L16 O6 C D E F G");

When playing the rest of the sequence, the isPlaying() method can be used to determine if the sequence is still playing.

if(music.isPlaying()
{
    ...
}

Alterternatively a callback function can be used to signal the start or end of playing the tune. See the included examples for more detailed instructions on how to use this library.

Supported MML Syntax

Short syntax overview:

Command Description
  Tnnn Set tempo [32-255]. Examples: T120, T240
  Vnnn Set volume [0-128]. Note: limited effect on PWM-volume. Examples: V1, T120
  Lnn Set default note length [1-64]. Examples: L8, L16
  Mx   Set timing. Mn=default, Ml=legato, Ms=staccato
  On   Set octave [0-7]. Examples: O6, O7
  A-G  Play whole note. Example: C
  Ann-Gnn  Play note of alternative length [1-64]. Example: C4, A16
  Nnn Play frequency [0-96]. Example: N48
   #   Play sharp note. Example: C#
  +   Alternative for #
  −   Play flat note. Example: D-
   R    Rest. Example:  CDEC r CDEC
  P   Alternative for R. Example: CDEC p CDEC
  .   Longer note. Example: CDEC. 
  > shift octave up. Example: CDE>CDE. 
   < shift octave down.  Example: CDE<CDE. 
   , play multiple tracks  Example: CDE<CDE.,EDC<ECD. 

The supported MML-commands are a subset that may not completely cover all available music scores. If notes seem missing, check your score against the syntax above and replace unknown commands by equivalent supported alternatives. The music notation is case-insensitive. Spaces are not required but can be used for readability.

Features & limitations

  • Playing back multiple tracks is supported by the base library, but not (yet) by this library. Only a single pulse-stream is generated. The documentation of the comma-command above is maintained for future purposes.
  • This library was tested in the Arduino IDE v1.6.10 and v1.8.2. The current version of this library supports ESP8266, Atmel ATmega328 and ATmega168 MCUs. Support for ATtiny85 was also added, but since the ATtiny85 has limited resources, available memory limits it usage to simple applications. On ATtiny85 Timer1 is used, impacting the use of the regular PWM analogWrite() function.
  • There was a bug in the MmlMusic base library that could impact playback of notes and the duration of the delay() function. When ending the play-string with a number (eg. "T120 O4 G16"), the player could read beyond the end of the string, play whatever was next in memory and mess up the timer callback. This bug has been fixed. Please use the latest version of the MmlMusic base library. See this issue for details.
  • In ESP8266 cores 2.5.1 and higher reading a float array from PROGMEM had a byte alignment issue causing incorrect playback of notes. This issue was fixed in ESP8266 core 2.6.0 and has a workaround in the MmlMusic base library for earlier cores. See this issue for details.

Credits

The base library is based on the MusicEngine library by Chris Taylor, ported from mBed to Arduino. It is a follow-up of the ESP-MusicEngine library.

Links

Disclaimer

  • All code on this GitHub account, including this library is provided to you on an as-is basis without guarantees and with all liability dismissed. It may be used at your own risk. Unfortunately I have no means to provide support.

mmlmusicpwm's People

Contributors

maxint-rd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

mmlmusicpwm's Issues

Crackling sound in ESP8266 cores 2.5.1 and higher

Hi @maxint-rd
Thanks for useful library.

After some years of stable work I updated Arduino IDE and their libraries (and https://github.com/esp8266/Arduino too). Nothing changed in my code but now music not play as expected. It's just creak from speaker.

I see this commit and paste this code into my sketch but nothing changed.

My code example placed here: https://github.com/UksusoFF/wemos-doorbell/blob/master/wemos-doorbell.ino

Can you help me found solution?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.