MYM Player

This forum is about audio tools, including samplers, sound trackers, sound chip editors, how to do sound effects, etc...
User avatar
Dbug
Site Admin
Posts: 4437
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

MYM Player

Post by Dbug »

For people that want to replay existing Atari ST/MSX/Spectrum/Amstrad tunes, there is still the possibility to use the MYM player port I did some years ago.

Some demo tunes are available here:
http://www.defence-force.org/computing/ ... /index.htm

It is also this player I used (in a slightly debugged version) in my Buggy Boy intro presented at LCP 2004 demo party.
http://www.defence-force.org/computing/ ... /index.htm

I guess I could publish the source code and converters too :)
This is not the fastest way (CPU wise) to replay musics (for example the players from Twilighte takes way less memory and cpu time... but when you do not have musicians available to play with SONIX it is not that bad.

I guess it could be used to do music demo discs, or as an economical way to 'upgrade' some old adventure games by adding nice soundtracks.

There are archives of tunes already converted to MYM format, that are ready to use:

http://ftp.kameli.net/pub/mym

If somebody is interested, I can provide more explanations on how to use all that...
User avatar
kamelito
Flying Officer
Posts: 182
Joined: Sun Jan 08, 2006 6:34 pm
Location: Nantes, France

Can you explain why the musics have to be converted?

Post by kamelito »

Hi Mike,

Can you explain why the musics have to be converted?
Does that mean that the Oric is not capable of running *.snd file ?

Sure share the code and explain us how to use it :)

Kamel
/kml
skype pseudo : kamelitoloveless
User avatar
Dbug
Site Admin
Posts: 4437
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: Can you explain why the musics have to be converted?

Post by Dbug »

kamelito wrote:Does that mean that the Oric is not capable of running *.snd file ?
Well, I guess that what you call SND files are actually file in SNDH format, that can for example be replayed by WinJAM.

These files are the exact equivalent of the .SID files. They contained both the music AND the replay routine. This means that the replay routine has to be executed for the music to play... in the case of the SID, the processor is a close cousin of the 6502, so it is possible for the Oric to play the code straight (with some quirks due to the differences in memory mapping between the C64 and the Oric). All you have to do is to interpret the commands sent to the SID chip, and transform them as something somewhat equivalent on the AY chip.

For the SND files you cannot do the same thing, because it would mean executing 68000 code on the Oric. Even if a music player only takes something like less than 10% of the total CPU time of an Atari ST, it still means you have a 1mhz 6502 processor to emulate 10% of the speed of a 8mhz 32 bits 68000.

I don't know for you, but me I'm not able to do that :D

Of course if you manage to do it, the easy part is that what you get can be directly injected in the AY soundchip (eventually dividing by two the frequency of notes to compensate for the difference in frequency between the two sound chips).
kamelito wrote:Can you explain why the musics have to be converted?
I theory we could convert the player, but this would be a tremendous work. Basicaly it's like writing a offline emulator able to transform 68000 code in 6502. And that's not easy. That's why musics need to be converted.

The easiest way is to ditch completely the player, and just replay the song dumbly.

Since a music player on the Atari ST typicaly is called from the screen refresh interupt, it means we have 50 (or 60 in NTSC) updates each second. The AY chip has 16 registers, but some are used for input and output ports, and thus are not part of the music. What remains is 14 registers.

If we just (on the Atari ST) modify the replay routine to write into a buffer in memory instead of sending registers values to the soundchip, we can then store the complete tune as just a list of registers to send back later.

It's what I did with the Trust music in my first Oric big scroller. (and it's actually something I was already doing in 1990 on the Atari ST to avoid spending processor time on playing the music :) ). And it's something that Leonard did later with ST Sound. All these .YM musics are just compressed dumps of YM registers.

Memory wise, this is not very efficient, that's why people does not store raw registers dumps.

14 registers saved x 50 times per second, means we need 700 bytes for each second of music. That's 42000 bytes for one minute. As you can see we cannot store a very long tune one the Oric using this method.

But there is ways to improve that. First you can use the fact that not all the bits of the registers are used. Here is the list of all YM registers:

Code: Select all

 Register Array
                            B7....B0
R0 Frequency of Channel A   00000000   8 bit fine tone adjustment
R1                          ----0000   4 bit rough tone adjustment
R2 Frequency of Channel B   00000000   8 bit fine tone adjustment
R3                          ----0000   4 bit rough tone adjustment
R4 Frequency of Channel C   00000000   8 bit fine tone adjustment
R5                          ----0000   4 bit rough tone adjustment
R6 Frequency of Noise       ---00000   5 bit noise frequency
R7 I/O port and mixer       iinnnttt   i-I/O, n-Noise, t-Tone
   settings                 bacbacba
R8 Level of channel A       ---mllll   m-Mode, l-Level
R9 Level of channel B       ---mllll   m-Mode, l-Level
RA Level of channel C       ---mllll   m-Mode, l-Level
RB Frequency of envelope    00000000   8 bit fine adjustment
RC                          00000000   8 bit rough adjustment
RD Shape of envelope        ----cath   c-Cont, a-Att, t-Alt, h-Hold
RE Data of I/O port A       00000000   8 bit data
RF Data of I/O port B       00000000   8 bit data
Obviously it is possible to put together some of the 4 bits registers. R1 and R3 can both fit in one single 8 bit value, and the same goes for R5 and RD.

Just doing this already reduced the memory consumption from 14 to 12 registers.

R6, R8, R9 and RA are all 5 bits registers, and R7 is having 2 free bits (we do not care about the status of the I/O port. This means that we have 3*3+2=11 free bits. Enough to ditch one more register.

So we finaly end-up with 11 registers to store each frame. If we do the same computation that earlier, this is 11*50=550 bytes per second, and 33000 bytes per minute. Still not awesome, but at least without doing much work we have won 9000 bytes.

But it's possible to get even better by using compression.

The YM files are not usable on the Oric because the packing method used oblige to get the whole file unpacked in memory to be able to read it. It obviously works fine on PC, but on an Oric it's not possible.

It's why some people (on MSX, Amstrad and Sinclair) have been working on this. And they made the MYM format. It does not compress as well as YM, but at least it's possible to unpack progressively using just few buffers.

Code: Select all

Sure share the code and explain us how to use it :)
I will do that later.
To late for today :)
User avatar
carlsson
Pilot Officer
Posts: 127
Joined: Thu Jan 12, 2006 11:26 pm
Location: Västerås, Sweden

Post by carlsson »

And MSX, ZX and CPC have the Z80 processor in common, so any music formats developed natively on these computers would still not work on the 6502 Oric without a Z80 emulator.

I guess you could take an Atari ST music player, disassemble it and figure out what it does with its song data, and write a new player following the same song structure. If several Atari ST musicians used the same routine, it could be applied to many songs and more compact than a "dumb" dump of register values. But it wouldn't be an easy task!
Anders Carlsson
User avatar
Dbug
Site Admin
Posts: 4437
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Post by Dbug »

And MSX, ZX and CPC have the Z80 processor in common, so any music formats developed natively on these computers would still not work on the 6502 Oric without a Z80 emulator.
Sure but MYM is not a native music format, it does not includes any replay code. It's just practical way of compressing data, suitable for 8 bits machines. Unpacking code is very simple. And I already ported the MYM player from MSX to the Oric.

Actually I've been cheating :)

The original distrib included two C source files, one to convert from YM to MYM format, and one to do the reverse operation.

If just started by transformating the MYM to YM source as a replayer (using the C compiler), and then I optimised.

I guess you could take an Atari ST music player, disassemble it and figure out what it does with its song data, and write a new player following the same song structure. If several Atari ST musicians used the same routine, it could be applied to many songs and more compact than a "dumb" dump of register values. But it wouldn't be an easy task!
Well, then better get in touch with the author of one Atari ST tracker (like Gwem of MaxYMiser fame) and get a way to devise an Oric player.

For the already made musics, I don't think it's worth the pain. There's already thousands of songs available in YM/MYM format, that can be for most directly replayed on the Oric without any other effort than putting them together on a disc.
User avatar
Euphoric
Game master
Posts: 99
Joined: Mon Jan 09, 2006 11:33 am
Location: France

Post by Euphoric »

And MSX, ZX and CPC have the Z80 processor in common, so any music formats developed natively on these computers would still not work on the 6502 Oric without a Z80 emulator.
I've done some work on emulating the 8080 and the Z80 on 6502 and 65816 cpus... I wanted to emulate some classic arcade games in order to have the "real thing" on the oric :-)
For example, I have a Space Invaders emulator on the Oric that you can fetch here : http://oric.free.fr/TAPES/midway.tap. Of course, a big problem was to rotate the screen 90° and convert it to the oric strange format (only 6 bits out of 8 store bitmap data). No need to say it was impossible to do in real time :-)
Anyway, the result is still fun to see if you speed-up Euphoric's emulation by a factor of 10 or 16: I like the waiting/demonstration feature with that invader coming and fixing the typos in the title screen :-)

Then I wrote a sort of "static compiler" which is the term sometimes used to describe the translation of binary code to a different cpu. In this case, it was about emulating 8080 and Z80 arcade games on a 65816 processor (a few Midway games for the 8080 cpu, and Namco's Pacman for the Z80). The most annoying part was tackling with computed branches, which obliged me to keep a huge table for address translation. Of course, the screen format problem is still there, but by accepting to have my TV monitor sideways, I have those Midway games running at a normal pace on a 3.5 MHz 65816 (SNES).

So, I think that it would be possible to have such static translation for music tunes *if* the code is not too big (the translation expands the size of the code), and provided that the same music chip is targetted... The 68000 is not a so fast cpu (each instruction takes quite a big number of cycles), so if only 10% of the ST power is required, I think it could be easily coped by a 1 MHz 6502... (6502 rules! :-)
Longshot
Private
Posts: 1
Joined: Wed Nov 08, 2006 11:45 pm

Post by Longshot »

Hello

I know that this subject is a little bit old (last post in jan 06) but i've just found this forum through a google link :D
This post is very interesting about the methods used on our oldies computers to play tunes from other platform

The SNDH format seems to be an interesting project, very useful for people who have computer using same processor and also same soundchip (according a little frequency adaptation) because the music data is consuming less kilobytes than a YM, AY, MYM, .. formats
The default is that players can be slowest than an unpacker of AY registers (but, when used in "critical" demoes, for example, it's possible to use "inter-part" screens to unroll registers)

For other platform, i think it's not so difficult to translate the player code from a processor to another. A "mechanical" translator cannot optimize like a "human" translator, especially when the code comes from a powerful processor. Also, the code of lot of players are really similars because lot of musicians were using the data structures very closed.
From 1989 to 1991, i'd translated eight 68000 players from atari on z80a on cpc (dividing frequency by 2)
This kind of conversion was not so difficult because the AY is a 8 bits processor, and i supposed (seeing the 68000 code) that this code was coming initially from a 8 bit processor, because 68000 registers was never used as 32 bits registers but only like 8 bits, and also, lot of musician were using the same sources, just modifying some subroutines.

The problem was a little more difficult for soundtrack. I don't remember anymore how the AY soundchip register are managed on an oric (i suppose by poke) but on Cpc, the only way to access the soundchip is through a PPI chip. So writing in a AY register cost lot of time. It's not really important for a single drum sample, but much more bad if you want to access simultaneously to the 3 level registers to "simulate" with 3 four-bit registers one 8 bits level register...
Rhaaaaa
JamesD
Flight Lieutenant
Posts: 358
Joined: Tue Nov 07, 2006 7:38 am

Post by JamesD »

I'm working on a music player for another 8 bit and the best thing I've been able to come up with to reduce the size of these files and still have portability is a virtual machine of sorts. Kinda like what infocom's ZMachine did for adventures but for music.
It would have a few registers for counters, simple loops. Possibly a few instructions for setting AY registers based on virtual machine registers.
I've actually thought out how to do a lot of it and what instructions to support.
Instructions would actually be a byte offset into a table of addresses of routines to handle the instruction. That way to execute an instruction just requires an indexed indirect jump. (or whatever it's called)

I figure instructions would be something like:
10 LD R0 ; load R0 with following byte
12 INC R0 ; increment R0
14 DEC R0 ; decrement R0
16 ADD R0 ; add following byte from R0
18 SUB R0 ; subtract following byte from R0
1A CMP R0 ;compare R0 with following byte
1C
1E
20 LD R1
22 INC R1
24 DEC R!

The code will probably be larger than if registers were encoded as part of the instruction byte but by doing this the instruction is decoded in the jump
Then there needs to be branch instructions, return from interrupt, end of song, transfer register to register, output virtual register to AY register, output block register pairs (AY register, value), etc...

This *could* make very complex music possible. The player is larger and slightly slower but it's under control of the musician.
Fading music in or out could be possible.
Controlling the music from outside the music could be possible by manipulation of virtual registers... lots of cool stuff.
Post Reply