FreeCalypso > hg > freecalypso-tools
view doc/Melody_E1 @ 1006:c3837867f631
Installed-binaries: new standardized packaging aid
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 10 Dec 2023 00:56:31 +0000 |
parents | e50c3aa1152a |
children |
line wrap: on
line source
Generating ringtone melodies through the Calypso DSP ==================================================== The DSP in the Calypso and other GSM DBB chips from TI includes a built-in capability for generating ringtone melodies to be played through a loudspeaker driven by the ABB, without using an external melody generator chip. More specifically, the DSP in question supports two flavors of internal melody generation, called Melody E1 and Melody E2 - although it is unclear whether Melody E2 is implemented in the DSP ROM or in the DSP code patches downloaded by TI's firmwares. The Melody E1 mechanism produces simple polyphonic melodies with up to 8 simultaneous notes; these melodies consist of simple sine waves generated by the DSP as commanded by the bits read from the melody file as explained below. Melody E2 is a more complex mechanism for producing melodies (also polyphonic with up to 8 simultaneous notes) using the sounds of specific instruments, rather than simple sine waves, but we currently lack the bits required in order to understand or exercise it, hence our current focus is on the simpler Melody E1 mechanism. How these melodies are played ============================= TI's RiViera Audio Service firmware component provides a front-end to the various audio services provided by the lower-level DSP+L1 combo. In the case of Melody E1 and Melody E2 features, the combination of the DSP and TI's ARM-side L1 code effectively defines the format of the melody bits themselves, but the RiViera Audio Service takes care of reading these bits from FFS and feeding them to L1. To play an E1 format melody, the UI code needs to call audio_melody_E1_start(); one of the arguments to this API function is the FFS absolute pathname of the melody file. The API function will open this file and pass the open file descriptor along with other parameters in the message posted to the Audio task; the latter task will prefetch the first buffer-full of melody bits from the file and then post an MMI_MELODY0_START_REQ message to the L1A task. The Melody E1 handler in L1A will set up some preliminaries and fire up the Melody E1 L1S task, and the latter will then pass the melody bits to the DSP at appropriate times. Melody E1 file format ===================== We have found a rather terse and not particularly thorough description of the Melody E1 bit format on pages 160 through 163 of this PDF document: https://www.freecalypso.org/LoCosto-docs/PSL1DOC/L1/L1M_AS001_1.pdf This description is not complete enough to enable proper understanding or implementation, but by combining it with a study of the L1A and L1S code that reads these bits and passes most of them to the DSP, we have reconstructed a somewhat more complete picture. The format is word-oriented, i.e., the basic unit of data in a Melody E1 file is the 16-bit word. Most of these words are passed to the DSP for final interpretation inside the latter, hence we won't be able to have a 100% certain understanding of what happens there unless we can find the source for the DSP ROM code or expend a Herculean effort to reverse-engineer it, but some of the words are interpreted and acted upon by the ARM-side L1 firmware code, which we have source-reconstructed already. When these words are written in a disk or FFS file, the byte order is little-endian, as it is ARM code that reads these 16-bit words from a byte-oriented source. The very first word in a Melody E1 file gives the global list of oscillators used by this melody; this word is read by the L1A code before the L1S task is fired up. The presence of this word is not documented at all in the terse description given in L1M_AS001_1.pdf, and our attempts at producing our own E1 melodies were going nowhere until we discovered that this word is needed through the study of our reconstructed TCS211 L1 code. This initial word corresponds to the osc-set line in our ASCII format. After the initial word giving the global oscillator set, the melody file consists of what we shall call time blocks. Each time block begins with a time descriptor word which is interpreted and acted upon by ARM L1S code, followed by 0 to 8 oscillator descriptors which are loaded into DSP API words. These words are described in TI's document, so we are just going to supplement that description wherever we have discovered something to the contrary. The lower byte of the time descriptor word tells the L1S task how long it should wait before loading the following oscillator descriptors into the DSP. It appears that TI's intent was for this time value to be measured in 20 ms audio frames, but what the ARM L1S code actually does is multiply the given time value by 4 and use the result as the number of TDMA frames to count - the L1S code executes on every TDMA frame. 13 TDMA frames equal 60 ms, thus 4 TDMA frames do not exactly equal 20 ms, but come a little short. It is not clear whether the melody files generated by TI and/or their customers account for this discrepancy or not. In any case, the time value given in the file needs to be non-zero - putting a zero in there will cause the L1S counter to be set to 65535 TDMA frames (a 16-bit unsigned counter loaded with 0 and decremented by one), which is probably not what you want. The upper byte of the time descriptor word is a bit mask indicating which DSP oscillators are to be loaded at this time. This bit mask byte can be zero, in which case the time block consists of just the time descriptor word. However, the L1S code does absolutely nothing to the DSP in this case, hence an empty (no oscillators) time block is indistinguishable from adding the time to the following non-empty block. But the largest time value that can fit in the byte is 255, hence empty time blocks can be used to produce larger time deltas. A time descriptor with zeros in both upper and lower bytes indicates the end of the melody; this terminator is required. Now we come to the interesting part: the oscillator descriptors that are loaded into the DSP to cause the actual melody generation to occur. The DSP's NDB API page contains 4 words for each of the 8 oscillators, and these NDB API words are where the oscillator descriptor words from the melody file ultimately go. Please refer to the description of the ml_load1 and ml_load2 bits on page 162 of TI's L1M_AS001_1.pdf document. Now here is what the L1S code actually does: first it loads 2 words from the file buffer into the DSP's NDB page - yes, directly into there. Then it does the following logic (code simplified from the actual into more readable pseudocode): load_size = 0; if (word1 & ml_load1) load_size++; if (word1 & ml_load2) load_size++; if (load_size) load load_size words at word2 address in the DSP's NDB page This logic is peculiar: what happens if ml_load2 is set but not ml_load1? The result will be that the word meant to be word3 (the envelope word) will get loaded into the word2 location in the DSP's NDB page. Unless the DSP actually checks the ml_load bits and expects the envelope word in the word2 location in this case, which I highly doubt, this L1S behaviour looks like a bug to me - so don't use the word3 present but not word2 combination in your melodies. It appears that these ml_load1 and ml_load2 bits are only checked by the L1S code and ignored by the DSP. I say so because when I tried creating a melody in which word2 and word3 were always omitted, the result was bogus. It appears that the first time a given oscillator is loaded, all 4 words must always be given, otherwise the DSP will act on whatever garbage happens to be in those NDB API words from before. When the same oscillator is subsequently reloaded, omitting word2 and/or word3 will cause that word's previous value to be reused. A few notes regarding some bits in word0: ml_synchro (bit 0): the L1S code ORs a 1 into this bit in the NDB API word after it has loaded all of the words. It thus seems more correct to me to put a 0 in this bit in the files, so that the DSP sees the new descriptor when it is complete - but of course we can never know for sure without knowing what actually happens inside the DSP. ml_directF: both common sense and the TSM30 source (which uses the Melody E1 feature of the DSP in that old Calypso version) suggest that ml_directF is bit 1, ml_square1 is bit 2 and ml_square2 is bit 3, i.e., it appears that the table on page 161 of L1M_AS001_1.pdf is wrong in this regard. Also note the order in which the fields are described on page 162 of the same PDF document. This is where our current knowledge ends. Until we either obtain a copy of the source for the DSP ROM or painstakingly reverse-engineer it, all we can do is look at the few existing examples of E1-format melodies we can find (see below) and experiment with putting different values in the various fields based on the description in the L1M_AS001_1.pdf document. Examples of E1-format melodies ============================== We've been very fortunate to discover that the legendary TSM30 phone appears to have used the Melody E1 feature, and that there are a bunch of E1-format melodies embedded in the famous TSM30 source from HispaPhreak. I have extracted these melodies, played them through the earpiece speaker on a Pirelli DP-L10 phone running FreeCalypso Magnetite (our own FCDEV3B with a loudspeaker that we can actually use has not been built yet as of this writing), and found some of them to be quite pleasant-sounding. These extracted TSM30 melodies can be found here: ftp://ftp.freecalypso.org/pub/GSM/ringtone/tsm30-melody-e1.tar.gz I also found a couple of melodies in our TCS211 reference semi-src under chipsetsw/services/Audio/tests; these two melodies illustrate how one can load word2 and word3 the first time and then omit them afterward when reloading the same oscillator. (All of the TSM30 melodies always load all 4 words in every oscillator descriptor.) Our own ASCII format for E1 melodies ==================================== In this FreeCalypso host tools package we have a utility for decoding existing Melody E1 binary bits into an amenable-to-study ASCII format, as well as a utility for generating new E1-format binary melodies from an ASCII text source in the same format. The ASCII format is of our own invention, and consists of numeric fields which map directly to the various bit fields in the DSP+fw's binary format. Our ASCII format for E1 melodies consists of 3 parts: an osc-set global header line, a sequence of time blocks, and an end line. The noteworthy aspects are: * Each time block is given as a time line followed by 0 or more osc lines. This lines must follow in direct succession without intervening blank or comment lines, and each time block must end with a blank line. * The end marker line is mandatory; having the ASCII file just end without it is an error. Please see the source code for fc-e1decode and fc-e1gen for the rest. Some words regarding Melody E2 ============================== E1-format melodies are self-contained: if you have a valid binary melody file in E1 format from whatever source, you can play it through the DSP of any Calypso device that runs our TCS211-based Magnetite firmware. But it is not so simple with Melody E2. In order to play a melody in E2 format, one needs not only the melody file itself, but also the set of *.mwa (instrument wave) files corresponding to the set of instruments used by that melody. It appears that the melody group at TI had produced as many as 48 different instrument wave tables: see the list in the non-production #if (AUDIO_SIMULATION) || (AUDIO_L1_STANDALONE) section of the Cust_audio_melody_E2_load_instrument() function in l1audio_cust.c in both TSM30 and LoCosto/Peek sources. (The LoCosto version lists 48 instruments whereas the much earlier TSM30 version lists only 40 of them, thus the list must have been added to over the course of TI history.) A given E2 melody selects a subset of 1 to 8 instruments out of the larger set to be used in that melody, and these selected instrument waves are loaded into the DSP's API RAM before the actual play of the melody itself. Unfortunately all we have are the *.mwa file _names_ for the 48 Melody E2 instruments that apparently existed at TI once upon a time, but not any of the actual bits. The TSM30 source uses only Melody E1, not E2, thus we do not currently have any source from which we can take any E2-format melody examples or E2 instrument wave tables for TI's DSP. We also don't have any documentation for any of these bits, and analysis of the Melody E2 code in L1 shows that it is significantly different from E1. The code in TCS211 L1 that reads Melody E2 file bits is not of much help for making our own E2 melodies, as all of the real magic happens in the DSP, not on the ARM side. Thus our FreeCalypso hardware+firmware combination is capable of playing both E1 and E2 melodies, but we won't be able to exercise the latter capability until and unless someone finds a surviving copy of some existing E2 melodies along with the *.mwa instrument wave files they require, whether it is the same instrument set as listed in the non-production section of l1audio_cust.c or a different one. But if someone does obtain a set of such melody bit files, our FreeCalypso devices running FreeCalypso firmware are ready to play them.