{"id":21561041,"url":"https://github.com/end2endzone/anyrtttl","last_synced_at":"2026-01-24T01:03:46.222Z","repository":{"id":135365264,"uuid":"151838849","full_name":"end2endzone/AnyRtttl","owner":"end2endzone","description":"A feature rich arduino library for playing rtttl melodies","archived":false,"fork":false,"pushed_at":"2025-04-29T00:47:24.000Z","size":438,"stargazers_count":6,"open_issues_count":3,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-29T01:44:26.571Z","etag":null,"topics":["arduino","esp32","esp8266","piezo","rttl","rtttl","tone"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/end2endzone.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-10-06T12:42:28.000Z","updated_at":"2025-04-29T00:47:25.000Z","dependencies_parsed_at":null,"dependency_job_id":"5d53fd7e-a4d5-4c53-9eec-04f736d2e523","html_url":"https://github.com/end2endzone/AnyRtttl","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/end2endzone/AnyRtttl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/end2endzone%2FAnyRtttl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/end2endzone%2FAnyRtttl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/end2endzone%2FAnyRtttl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/end2endzone%2FAnyRtttl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/end2endzone","download_url":"https://codeload.github.com/end2endzone/AnyRtttl/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/end2endzone%2FAnyRtttl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272852293,"owners_count":25004054,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-30T02:00:09.474Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino","esp32","esp8266","piezo","rttl","rtttl","tone"],"created_at":"2024-11-24T09:18:33.857Z","updated_at":"2026-01-24T01:03:46.214Z","avatar_url":"https://github.com/end2endzone.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"![AnyRtttl logo](https://github.com/end2endzone/AnyRtttl/raw/master/docs/AnyRtttl-splashscreen.png)\n\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Github Releases](https://img.shields.io/github/release/end2endzone/AnyRtttl.svg)](https://github.com/end2endzone/AnyRtttl/releases)\n[![Visitors](https://visitor-badge.laobi.icu/badge?page_id=end2endzone.AnyRtttl)](https://github.com/end2endzone/AnyRtttl)\n\n[![Button Install](https://img.shields.io/badge/Install-brightgreen?logoColor=white\u0026logo=GitBook)](https://www.ardu-badge.com/AnyRtttl)\n[![Button Changelog](https://img.shields.io/badge/Changelog-blue?logoColor=white\u0026logo=googleforms)](CHANGES)\n\n\n\n# AnyRtttl #\n\nAnyRtttl is a feature rich arduino library for playing [RTTTL](http://www.end2endzone.com/anyrtttl-a-feature-rich-arduino-library-for-playing-rtttl-melodies/#Quick_recall_of_the_RTTTL_format) melodies. The library offers much more interesting features than relying on the widely available `void play_rtttl(char *p)` function. The library supports all best RTTTL features.\n\n## Features ##\n\n* Really small increase in memory \u0026 code footprint compared to the usual blocking algorithm.\n* [Blocking](#blocking-mode) \u0026 [Non-Blocking](#non-blocking-mode) modes available.\n* Support custom `tone()`, `noTone()` and `millis()` functions.\n* Compatible with external Tone libraries.\n* Supports RTTTL melodies stored in RAM or Program Memory (`PROGMEM`).\n* Compatible with any custom or arbitrary RTTTL format that can be decoded as legacy RTTTL.\n* Support a STRICT or RELAXED parsing mode. See [Strict parsing mode](#strict-parsing-mode) and [Relaxed parsing mode](#relaxed-parsing-mode).\n* Support for playing 2 melodies simultaneously (using 2 speakers on two different pins). See [ESP32DualPlayRtttl](examples/ESP32DualPlayRtttl/ESP32DualPlayRtttl.ino) example.\n* Supports highly compressed RTTTL binary format. See [Play16Bits](examples\\Play16Bits\\Play16Bits.ino) or [Play10Bits](examples\\Play10Bits\\Play10Bits.ino) examples.\n* Supports names longer than the 10 character limit.\n* Supports dotted notes in format `[\u003cduration\u003e]\u003cnote\u003e[\u003coctave\u003e][.]` (Nokia's specification) or the alternate format `[\u003cduration\u003e]\u003cnote\u003e[.][\u003coctave\u003e]` (Nokia's Simpsons example).\n\n\n## Status ##\n\nBuild:\n\n| Service | Build | Tests |\n|----|-------|-------|\n| Windows Server 2019 | [![Build on Windows](https://github.com/end2endzone/AnyRtttl/actions/workflows/build_windows.yml/badge.svg)](https://github.com/end2endzone/AnyRtttl/actions/workflows/build_windows.yml) | [![Tests on Windows](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/end2endzone/58cf6c72c08e706335337d5ef9ca48e8/raw/AnyRtttl.master.Windows.json)](https://github.com/end2endzone/AnyRtttl/actions/workflows/build_windows.yml) |\n| Ubuntu 22.04        | [![Build on Linux](https://github.com/end2endzone/AnyRtttl/actions/workflows/build_linux.yml/badge.svg)](https://github.com/end2endzone/AnyRtttl/actions/workflows/build_linux.yml)       | [![Tests on Linux](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/end2endzone/58cf6c72c08e706335337d5ef9ca48e8/raw/AnyRtttl.master.Linux.json)](https://github.com/end2endzone/AnyRtttl/actions/workflows/build_linux.yml)       |\n\n\n\n\n# Purpose #\n\nAfter publishing [NonBlockingRtttl](https://github.com/end2endzone/NonBlockingRTTTL) arduino library, I started using the library in more complex projects which was requiring other libraries. I quickly ran into the hell of library dependencies and library conflicts. I realized that I needed more features that could help me prototype faster.\n\nOther libraries available which allows you to \"play\" a melody in [RTTTL](http://www.end2endzone.com/anyrtttl-a-feature-rich-arduino-library-for-playing-rtttl-melodies/#Quick_recall_of_the_RTTTL_format) format suffer the same issue: they are based on blocking APIs or the RTTTL data is not optimized for space.\n\nAnyRtttl is different since it packs multiple RTTTL related features in a single library. It supports [blocking](https://en.wikipedia.org/wiki/Blocking_(computing)) \u0026 [non-blocking](http://en.wikipedia.org/wiki/Non-blocking_algorithm) API which makes it suitable to be used by more advanced algorithm. For instance, when using the non-blocking API, the melody can be stopped when a button is pressed. The library is also compatible with external Tone libraries and it supports highly compressed RTTTL binary formats.\n\n**Existing Non-Blocking code**\n\nMost of the code that can play a melody on internet are build the same way: sequential calls to `tone()` and `delay()` functions using hardcoded values. This type of implementation might be good for robots but not for realtime application or projects that needs to monitor pins while the song is playing.\n\nWith AnyRtttl non-blocking mode, your program can read/write IOs pins while playing and react on changes. Implementing a \"stop\" or \"next song\" push button is easy!\n\n\n\n# Usage #\n\nThe following instructions show how to use the library.\n\n\n\n## Blocking mode ##\n\nTo play a RTTTL melody using the blocking mode API, you call `anyrtttl::blocking::play(BUZZER_PIN, melody);` with your buzzer pin and the RTTTL melody string. This function will play the entire melody sequentially, pausing execution until the melody finishes.\n\nThe blocking api will:\n* Play the RTTTL string note by note.\n* Halt execution until the melody finishes, returning the control of the execution to the your sketch.\n* Uses Arduino's `tone()` and `millis()` internally to implement delay between notes.\n\nThe blocking api can be used in your sketch `setup()` or `loop()` sections. \n\nThis is ideal for simple sketches where you do not need multitasking. For example:\n* Startup sounds\n* Simple demos\n* One-shot audio feedback\n\n\n\n## Non-blocking mode ##\n\nThe non-blocking API will let the melody play in the background while your `loop()` keeps running. It will not freeze your sketch allowing you sketch to process other tasks simultaneously. \n\nWith the non-blocking api, you need to\n* Call `begin()` to initialize the library with a new melody.\n* Call `play()` in the `loop()` at a high and consistent rate to allow playback to advance notes at their scheduled times.\n* Make sure all other tasks in `loop()` execute quickly so they do not delay playback timing. Any long-running operations in `loop()` will introduce timing jitter and can delay note transitions.\n\nThe non-blocking api can not be used in your sketch `setup()`. It must be used in the `loop()` section.\n\nThis is ideal for sketches that are multitasks. For example, sketches that:\n* Read sensors continuously\n* Handle buttons and debouncing\n* Update displays\n* Maintain communication (Serial, I2C, SPI)\n* Run state machines\n\nIn summary:\n\nCall `anyrtttl::nonblocking::begin()` to setup AnyRtttl library in non-blocking mode.\n\nThen call `anyrtttl::nonblocking::play()` to update the library's state and play notes as required.\n\nUse `anyrtttl::done()` or `anyrtttl::nonblocking::isPlaying()` to know if the library is done playing the given song.\n\nAnytime, one can call `anyrtttl::nonblocking::stop()` to stop playing the current song.\n\nThe following code shows how to use the library in non-blocking mode:\n\n```cpp\n#include \u003canyrtttl.h\u003e\n#include \u003cbinrtttl.h\u003e\n#include \u003cpitches.h\u003e\n\n//project's constants\n#define BUZZER_PIN 8\nconst char * tetris = \"tetris:d=4,o=5,b=160:e6,8b,8c6,8d6,16e6,16d6,8c6,8b,a,8a,8c6,e6,8d6,8c6,b,8b,8c6,d6,e6,c6,a,2a,8p,d6,8f6,a6,8g6,8f6,e6,8e6,8c6,e6,8d6,8c6,b,8b,8c6,d6,e6,c6,a,a\";\nconst char * arkanoid = \"Arkanoid:d=4,o=5,b=140:8g6,16p,16g.6,2a#6,32p,8a6,8g6,8f6,8a6,2g6\";\nconst char * mario = \"mario:d=4,o=5,b=100:16e6,16e6,32p,8e6,16c6,8e6,8g6,8p,8g,8p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,16p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16c7,16p,16c7,16c7,p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16d#6,8p,16d6,8p,16c6\";\nbyte songIndex = 0; //which song to play when the previous one finishes\n\nvoid setup() {\n  pinMode(BUZZER_PIN, OUTPUT);\n\n  Serial.begin(115200);\n  Serial.println();\n}\n\nvoid loop() {\n  // If we are not playing something \n  if ( !anyrtttl::nonblocking::isPlaying() )\n  {\n    // Play a song based on songIndex.\n    if (songIndex == 0)\n      anyrtttl::nonblocking::begin(BUZZER_PIN, tetris);\n    else if (songIndex == 1)\n      anyrtttl::nonblocking::begin(BUZZER_PIN, arkanoid);\n    else if (songIndex == 2)\n      anyrtttl::nonblocking::begin(BUZZER_PIN, mario);\n\n    //Set songIndex ready for next song\n    songIndex++;\n  }\n  else\n  {\n    anyrtttl::nonblocking::play();\n  }\n}\n```\n\n\n## Macros ##\n\nUse `ANY_RTTTL_VERSION` to get the current version of the library.\n\nDefine `ANY_RTTTL_INFO` to enable library state debugging via the serial port.\nDefine `ANY_RTTTL_DEBUG` to enable more detailed, advanced debugging of the library. See [GlobalMacros.md](GlobalMacros.md) which provides instructions for creating global macros.\n\nDefine the global macro `ANY_RTTTL_DONT_USE_TONE_LIB` to disable linking with Arduino's built‑in `tone()` and `noTone()` functions. When defined, AnyRtttl will not use these functions and your sketch will not link or depend on the tone library.\n\nDefine the global macro `ANY_RTTTL_NO_DEFAULT_FUNCTIONS` to disable all default function assignments. In this mode, AnyRtttl will not provide default implementations for its internal function pointers.\n\nIf you use either `ANY_RTTTL_DONT_USE_TONE_LIB` or `ANY_RTTTL_NO_DEFAULT_FUNCTIONS`, you must manually configure AnyRtttl at runtime by calling `anyrtttl::setToneFunction()`, `anyrtttl::setNoToneFunction()` or `anyrtttl::setMillisFunction()` before attempting to play a melody.\n\n\u003e **Note:**  \nAnyRtttl is distributed with its own separate C++ source files (\\*.cpp). A macro that is only defined at the start of your sketch does not propagate into the library's source files. As a result, AnyRtttl mostly remain unaffected by the sketch‑level macro definition.\n\u0026nbsp;  \n\u0026nbsp;  \nSee [GlobalMacros.md](GlobalMacros.md) which provides instructions for creating global macros.\n\n### Parsing modes ###\n\nThis library supports two parsing modes: _Strict_ and _Relaxed_. It provides different levels of input quality and validation requirements. The selected mode determines how rigorously the parser validates input and how it reacts to malformed or ambiguous data.\n\n\n\n#### Strict parsing mode ####\n\nStrict mode do not validates the RTTTL melody content. It expect the melody to match the [original Nokia's specification](#format-specification).\n\nUse macro `RTTTL_PARSER_STRICT` to configure the library in strict parsing mode.\n\n* Strict has lowest memory and program footprint.\n* May fail with invalid syntax or unsupported constructs.\n* Has no error handling.\n* Parsing errors may result in potential crashes.\n* Supports names longer than the 10 character limit.\n\n\n\n#### Relaxed parsing mode ####\n\nRelaxed mode prioritizes robustness and usability. The parser attempts to interpret and recover from minor issues instead of failing.\n\nUse macro `RTTTL_PARSER_RELAXED` to configure the library in relaxed parsing mode. This mode is also the default mode when `RTTTL_PARSER_STRICT` and `RTTTL_PARSER_RELAXED` are not specified.\n\n* Relaxed is more resilient to invalid characters or parsing errors.\n* Supports RTTTL note duration of 64 or 128.\n* Supports any BPM values between 10 and 2000.\n* Supports RTTTL melodies with uppercase characters.\n* Supports RTTTL melodies with spaces.\n* Supports each control in the control section (d, o and b) to be specified in any order.\n\n\n\n## Playing RTTTL data stored in flash (program) memory ##\n\nAnyRtttl also supports RTTTL melodies stored in flash or Program Memory (PROGMEM).\n\nThe `anyrtttl::nonblocking::begin()` function supports _Program Memory_ macros such as `FPSTR()` or `F()`.\n\nThe following code shows how to use the library with RTTTL data stored in flash (program) memory instead of SRAM:\n\n```cpp\n#include \u003canyrtttl.h\u003e\n#include \u003cbinrtttl.h\u003e\n#include \u003cpitches.h\u003e\n\n//project's constants\n#define BUZZER_PIN 8\nconst char tetris[] PROGMEM = \"tetris:d=4,o=5,b=160:e6,8b,8c6,8d6,16e6,16d6,8c6,8b,a,8a,8c6,e6,8d6,8c6,b,8b,8c6,d6,e6,c6,a,2a,8p,d6,8f6,a6,8g6,8f6,e6,8e6,8c6,e6,8d6,8c6,b,8b,8c6,d6,e6,c6,a,a\";\nconst char arkanoid[] PROGMEM = \"Arkanoid:d=4,o=5,b=140:8g6,16p,16g.6,2a#6,32p,8a6,8g6,8f6,8a6,2g6\";\nconst char mario[] PROGMEM = \"mario:d=4,o=5,b=100:16e6,16e6,32p,8e6,16c6,8e6,8g6,8p,8g,8p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,16p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16c7,16p,16c7,16c7,p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16d#6,8p,16d6,8p,16c6\";\n// James Bond theme defined in inline code below (also stored in flash memory) \nbyte songIndex = 0; //which song to play when the previous one finishes\n\nvoid setup() {\n  pinMode(BUZZER_PIN, OUTPUT);\n\n  Serial.begin(115200);\n  Serial.println();\n}\n\nvoid loop() {\n  // If we are not playing something \n  if ( !anyrtttl::nonblocking::isPlaying() )\n  {\n    // Play a song based on songIndex.\n    if (songIndex == 0)\n      anyrtttl::nonblocking::beginProgMem(BUZZER_PIN, tetris);\n    else if (songIndex == 1)\n      anyrtttl::nonblocking::begin_P(BUZZER_PIN, arkanoid);\n    else if (songIndex == 2)\n      anyrtttl::nonblocking::begin(BUZZER_PIN, FPSTR(mario));\n    else if (songIndex == 3)\n      anyrtttl::nonblocking::begin(BUZZER_PIN, F(\"Bond:d=4,o=5,b=80:32p,16c#6,32d#6,32d#6,16d#6,8d#6,16c#6,16c#6,16c#6,16c#6,32e6,32e6,16e6,8e6,16d#6,16d#6,16d#6,16c#6,32d#6,32d#6,16d#6,8d#6,16c#6,16c#6,16c#6,16c#6,32e6,32e6,16e6,8e6,16d#6,16d6,16c#6,16c#7,c.7,16g#6,16f#6,g#.6\"));\n\n    //Set songIndex ready for next song\n    songIndex++;\n  }\n  else\n  {\n    anyrtttl::nonblocking::play();\n  }\n}\n```\n\n\n\n# Advanced Usage #\n\n\n\n## External Tone or Timer #0 libraries ##\n\n\n### Custom millis() function (timer0) ###\n\nThe library also supports custom `millis()` function. If a project requires modification to the microcontroller's build-in Timer #0, the `millis()` function may be impacted and behave incorrectly. To maximize compatibility, one can supply a custom function which behaves like the original to prevent altering playback.\n\n\n### Custom tone() and noTone() functions (timer2) ###\n\nThe AnyRtttl library is also flexible by allowing you to use the build-in arduino `tone()` and `noTone()` functions or an implementation from any external library which makes it compatible with any Tone library in the market.\n\n\u003e **Note:**  \nWhen using your own functions for implementing `tone()` and `noTone()`, it is recommended to also define macro `ANY_RTTTL_DONT_USE_TONE_LIB`.\n\u0026nbsp;  \n\u0026nbsp;  \nBy default, AnyRtttl uses Arduino's built‑in `tone()` and `noTone()` functions. This automatically link your sketch with the tone library, which may lead to compilation or linking errors in situations where Timer2 is already used. To avoid this, you can define the global macro `ANY_RTTTL_DONT_USE_TONE_LIB`.\n\u0026nbsp;  \n\u0026nbsp;  \nSee [configuration](#Configuration) section for more details.\n\n### Example on Arduino Nano ##\n\nOn the Arduino Nano, the [tone() function relies on Timer2](https://forum.arduino.cc/t/timers-used-by-nano/1103697/5). If Timer2 is already in use for another task, the built-in `tone()` and `noTone()` functions will conflict with it. In that case, you will need to create your own custom versions and configure AnyRtttl to use them.\n\nFor example :\n```cpp\n#include \u003cavr/interrupt.h\u003e\n// ...\nISR(TIMER2_COMPA_vect) { }\n\n// Define tone() and noTone() versions that relies on Timer1.\nvoid timer1_tone(uint8_t pin, unsigned int frequency, unsigned long duration) {\n  // ...\n}\nvoid timer1_no_tone(uint8_t pin) {\n  // ...\n}\n\nvoid setup()\n{\n\tanyrtttl::setToneFunction(\u0026timer1_tone);\n\tanyrtttl::setNoToneFunction(\u0026timer1_no_tone);\n}\n```\n\n\n\n## Binary RTTTL / Compatibility with custom RTTTL formats ##\n\nAnyRtttl can be configured for playing your custom format. AnyRtttl can use a custom function for decoding such a custom format. This allows the library to be compatible with any custom RTTTL formats that can be decoded as legacy RTTTL.\n\nFor example, AnyRtttl library can be adapted to play RTTTL data which is stored as binary data instead of text. This is actually a custom implementation of the RTTTL format. Using this format, one can achieve storing an highly compressed RTTTL melody which saves memory.\n\nThe [Play10Bits](examples/Play10Bits/Play10Bits.ino) and [Play16Bits](examples/Play10Bits/Play10Bits.ino) are examples for showing AnyRtttl's capability to adapt to custom formats.\n\nSee [BinaryRTTTL.md](BinaryRTTTL.md) for a definition of this custom RTTTL format.\n\n\n\n## Custom Tone function (a.k.a. RTTTL 2 code) ##\n\nThis example shows how custom functions can be used by the AnyRtttl library to convert an RTTTL melody to arduino code.\n\nFirst define replacement functions like the following:\n\n```cpp\nvoid serialTone(byte pin, uint16_t frequency, uint32_t duration) {\n  Serial.print(\"tone(\");\n  Serial.print(pin);\n  Serial.print(\",\");\n  Serial.print(frequency);\n  Serial.print(\",\");\n  Serial.print(duration);\n  Serial.println(\");\");\n}\n\nvoid serialNoTone(byte pin) {\n  Serial.print(\"noTone(\");\n  Serial.print(pin);\n  Serial.println(\");\");\n}\n\n```\n\nEach new functions prints the function call \u0026 arguments to the serial port.\n\nIn the `setup()` function, setup the AnyRtttl library to use the new functions:\n\n```cpp\n//Use custom functions\nanyrtttl::setToneFunction(\u0026serialTone);\nanyrtttl::setNoToneFunction(\u0026serialNoTone);\n```\n\nUse the `anyrtttl::blocking::play()` API for \"playing\" an RTTTL melody and monitor the output of the serial port to see the actual arduino code generated by the library.\n\nThe following code shows how to use the library with custom functions:\n\n```cpp\n#include \u003canyrtttl.h\u003e\n#include \u003cbinrtttl.h\u003e\n#include \u003cpitches.h\u003e\n\n//project's constants\n#define BUZZER_PIN 8\nconst char * tetris = \"tetris:d=4,o=5,b=160:e6,8b,8c6,8d6,16e6,16d6,8c6,8b,a,8a,8c6,e6,8d6,8c6,b,8b,8c6,d6,e6,c6,a,2a,8p,d6,8f6,a6,8g6,8f6,e6,8e6,8c6,e6,8d6,8c6,b,8b,8c6,d6,e6,c6,a,a\";\n\n//*******************************************************************************************************************\n//  The following replacement functions prints the function call \u0026 parameters to the serial port.\n//*******************************************************************************************************************\nvoid serialTone(byte pin, uint16_t frequency, uint32_t duration) {\n  Serial.print(\"tone(\");\n  Serial.print(pin);\n  Serial.print(\",\");\n  Serial.print(frequency);\n  Serial.print(\",\");\n  Serial.print(duration);\n  Serial.println(\");\");\n}\n\nvoid serialNoTone(byte pin) {\n  Serial.print(\"noTone(\");\n  Serial.print(pin);\n  Serial.println(\");\");\n}\n\n\nvoid setup() {\n  pinMode(BUZZER_PIN, OUTPUT);\n\n  Serial.begin(115200);\n  Serial.println();\n\n  //Use custom functions\n  anyrtttl::setToneFunction(\u0026serialTone);\n  anyrtttl::setNoToneFunction(\u0026serialNoTone);\n}\n\nvoid loop() {\n  anyrtttl::blocking::play(BUZZER_PIN, tetris);\n\n  while(true)\n  {\n  }\n}\n```\n\n\n\n\n# Examples #\n\nMore AnyRtttl examples are also available:\n\n* [Basic](examples/Basic/Basic.ino)\n* [BlockingProgramMemoryRtttl](examples/BlockingProgramMemoryRtttl/BlockingProgramMemoryRtttl.ino)\n* [BlockingRtttl](examples/BlockingRtttl/BlockingRtttl.ino)\n* [BlockingWithNonBlocking](examples/BlockingWithNonBlocking/BlockingWithNonBlocking.ino)\n* [ESP32DualPlayRtttl](examples/ESP32DualPlayRtttl/ESP32DualPlayRtttl.ino)\n* [ESP32Rtttl](examples/ESP32Rtttl/ESP32Rtttl.ino)\n* [ESP8266-NodeMCU](examples/ESP8266-NodeMCU/ESP8266-NodeMCU.ino)\n* [IoT-beeps](examples/IoT-beeps/IoT-beeps.ino)\n* [NonBlockingProgramMemoryRtttl](examples/NonBlockingProgramMemoryRtttl/NonBlockingProgramMemoryRtttl.ino)\n* [NonBlockingRtttl](examples/NonBlockingRtttl/NonBlockingRtttl.ino)\n* [NonBlockingStopBeforeEnd](examples/NonBlockingStopBeforeEnd/NonBlockingStopBeforeEnd.ino)\n* [Play10Bits](examples/Play10Bits/Play10Bits.ino)\n* [Play16Bits](examples/Play16Bits/Play16Bits.ino)\n* [PlaySerialRtttl](examples/PlaySerialRtttl/PlaySerialRtttl.ino)\n* [Rtttl2Code](examples/Rtttl2Code/Rtttl2Code.ino)\n\n\n\n\n# RTTTL Format #\n\n## Nokia's original specification ##\n\nThis library implements the [original Nokia Phone specification](http://merwin.bespin.org/t4a/specs/nokia_rtttl.txt) ([backup copy here](docs/nokia_rtttl.txt)).\n\nThis format is specified as the following:  \n`\u003cname\u003e:\u003ccontrol-section\u003e:\u003ctone-commands\u003e,\u003ctone-commands\u003e...`\n\n\n### Control Section: ###\n\nThe control section is optional.\nIt defines the following parameters for the melody:\n\n* `d=\u003cvalue\u003e` : Default duration of a note if unspecified.\n* `o=\u003cvalue\u003e` : Default octave of a note if unspecified.\n* `b=\u003cvalue\u003e` : Beats per minutes of a quarter note\n\n\n### Tone commands: ###\n\nTones can be represented in the following format:\n\n`[\u003cduration\u003e] \u003cnote\u003e [\u003cscale\u003e] [.] \u003cdelimiter\u003e` where :\n\n* `duration` is the duration divider of full note duration, eg. 4 represents a quarter note.\n* `note` is the note name (one of `p`,`c`,`c#`,`d`,`d#`,`e`,`f`,`f#`,`g`,`g#`,`a`,`a#`,`b`). The note `p` is a special note that represents a pause, a silent note in the melody.\n* `scale` is the scale of the melody: from 4 to 7.\n* `.` is a dotted note which increases the duration.\n\nThe duration, octave and dot are optional.\n\n\n## Nokia's ambiguity with dotted notes (Simpsons example) ##\n\nThe original Nokia RTTTL specification defines the note format as `[\u003cduration\u003e] \u003cnote\u003e [\u003cscale\u003e] [\u003cspecial-duration\u003e] \u003cdelimiter\u003e`, which implies that the dot should appear after the optional `\u003cscale\u003e` character.\n\nHowever, the _Simpsons_ ringtone (see below) included in the specification  place the dot before the scale character (e.g., `c.6` and `g.6` instead of `c6.` and `g6.`). This inconsistency suggests that both placements were accepted by early Nokia implementations, and parsers should be tolerant of either ordering when interpreting RTTTL strings.\n\nExample: `Simpsons:d=4,o=5,b=160:32p,c.6,e6,f#6,8a6,g.6,e6,c6,8a,8f#,8f#,8f#,2g`.\n\n\n## Other specifications: ##\n\n* An old but accurate specification:  \n  https://www.mobilefish.com/tutorials/rtttl/rtttl_quickguide_specification.html\n* The original Nokia Phones specification:  \n  http://merwin.bespin.org/t4a/specs/nokia_rtttl.txt\n* The specification on Wikipedia:  \n  https://en.wikipedia.org/wiki/Ring_Tone_Text_Transfer_Language#Technical_specification\n* A more modern RTTTL specification document:  \n  https://rtttl.skully.tech/rtttl_specification\n\n\n## RTTTL ressources ##\n\nOnline RTTTL players:\n\n* A web based RTTTL melody composer:  \n  https://rtttl.skully.tech/\n* Online RTTTL player:  \n  https://adamonsoon.github.io/rtttl-play/\n* Nokia Composer:  \n  https://eddmann.com/nokia-composer-web/\n\nOther:\n\n* RTTTL documentation on ESPHome:  \n  https://esphome.io/components/rtttl/\n* Converting Arduino melodies:  \n  https://end2endzone.com/how-to-convert-arduino-code-to-actual-rtttl-melodies-using-librtttl-and-anyrtttl/#game-of-throne\n\nMelody databases:\n\n* https://picaxe.com/RTTTL-Ringtones-for-Tune-Command/\n* https://www.voip-info.org/rtttl-melodies/\n* Multiple melodies for IoT projects: [example IoT-beeps](examples\\IoT-beeps\\IoT-beeps.ino).\n* https://github.com/end2endzone/smart-doorbell-homeassistant/blob/main/src/doorbell/rtttl_melodies.txt\n* https://github.com/end2endzone/smart-doorbell-homeassistant/blob/main/src/doorbell/rtttl_ringtones.txt\n\n\n\n\n# Building #\n\nPlease refer to file [INSTALL.md](INSTALL.md) for details on how installing/building the application.\n\n\n\n\n# Platforms #\n\nAnyRtttl has been tested with the following platform:\n\n  * Arduino Uno\n  * ESP8266 (NodeMCU)\n  * ESP32 (DevKit, ESP-WROOM-32)\n\n\n\n\n# Versioning #\n\nWe use [Semantic Versioning 2.0.0](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/end2endzone/AnyRtttl/tags).\n\n\n\n\n# Authors #\n\n* **Antoine Beauchamp** - *Initial work* - [end2endzone](https://github.com/end2endzone)\n\nSee also the list of [contributors](https://github.com/end2endzone/AnyRtttl/blob/master/AUTHORS) who participated in this project.\n\n\n\n\n# License #\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fend2endzone%2Fanyrtttl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fend2endzone%2Fanyrtttl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fend2endzone%2Fanyrtttl/lists"}