This library provides support for parsing and playing tunes in RTTTL format.

RTTTL conversion code based on https://github.com/end2endzone/NonBlockingRTTTL.

The parser is stream-based and allows random seeking where the stream supports it.

An RTTTL writer is also included to assist with editing/creation of RTTTL files.

API Documentation

namespace RingTone


enum class Note

Note numbers, defined here for convenience.


enumerator MUTE
enumerator C
enumerator C_Sharp
enumerator D_Flat
enumerator D
enumerator D_Sharp
enumerator E_Flat
enumerator E
enumerator F
enumerator F_Sharp
enumerator G
enumerator G_Sharp
enumerator A_Flat
enumerator A
enumerator A_Sharp
enumerator B_Flat
enumerator B


template<unsigned octave, unsigned note>
static constexpr unsigned calculateFrequency()
unsigned charToNoteValue(char c)

Get the corresponding note number for a letter.


To sharpen a note, add 1



Return values:

unsigned – Notes start at 1, 0 indicates error or pause/mute

unsigned getNoteFrequency(unsigned octave, unsigned note)

Convert a scale/note combination into frequency.

  • octave

  • note

Return values:

unsigned – Frequency, 0 if out of range

unsigned getClosestNote(unsigned frequency, unsigned &octave)

Convert a frequency into a scale/note combination into frequency.

  • frequency

  • octave – Octave for the note

Return values:

unsigned – The note number, 0 if out of range

const char *getNoteName(unsigned noteValue)

Get text for a given note number.


static unsigned noteFrequencyA4 = 440

Reference note frequency.

static constexpr float frequencyRoot = pow(2, 1.0 / 12)
struct NoteDef
#include <RingTone.h>
class Parser
#include <RingTone.h>

Base parser class.

Subclassed by RingTone::RtttlParser

Public Functions

virtual bool readNextNote(NoteDef &note) = 0

Fetch the next note for this tune.

Return values:

bool – true on success, false if no more notes available

class Player
#include <RingTonePlayer.h>

Base class to support playback of tunes.


This class doesn’t produce any sound. To do this provide set the onPrepareNote and onPlayNote callbacks, or override the prepareNote and playNote methods in an inherited class.

Public Functions

void begin(RingTone::Parser *parser)

Initialise player.


We don’t own the parser, just take a reference


parser – The source of ringtone data

void end()

Stop the player and un-reference parser.

bool start(unsigned delayMs = 0)

Start or continue playing the tune.

void stop()

Stop/pause playing the tune.

inline void resetPlayTime()

Stop playback and reset play time.

inline bool isStarted()

Determine if a tune is being played.

inline unsigned getSpeed() const

Get playback speed factor.

Return values:

unsigned – 100 = normal speed, 50 = half speed, 200 = double speed, etc.

inline unsigned setSpeed(unsigned speed)

Set playback speed factor.

Return values:

unsigned – New speed factor

inline unsigned adjustSpeed(int adjust)

Make a relative adjustment to playback speed.

Return values:

unsigned – New speed factor

struct RtttlHeader
#include <RtttlParser.h>
struct RtttlParserState
#include <RtttlParser.h>

Subclassed by RingTone::RtttlParser

class RtttlParser : public RingTone::Parser, private RingTone::RtttlParserState
#include <RtttlParser.h>

Class to parse RTTTL files RTTTL (RingTone Text Transfer Language) format.

Public Functions

bool begin(IDataSourceStream *source)

Initialise the parser with the given stream.

void end()

Release the source stream.

bool nextTune()

Locate next tune and read header.

bool seekTune(unsigned index)

Find a tune by index, starting at #0.

inline unsigned getIndex()

Get the current tune index.

unsigned getCount()

Get the number of tunes in this file.

inline const String &getTitle()

Get the current tune title.

inline String getCaption()

Get a display caption for the current tune.

inline bool rewind()

Rewind to start of tune.

virtual bool readNextNote(RingTone::NoteDef &note)

Fetch the next note for this tune.



Return values:

bool – true on success, false if no more notes available

class RtttlWriter
#include <RtttlWriter.h>
class RtttlJsonListStream : public IDataSourceStream

A forward-only stream for listing contents of a tune file.


Tune files can be large so we only output one tune title at a time

Public Functions

inline RtttlJsonListStream(const String &name, RingTone::RtttlParser *parser)

Construct a list stream.

  • name – Identifies this stream, will have .json appended

  • parser – Pre-initialised parser to obtain tunes from

inline virtual bool isValid() const override

Determine if the stream object contains valid data.


Where inherited classes are initialised by constructor this method indicates whether that was successful or not (e.g. FileStream)

Return values:

bool – true if valid, false if invalid

virtual uint16_t readMemoryBlock(char *data, int bufSize) override

Read a block of memory.


Should IDataSourceStream::readMemoryBlock return same data type as its bufSize param?

  • data – Pointer to the data to be read

  • bufSize – Quantity of chars to read

Return values:

uint16_t – Quantity of chars read

virtual bool seek(int len) override

Move read cursor.


len – Relative cursor adjustment

Return values:

bool – True on success.

inline virtual bool isFinished() override

Check if all data has been read.

Return values:

bool – True on success.

virtual String getName() const override

Returns name of the resource.


Commonly used to obtain name of file

Return values:



Used by

SoC support

  • esp32

  • esp32c2

  • esp32c3

  • esp32s2

  • esp32s3

  • esp8266

  • host

  • rp2040