Look for downloads on external sites:
Submitted by algorithm on 6 September 2017
This single filer C64 demo is a remake of a the classic KAOS part in the amiga budbrain megademo.
How it came about
After experimenting with a few other (more cpu consuming) audio compression routines for the c64, I
decided to revisit the fast VQ decode method as I was planning in mixing and decoding multiple streams on this machine.
The original idea was to mix in two fixed size looped samples to give more "variety", but after starting coding the routine, It was not an issue to mix in 4 vq packed samples and to still leave some spare cpu time.
I decided to adjust the player so that it can read in data similar to a mod (4 tracks, timeline, triggered samples). In a matter of time, I was able to play back 4 channels and trigger any vq sample in the timeline for each track individually.
Some quick adjustments later, I had separate volume control per sample as well as some other gating options as well as playing looped samples (chords etc)
Now, there had to be some sacrifices that were required to be made. Pitch adjustments would have been an easy possibility (via indexing incremental pitch tables and adding at the end to the low offset - as in the frodigi pitch adjustment method). However, I decided to opt for using VQ compression on all channels which would allow me to use 4 times the samples in ram and also allow me to overcome the limitation of no-pitch by using resampled data for notes.
Some modules consist of fixed pitch samples (such as drums, sample loops and precalculated chords). However, the main lead and bassline does not have too many note variations. If for example you would take into account a bassline with 4 pitches, Even with 4 separate samples per pitch, this would compress to the equivalent of a single instrument due to the vq compression. This together with the compression of the fixed pitch samples would generate a mod usually far smaller than the original.
I was going through a few modules and came across the Kaos mod (from budbrain megademo). This consisted of a few loops and fixed pitch samples and only a few different notes per sample for the bassline and lead instruments. It was a good candidate for testing. Once done, I had created a 1:1 conversion and decided to make a demo from it.
The conversion process was mundane and time consuming and would have been considerably faster If i had automated this somewhat. However as i had started the exercise, I decided to continue using the manual approach for the mod.
I went through each sample (from beginning to end) and see if there are different frequencies used in the mod for that particular sample. Then on an empty mod, entered these samples with the separate frequencies to play one after another.
e.g. if sample 2 in the mod is played back at d#5 and c#5, enter d#5 and c#5 in a blank mod
the sample chunk would then be saved as a 44100hz wav, this would then be imported into an audio editor, then resampling the whole chunk at 8400hz. The individual notes would then be saved as a multiple of 168 bytes (equiv to a frame of playback at 8400hz) Each note would then be given something easy to identify (e.g sample2-d#5) etc
Then the process was repeated for all the samples used in the mod.
These samples are then converted to 64 intensities and combined and VQ packed with the relevant offset start and length data.
To recreate the mod using the new samples, the new samples would be inserted into the relevant sample slots using default sample rate (8400hz). Any different pitches have the relevant sample inserted with the required volume commands.
For other pitch bending based commands, segments of that sample were extracted and used.
This would then result in a full mod file using these remapped samples that can be played back using my custom vq mod player.
The patterns were split from 64 sections per track to 16, and then all redundant patterns removed, then remapped to the 16 sections. This saved significant ram space.
The mixer / music driver
the core of the routine is a vq lookup reader with each lookup having 256 possible values that points to 1k codetables that are precalculated in 4 levels of volume. the data for each track is mixed together than pushed to stack ahead of time (With the NMI reading from stack earlier).
In order to save more on cpu time, the mixer is dynamic in nature. It can adjust itself using one of 16 routines based on whether any samples with non-zero volume are currently playing back in that frame. If all 4 channels are active in that frame, the typical cpu usage is around 80% while it would be far lower if 3 or less channels are active.
I had done a few experiments in quality of mixing and found that the signed 6bit addition method worked best for the fastest mixing. It may have been possible to even use signed 7bit with careful prereduction of volume without any overflow, but decided to opt for the 6bit scaling to guarantee no overflow regardless of loudness of each channel in the track.
the additional possible carry generated by this addition gives the output some additional "dither noise" which can aid in covering up some imperfections giving its own imperfections as well :-)
the music driver
at the end of all this, a music driver had been produced which only requires an initialisation and then requires an update per frame in irq. The whole kaos track packed took up only 28k (from a 150k mod)
why is the quality so bad
For what it does in a very small size (28k) (from a 150k mod) and the tasks involved + running it in a single file on a c64, several compromises obviously had to be made. Some reasons for degradation as follows
original samples were not good in quality
Listen to the original samples in the KAOS track, and you will indeed hear that they are pretty rough sounding in nature
samples are resampled to 8400hz
most of the samples are way above 8400hz in the original. These required resampling to fit the c64's playback rate in the mixer to 8400hz
VQ packed samples
dont expect a quick and fast solution that packs to a quarter of the size to give any miracles. (Even though my VQ encoder works in a similar way to CSAM and refines entries, it cant give lossless perception at this 4:1 rate)
6bit scaled signed samples. from -128 to +127 in the original scaling it down to -32 to +31 will no doubt generate worse quality resolution and even further when volume adjustments are made to this further (reduction in volume)
sample playback method
the method uses a direct write to d418 with sid pre-setup which can give higher than 6bits output (instead of 4bits) using d418. This is not perfectly linear, hence there will be quality loss issues. Also the mixing in the end produces 8bit sample output and this would then need to be translated back to the non-linear 6bit which gives further quality loss (+ it can vary dependant on sid revision)
Taking into account the above quality loss issues, it still manages to generate samples that are better then expected
Why this, when there is THCM's player
THCM's decoder/player is specifically crafted to be fully 100% mod compatible with all commands supported. If you want full mod compatibility, then THCM's one is the choice. As samples are unpacked raw, these will either need to be resampled to low rates or to use small size samples.
My players' purpose is completely different. IT is meant for playing back very large amount of samples in a smaller ram space with "some" very basic mod support (e.g placement of samples, some volume control, looping etc). If you want the possibility to playback 160k worth of samples in ram at one time and track these together, this is the player of choice. With some work, it is possible to recreate large size mods nearly 1:1 while only using less than a quarter of its original size.
As the cpu usage is proportional to the amount of channels, the composer can use specific amount of channels during sections in a demo where cpu usage is required more for a certain part, hence the dynamic mixing can have quite some advantage when used correctly.
tech specs and limitations
full 4 channel tracked samples with realtime vq decompression on the fly for each sample.
4 volume levels per sample (0%,33%,66%,100%)
gating (pulsing effects to zero at variable speed
6bit samples mixed to 8bit and output via amplitude table
no pitch adjustment (costly for cpu when VQ per channel is involved)
each sample 6bits (to allow for fast mixing). This can affect clarity in particular when low volume levels are in the sample or low volume is selected as a parameter for the sample.
As the pop out effects can occur at any time in the song, I needed to take into account the worst case scenario for free cpu time.
It would have been trivial in cpu time to place images and then flip them when required via dd00/d018, but as ram space was rather limited for the other effects, this is plotted inplace.
the "vectors" - precalculated csam, is packed using rle and depacked on the fly. The others are just some color adjustments and plotting. I wanted to make it as close to the amiga original hence no other extra effects.
· Hidden Parts
|Info on other sites|