tokenrove / ymamoto Goto Github PK
View Code? Open in Web Editor NEWA replay routine for the Atari ST, using the YM2149 chip.
A replay routine for the Atari ST, using the YM2149 chip.
YMamoto Alpha Zero Julian Squires <[email protected]> / 2004 ABOUT YMAMOTO YMamoto is my first attempt at a reasonable music playroutine for the Atari ST. The design goal is to allow the production of interesting music; I considered adding efficiency of {memory usage, song size, cycles per frame} to the set of goals, but I decided that aiming at any of these things directly would just cripple the main goal, until I am more familiar with the ST and the YM. So, YMamoto, when finished, should be suitable at least for music disks and parts of demos where cycles aren't too scarce. USING YMAMOTO IN ANOTHER PROGRAM Call ymamoto_init with A0 pointing to the song data, and D0 set to the track index to play. Note that the first track index is 1, not 0. Call ymamoto_update once per frame until it returns $FFFF in D0. FIXME: Eventually there will be a way to use trigger events to allow you to sync your effects to the music. YMAMOTO DATA FORMAT All relative pointers are to long aligned addresses, and hence the pointers are stored as shorts, and shifted left two bits to get the actual address. These pointers are relative to the beginning of the song data, not their current position, and are always forward references, so they don't get sign extended when loaded from words. SONG pointer to arpeggio table (word, relative, >>2) pointer to volume envelope table (word, relative, >>2) pointer to vibrato table (word, relative, >>2) number of tracks (byte) Should always be >=1. offset to track 0 (word, relative, >>2) offset to track ... TRACK (long aligned) channel A start point (word, relative, >>2) channel B start point (word, relative, >>2) channel C start point (word, relative, >>2) CHANNEL DATA STREAM (long aligned) The two kinds of values possible in the channel data stream are notes and commands. They can be determined by the value of their MSB, which is 0 for notes, and 1 for commands. Notes are stored in the following inefficient way: 0ddd dddd rnnn nnnn d => duration, in frames-1, from 0 (1/50th of a second) to 127 (2.56 seconds). r => reserved (0). n => tone, value from 0 = C0, 95 = B7. 126 = wait, 127 = rest (wait, silence channel). Other values might be used for special purposes. Global commands: (can occur in any channel; need only occur once) 10rr rccc xxxx xxxx r => reserved. c => every track must end \ 000 => track end (not followed by any data) with one of these. / 001 => track loop 010 => trigger external event x => command data Channel commands: 11cc cccc xxxx xxxx 1100 0001 aaaa aaaa arpeggio. 0 = disable arpeggio. 1100 0010 xxxx xxxx set detune 1100 0011 xxxx vvvv set fixed volume 1100 0100 eeee eeee set software volume envelope. 0 = disable soft envelope. 1100 0101 nnnn nnnn enable/disable noise. n = noise frequency, 0 to disable. 1100 0110 xxxx xxxx AM sample playback [reserved.] 1100 0111 <envelope bytes would follow> set hardware envelope [reserved.] 1100 1000 xxxx xxoe envelope-follow mode. e = enable/disable; o = one octave lower/same pitch. 1100 1001 pppp pppp pitch envelope. 0 = disable pitch envelope. 1100 1010 ssss ssss portamento. s = speed. 1100 1011 vvvv vvvv vibrato. 0 = disable vibrato. Arpeggio and venv tables: (long aligned) number of entries in table (byte) entry 1 length (byte) entry 1 loop point (byte) entry 1 data (length*byte) ... Vibrato table: (long aligned) number of entries in table (byte) entry 1 "length" (byte, always 3) entry 1 delay (byte) entry 1 depth (byte, 0 through 8) entry 1 speed (byte, 0 through 4) entry 1 oscillator mask (byte, 1<<speed) NOTES ON IMPROVING YMAMOTO ENVELOPES It might be nice to provide a means for sweeping the envelope, perhaps by a table driven method like arpeggios and vibratos. Also, changing the shape on the fly, perhaps even with a separation timer. STORAGE I think I'm going to rewrite this as a byte-oriented format. Word orientation seems to waste more than it gains (marginal theoretical speed improvements). Also, I've been reading Rob Hubbard's replays lately, as well as various others, and I like some of his approaches a lot. Notes could be stored as being relative to a base octave (set with separate commands), just as their duration could be stored as being relative to a base duration. This would probably allow encoding most note data as single bytes. (Tone value would need no more than five bits, to encode +15/-16 tones; duration could be just two bits, allowing access to the four most common durations.) Obviously, a system for encoding loops and repeats would be good; especially something that took alternate endings into account, because that would seriously improve the value of repeats for a lot of my music. Also, possibly a system based on windows (rather than "patterns" in the tracker sense) might be really handy for riff-oriented music. Being able to define ``instruments'' that allowed voices to rapidly switch a variety of characteristics at once, might save some time and space. (An instrument might define a base range, default staccato, default volume envelope, default vibrato, et cetera.) We may need to increase the size of the relative offsets, though ``64k should be enough for anybody''; time will tell, as I write longer tunes. Arpeggios (and other tables) could be stored aligned on 8 byte boundries, to make seeking into the arp table very quick. For arpeggios longer than 8 bytes, you could just have ``double wide'' arpeggios that take up 16 bytes. DURATIONS An alternate approach to duration is to fix the atomic duration (one frame), and have the music creation tool do all the duration calculations. This is good for some kinds of music, but it means that one cannot switch a song between 50 and 60 Hz replay without recompiling it. This is what we have now; the notes below apply to the previous system, which was replay-speed independant. Duration modifiers are probably very rarely used together (tied, double dotted triplets for example); they can probably turn into something state based (which would allow us to accomidate stranger timings, like quintuplets). This is the old duration format T => 1 = tied with next note D => duration modifier: 000 => normal 001 => dotted 010 => double dotted 100 => triplet time (quintuplet time? duplet time?) NB that these may change from independant flags into a single, 8 state value. d => duration, value from 0 (whole note) to 7 (128th note). Another thing is that, if we find we're already doing full divisions somewhere (because of quintuplets or whatever), we might as well just start representing durations as arbitrary fractions; this allows much more flexibility in some ways. MISC. It could be interesting to provide a sort of voice scheduling system, which tried to fit ``optional'' voices in on channels when the regular voice was silent (due to rests or staccato). Maybe this is better placed in the music composition tool, though.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.