view doc/Buzzer-melodies @ 929:ab771ce34fac

rvinterf/lowlevel/format.c: get rid of static fmtbuf
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 23 May 2023 05:56:08 +0000
parents cb0f61535166
children
line wrap: on
line source

The Calypso chip includes a built-in hardware provision for driving
old-fashioned cellphone ringing buzzers.  Not all Calypso phones use a buzzer
as their ringing noise generator - many of the higher-end Calypso phones like
Mot C155/156 and Pirelli DP-L10 use a loudspeaker driven by a MIDI player chip
instead, and it appears that the legendary TSM30 phone may have used TI's
Melody E1 mechanism as its ringer.  However, Motorola C11x/12x and C139/140
phones do use an old-fashioned buzzer, and in FreeCalypso we also work with some
development boards that include one.  Having thus established the relevance of
the buzzer feature for FreeCalypso, we have done a bit of work toward exercising
the buzzer and playing melodies through it.  This article describes the
available support for buzzer melodies in FC host tools.

Buzzer hardware capabilities
============================

The actual noise-making element in phones like Mot C1xx appears to be a magnetic
buzzer - I previously assumed that it was a piezoelectic buzzer, but this
assumption now appears to be incorrect.  However, the relevant capabilities of
this old-fashioned cellphone ringing buzzer are determined not so much by the
physics of the actual noise-making element, but by the circuit with which it is
driven.  The buzzer is controlled by a single-bit digital output from the
Calypso chip, different tone frequencies are generated by Calypso as digital
square wave outputs, and different power control levels (for louder or softer
ringing sound volume) are produced by applying PWM to the "on" phase of the tone
square wave.

The Calypso chip allows its buzzer output to be driven with one of two different
internal logic blocks: either BU or PWT.  We don't have any authoritative
documentation for TI's earlier DBB chips prior to Calypso, but it appears that
LT and BU functions for light and buzzer control came first, built into the
ARMIO block which appears to precede the GSM Skunkworks business altogether, and
then at some later point the alternative PWL and PWT implementations were added.

When driven as BU, Calypso buzzer output can produce 255 different frequencies
ranging from 99 Hz to 12.7 kHz, produced by taking the 13 MHz master clock,
dividing it by 512, and then dividing it again by a programmable integer factor
in the range [2,256].  This mode of driving the buzzer works ideally when
non-musical output frequencies are needed, i.e., frequencies that are expressed
in absolute Hz rather than musical notes.

PWT appears to have been added specifically to facilitate playing of ringtones
that are composed of musical notes.  Compared to the range of 255 possible
frequencies that can be produced by BU, PWT can only produce 48 different tone
frequencies, but these 48 possible PWT frequencies are special in that they
closely approximate the 48 musical notes ranging from F4 to E8 in the scientific
pitch notation.  These 48 musical notes of PWT range cannot be reproduced as
distinct frequencies in BU mode: at the upper range beginning with A6, two or
three different notes collapse to the same BU tone frequency, as the possible
frequencies that can be produced from 13 MHz by the simple division implemented
in BU get farther apart than successive notes of the chromatic scale.  Thus if
you are seeking to play ringtones that are composed of musical notes, use of PWT
should be considered mandatory rather than optional.  OTOH, if you are playing
non-musical tones like SIT that are defined in absolute Hz, then BU will often
work better.

Motorola C1xx official firmware uses PWT mode to play its ringtones, both
built-in and user-composed, and we have successfully extracted some of those
professional-quality PWT melodies from at least one C1xx firmware version.

Concept of buzzer melodies
==========================

The Calypso buzzer (either BU or PWT) is monophonic, meaning that it can only
play one note at a time.  Given this constraint, a playable buzzer melody can be
defined as a list of {tone, volume, duration} tuples, where <tone> is the
frequency to be played (BU or PWT), <volume> is the relative volume for this
note (PWM volume control), and <duration> is how long this note should sound.

The definitions for <tone> and <volume> are straightforward - they are numbers
going directly into hardware registers - but in what units should the duration
of notes be reckoned?  In FreeCalypso we have adopted TDMA frames of 4.615 ms
(or more precisely 60/13 ms) as our unit of duration for buzzer melodies, based
on this reasoning: if playing of buzzer melodies is to be incorporated into
operational phone handset firmware, then TDMA frames will be the only time unit
that is available natively and directly, whereas any other measurement such as
milliseconds would have to be converted to TDMA frames by the firmware code.
Therefore, it makes the best sense to reckon all note durations in our buzzer
melodies in TDMA frames to begin with.

2022 addition: BUZM melody player engine in FC Tourmaline
=========================================================

As of 2022 our FC Tourmaline firmware includes a new buzzer melody player
engine, implemented as a RiViera-based service named BUZM.  The new BUZM service
sits on top of the low-level PWT buzzer driver in the same way how RiViera
Audio service sits on top of the low-level DSP+L1 combo, and the API (directed
toward UI firmware layers) of the new BUZM service is modeled after that of RV
Audio service.  The primary objective of this BUZM venture is to get rid of the
Condat audio driver layer mess which we inherited from TI (it has buzzer ringing
and audio tone generation entangled together in a gnarly way which we need to
move away from), but this migration also provides a secondary benefit: instead
of being hard-coded, buzzer melodies will now be read from files in FFS, just
like E1 melodies for loudspeaker-based ringing, allowing our UI firmware design
to be harmonized between the two ringer configurations.

The following design decisions underlie our new FC Tourmaline buzzer melody
facility:

* Regarding the choice between BU or PWT driving, PWT has been chosen.  All
  melodies created for playing via BUZM need to consist of musical notes F4
  through E8 (scientific pitch notation, 349 to 5274 Hz), as supported by
  Calypso PWT block.  This design decision matches Mot C1xx official firmware.

* Each melody is a sequence of sounded tones (PWT), either directly abutted or
  separated by pauses.  In actual implementation, each melody is a sequence of
  directly abutted entries, where each entry can be either a sounded tone or a
  pause.  Each entry (tone or silence) has a duration, reckoned in TDMA frames
  as explained above.

* For every sounded tone in a melody, a note volume in the range [1,64] is
  given.  If the melody is played at maximum volume, the per-note volumes will
  be written directly into the hardware register (PWM control in 1/64 units).
  If the user-specified play volume is less than 64, the actual sounding volume
  of each note is determined as (play_volume * note_volume / 64), with the
  division step rounding up - when both play_volume and note_volume are
  constrained in the [1,64] range, the result of the rounding-up division is
  also constrained in the same range.

In terms of tool support, each FreeCalypso PWT buzzer melody begins life as an
ASCII text source in the format defined by us.  It is then compiled into binary
form with our fc-pwt-comp utility, and the resulting binary melody file is
uploaded into FreeCalypso device FFS.  For manual testing, each uploaded buzzer
melody can be played with AT@BUZ command.  For finished phone operation, there
will be two ringtone list files (one for play-until-answer ringing tones and
one for non-repeating message alert tones) that will drive ringtone selection
in the phone UI.

The format of ASCII source files for PWT melodies is best documented by
examples: see several in the ringtools/examples directory.

Organization of melodies in FC device FFS
=========================================

We shall have two types of ringtone melodies in FreeCalypso: PWT melodies to be
played via the buzzer, and E1 melodies to be played via the voice path
loudspeaker.  Naturally, buzzer melodies can only be played on hardware
platforms that have a buzzer, and voice path loudspeaker melodies can only be
played on hw platforms that have such a speaker.  The only platforms that can
be expected to have both hw provisions are development boards like D-Sample and
FC Venus - but even on those development boards, each given UI firmware build
will support one or the other ringing type, but not both at the same time.

We shall have two separate FFS subtrees for these two melody types: PWT melodies
for the buzzer will be stored under /buz, whereas E1 melodies for the voice path
will be stored under /mel.  Both trees will be constructed on the host system
under /opt/freecalypso/buz and /opt/freecalypso/mel, and they will be uploaded
into FC device FFS with fc-fsio:

upload-subtree /opt/freecalypso/buz /buz
upload-subtree /opt/freecalypso/mel /mel

Individual melody files (compiled binary formats produced by fc-pwt-comp and
fc-e1gen) will be stored as /buz/melodyname.bz and /mel/melodyname.e1 for the
two types.  There will also be melody list or index files:

/buz/ringtones.mls
/buz/msgtones.mls
/mel/ringtones.mls
/mel/msgtones.mls

Each ringtones.mls file (for the buzzer or for Melody E1) will list the
available melodies for the continuous play-until-answer ringing tone, and each
msgtones.mls file will list the available melodies for the non-repeating message
alert tone.  The melody list (.mls) file format is defined by us: it is a binary
format consisting of fixed-length records, one 80-byte record for each listed
melody.  Each record consists of two fields: the FFS pathname (always absolute
as required by the RTOS environment without current directories) of the melody
file and the name of the melody for the selection menu in the phone UI.  Melody
lists are compiled from line-based ASCII source into this binary format by our
fc-ringlist-comp utility.

Support for iMelody ringtones
=============================

Back in the olden days when dumbphones with monophonic buzzer-type ringers were
the norm in society, there was a community of phone users who composed and
exchanged their own ringtone melodies; the community standard format for those
interchanges was EMS iMelody.  Searching around the Internet in 2022, I (Mother
Mychaela) couldn't find any iMelody ringtones that sound any good - the only
ones I could find sound like crap, nowhere near professional-quality melodies
which we've lifted out of Motorola's firmware.  However, as a matter of due
diligence, I felt that it would improper for FreeCalypso not to support iMelody
ringtones, hence I wrote a program that groks iMelody files and converts those
melodies to our native PWT format - this program is fc-imy2pwt.

Right now fc-imy2pwt implements a subset of the iMelody spec; the missing
features are:

* All volume change commands in the melody are ignored: fc-imy2pwt does not
  support per-note volume changes within the melody, and all PWT notes are
  emitted at the maximum per-note volume of 64/64.

* The STYLE setting in IMY files is ignored, and all melodies are converted as
  if the style was S1, i.e., continuous, without automatically inserted rest
  between notes.

* All vibrator/LED/backlight control commands are ignored: in FreeCalypso
  architecture there is no synchronization between ringtone melodies and
  vibration cadence, instead the user selects between silent mode, ring only,
  vibrate only or ring+vibrate alerting as needed, without interference from
  overly-creative vanity melody composers.  Likewise, we do not support
  melody-driven manipulation of any lights.

The policies of keeping the ringer and the vibrator separate and of leaving our
LCD and keypad backlights alone are absolute, whereas support for volume changes
within the melody and for non-S1 styles (automatically inserted rest periods)
can be implemented *if* someone in our community has a real use case for such
functionality.

Standalone buzzer exercising (outside of FC firmware)
=====================================================

We have a target utility (running on Calypso devices out of RAM) called
buzplayer, and a front end host program called fc-buzplay.  If you load and run
buzplayer manually via fc-iram, you can use it to exercise the buzzer manually,
playing any tone at any volume, in either BU or PWT mode.

fc-buzplay is a higher-level tool: it establishes out-of-firmware operation on
a target Calypso device similarly to fc-loadtool (based on the same framework),
but running buzplayer instead of loadagent.  Once you land at the buzplay>
prompt, the main command of interest is 'play': it takes one required argument,
the name of the melody file to play (ASCII BU or PWT format), and a second
optional argument, the play volume in the [1,64] range.  The current version of
this 'play' command intuits the melody format (BU or PWT) from the filename,
which must end in .buz or .pwt, respectively.  You can also issue explicit
play-bu and play-pwt commands, in which case the filename can be anything.  All
of these play command variants read the melody file in the respective format
(ASCII in both cases, line-based), feed the melody to the target, and then
command buzplayer to actually play it on the physical buzzer.