# Blog

## Weekend side project: sap2mid

A couple of days ago I realized there was no such thing as a program to convert SAP files into MIDI files. This sucks, as I wanted to experiment with "orchestrating" some of my favorite tunes found in the Atari SAP Music Archive.

Now, I'm not by any means great at this, but I've done some experiments before using manual transcriptions, and in the end I found that these chiptunes do have a lot of potential:

And that was transcribed by hand, which was more time consuming than necessary and it gets very hard for more complex chiptunes.

So when I started hunting for a way to automate it, I found out there's a convoluted way to convert SAP files into CSound files, but this seemed like an unnecessary chore, and the patches aren't compatible with the modern ASAP code which actually supports playing a lot of the tracks in the Atari SAP Music Archive, which previous versions weren't able to.

So I studied everything I could find about the Atari POKEY sound chip, I've downloaded emulators to play around with it, I tried to understand how the POKEY chip is controlled and how it is used for music.

Then, after a more in-depth look at the ASAP source files, I found out there's a little application in there called asapscan, which can give some information about SAP files. One of available parameters simply dumps the raw POKEY registers relevant for sound generation: AUDF1-4, AUDC1-4 and AUDCTL This is what the dump looks like:

2.04: 00 83  BF C6  00 00  00 00  40 | 00 83  BF C6  00 00  00 00  40


The first word being the current time stamp, and the next 8 values being AUDF followed by AUDC, for each of the four channels. The vertical pipe means there are two POKEY chips, so this is a stereo SAP.

So it turns out I already have a program out there designed for dumping the POKEY data. I wouldn't have to deal with the CPU emulation or anything of the sort, and the RAW dump contains all the information I'd ever need to create a MIDI file.

My C skills are rusty, so for now, instead of making a proper executable, I simply modified asapscan to dump a modified version of this data with more precision for the timestamp, which then is parsed by a Python script in order to generate the MIDI file.

Here are some preliminary results:

The original SAP file:

And here's the first generated MIDI file. Success!

There are a lot of stuff that still needs tweaking, and I'm still trying to figure how to interpret certain types of POKEY data (e.g. high pass filters) as something useful.

For now, I'm only handling a few of the poly types, and each as separate instruments, as each generates a particular type of timbre that's very predictable. I have already experimented successfully with the higher polys being treated as drum notes, but I'm not sure how well that'll work with other files.

There are other issues that need to be addressed, but I'll work on that later.

### More output examples

Now here's a few output MIDIs straight from the script, without any modification whatsoever, along with YouTube links showing what each music is supposed to sound like.

Some more output examples available here, if you're interested.

As you can see, there's a lot of stuff that doesn't sound quite right (poly 000 is wrong, for one, I'm not sure why yet), and some important modulations aren't being accounted for, but even so, it is working surprisingly well already, and the tracks themselves are very easy to cleanup and fix.

Also, I have no idea why some channels end up being almost silent, while others are just fine. Is there a multiplier for the overall volume that I'm not aware of? If you know about it, please comment!

Well, it's been an interesting little project so far. Sadly I need to move on to something else for now, but I'll definitely come back to this and fix all the issues I can when time allows.

### Update

Well, I've fixed the code a bit. It seems to be more accurate now, and it's not hanging notes on Draconus or Bells as it did before. Still, there's a lot of dissonance going on for some reason.

I'm guessing it's the 16 bit mode. It sounds better if I ignore it in Draconus, but the actual notes seem correct if I don't.

This could also be related to the filters. As there is no way to handle them during the conversion (at least none I can think of), the results don't sound the same.