{"id":13800875,"url":"https://github.com/dhylands/upy-rtttl","last_synced_at":"2025-07-02T04:33:08.771Z","repository":{"id":54370724,"uuid":"64044816","full_name":"dhylands/upy-rtttl","owner":"dhylands","description":"Python Parser for Ring Tone Text Transfer Language (RTTTL)","archived":false,"fork":false,"pushed_at":"2025-02-17T02:55:21.000Z","size":19,"stargazers_count":40,"open_issues_count":2,"forks_count":11,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-06-24T09:14:25.719Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","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/dhylands.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-07-24T02:22:40.000Z","updated_at":"2025-06-05T22:12:11.000Z","dependencies_parsed_at":"2022-08-13T13:40:33.577Z","dependency_job_id":null,"html_url":"https://github.com/dhylands/upy-rtttl","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dhylands/upy-rtttl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dhylands%2Fupy-rtttl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dhylands%2Fupy-rtttl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dhylands%2Fupy-rtttl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dhylands%2Fupy-rtttl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dhylands","download_url":"https://codeload.github.com/dhylands/upy-rtttl/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dhylands%2Fupy-rtttl/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263075273,"owners_count":23409890,"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","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":[],"created_at":"2024-08-04T00:01:17.205Z","updated_at":"2025-07-02T04:33:08.742Z","avatar_url":"https://github.com/dhylands.png","language":"Python","funding_links":[],"categories":["Libraries"],"sub_categories":["Audio"],"readme":"Ring Tone Text Transfer Language Parser\n=======================================\n\nThis library can parse RTTTL text lines and delivers the frequency and duration\nfor each note.\n\nA typical RTTTL string looks like this:\n```\nEntertainer:d=4,o=5,b=140:8d,8d#,8e,c6,8e,c6,8e,2c.6,8c6,8d6,8d#6,8e6,8c6,8d6,e6,8b,d6,2c6,p,8d,8d#,8e,c6,8e,c6,8e,2c.6,8p,8a,8g,8f#,8a,8c6,e6,8d6,8c6,8a,2d6\n```\n\nYou can find many more sample ring tones here: http://www.picaxe.com/RTTTL-Ringtones-for-Tune-Command/\n\nYou can find a description of RTTTL here: https://en.wikipedia.org/wiki/Ring_Tone_Transfer_Language\n\n# Using RTTTL on the pyboard\n\nInstantiate an instance of the RTTTL class, passing in the tune string to the\nconstructor.\n```python\ntune = RTTTL('Entertainer:d=4,o=5,b=140:8d,8d#,8e,c6,8e,c6,8e,2c.6,8c6,8d6,8d#6,8e6,8c6,8d6,e6,8b,d6,2c6,p,8d,8d#,8e,c6,8e,c6,8e,2c.6,8p,8a,8g,8f#,8a,8c6,e6,8d6,8c6,8a,2d6')\n```\n\nThen use the notes generator to enumerate the notes in the tune. The notes\ngenerator will return a tuple, where the first entry in the tuple contains\nthe frequency of the note (in Hz) and the second entry in the tuple contains\nthe duration of the note.\n```python\nfor freq, msec in tune.notes():\n    play_tone(freq, msec)\n```\n\nWhen using a piezo you basically provide a 50% PWM signal to the piezo using the frequency of the note. Some piezo speakers can vary the volume by using a different duty cycle. The piezo on the G30DEV board Dave Hylands this on, it didn't seem to make any difference.\n\nIn order to distinguish consecutive notes, you need a small gap between the notes.\nDave Hylands chose to use 90% of the duration to play the tone, and 10% of duration to play silence.\n\nDave Hylands used the following play_tone routine on the G30DEV board:\n```python\nimport pyb\nbuz_tim = pyb.Timer(3, freq=440)\nbuz_ch = buz_tim.channel(1, pyb.Timer.PWM, pin=pyb.Pin.board.BUZZER, pulse_width=0)\ndef play_tone(freq, msec):\n    print('freq = {:6.1f} msec = {:6.1f}'.format(freq, msec))\n    if freq \u003e 0:\n        buz_tim.freq(freq)\n        buz_ch.pulse_width_percent(50)\n    pyb.delay(int(msec * 0.9))\n    buz_ch.pulse_width_percent(0)\n    pyb.delay(int(msec * 0.1))\n```\n\nDave Hylands put a recording of the above on YouTube: https://youtu.be/TadV2AEvfww\n\nThe G30DEV board definition files for MicroPython can be found here: https://github.com/dhylands/G30DEV\n\nWhen using pin Y2 on a pyboard v1.0, change the timer/pin to:\n```python\nbuz_tim = pyb.Timer(8, freq=440)\nbuz_ch = buz_tim.channel(2, pyb.Timer.PWM, pin=pyb.Pin('Y2'), pulse_width=0)\n```\n\nTo see which timers are available on which pins, consult the MicroPython quickref:\nhttp://docs.micropython.org/en/latest/pyboard/pyboard/quickref.html\n\nDavid Glaude used the following play_tone routine on Circuit Python M0 board:\n```\nimport board\nimport pulseio\nimport time\n\nspeaker_pin   = board.D0  # Speaker is connected to this DIGITAL pin\n\n# Initialize input/output pins\npwm       = pulseio.PWMOut(speaker_pin, variable_frequency=True, duty_cycle=0)\n\ndef play_tone(freq, msec):\n#    print('freq = {:6.1f} msec = {:6.1f}'.format(freq, msec))\n    if freq \u003e 0:\n        pwm.frequency  = int(freq)   # Set frequency\n        pwm.duty_cycle = 32767  # 50% duty cycle\n\ttime.sleep(msec*0.001)  # Play for a number of msec\n    pwm.duty_cycle = 0          # Stop playing\n    time.sleep(0.05)            # Delay 50 ms between notes\n```\n\nFiles:\n- circuit_test.py: Playing RTTTL on M0 Circuit Python board.\n- pc_test.py: Printing RTTTL decoding on any platform (no sound produced).\n- pyb_test.py: Playing RTTTL on G30DEV board.\n- rtttl.py: RTTTL decoding library.\n- songs.py: Optionnal collection of RTTTL songs to test the library.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdhylands%2Fupy-rtttl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdhylands%2Fupy-rtttl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdhylands%2Fupy-rtttl/lists"}