Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
You are not logged in 
CSDb User Forums


Forums > CSDb Entries > Release id #173684 : Wir sind die Nacht
2019-01-24 00:33
ChristopherJam

Registered: Aug 2004
Posts: 901
Release id #173684 : Wir sind die Nacht

Some technical details about this intro (copied from Production Notes for ease of discussion/better visibility, with minor memory map corrections)


The data hierarchy for the music is as follows:
- A song is a list of segments from the original track.
- A segment is broken into list of slices
- A slice is composed of up to 255 blocks (this way slice playback doesn't have to handle page crossings)
- Each block represents six samples as an 8 bit index into a palette of deltas

All of the segments share a single 256 entry palette; each palette entry contains six delta values
A slice contains a starting sample value, then up to 255 palette indices.

so, total size (excluding sequence information) is roughly 1.5k+nsamples/6

There are eight unique segments, with a total duration of 8.54 seconds. At a sample rate of 7819Hz (one sample every two raster lines), that's 66786 samples. I lose around 70 bytes to padding when dividing the segments into slices that don't cross page boundaries, so the total block storage is 11,201 bytes

The slice playback routine is a CIA interrupt scheduled to ensure block boundaries never clash with character DMA. Everything else runs in main, including updating the pointer to the next slice whenever the previous one has commenced playback.

- The blocks are decrunched to the end of zero page, one block every 12 raster lines.
- The encoder performs carry prediction/compensation, so there's only one CLC required to decode each block.
- The sample playback method is Mahoney's; I've lifted the initialisation code directly from the Musik RunStop technical details, and built my own translation tables from his measurement data (thanks Pex!)


Scroller font was originally a 5x2 heavily based on Blackmoor LET. I did a lot of hand pixelling to try and get it to look nice in the available cset space, but then I had to squash it down to a 4x2 at the last minute when I didn't have enough ram for the table that contains the char indices for each glyph.


Most of the initialisation code is overwritten by a second decrunch pass once initialisation is complete.

Approximate memory map is as follows:

init time:

0x4000..0x6bc1 sampledata.prg (one byte per six samples)
0x6bc2..0x6bf4 sd.prg         (some sequence data that didn't fit into main.prg)
0x6c00..0x6c64 tc.prg         (tinycrunch. Overwritten with 'rasterbar' characters after it's done with)
0x6c64..0x6e23 init.prg       (SID detection, sample and music playback init, VIC init, scrolltext load location)
0x6ed0..0x6fc7 pextable6.prg  (sample translation table for 6581)
0x6fd0..0x70c7 pextable8.prg  (sample translation table for 8580)
0x710f..0x7530 art_tc.prg     (tinycrunched artwork. Overwrites 6c78..7530)
0x7531..0x79ea main.prg       (effect code, music playback, and sequence data)
0x7a00..0x8000 vqpalette.prg  (six deltas per palette entry)

run time:

0x0002..0x00f4 pextable
0x00fa..0x00ff current sample block
0x0100..0x01dd scrolltext
0x01f8..0x01ff stack

0x4000..0x6bc1 sampledata.prg
0x6bc2..0x6bf4 sd.prg
0x6c78..0x6fe8 screen
0x7000..0x7270 clogo.prg   # 78 logo chars
0x7270..0x7530 cfont.prg   # 85 font chars
0x7538..0x7578 8 char defs for the fake rasters
0x7531..0x79ea main.prg (but first 71 bytes get trashed by fake rasters after main loop is entered)
0x7a00..0x8000 vqpalette.prg
2019-01-24 10:55
Oswald

Registered: Apr 2002
Posts: 4365
why arent blocks 8 samples long ? whats the average error per sample ? how are slices packed, and whats the typical slice size ? could you reuse slices ? what would be the first thing you'd do to increase quality ?
2019-01-24 17:38
ChristopherJam

Registered: Aug 2004
Posts: 901
The longer the block, the worse the errors. Block size of 4, and I was getting better quality than 2 bits per sample ADPCM (at least for single segments). Block size of 6, and the quality was a little worse but still tolerable.

Odd block sizes are annoying to implement, as it's harder to dodge badlines.

RMS error usually varies from 1 to 5 depending on the segment. I'd do better if I had a separate 1.5k palette for each category of segment (eg one for vocals, another for percussion heavy segments, a third for more bassy stuff)

Slices are mostly 255 blocks long, segments 3-15 slices. There's a minimum slice length of around 28 blocks, as I only update the "next slice" pointer once per frame. So, I just finish the last partial page (assuming more than 28 blocks free), then grab 255 blocks at a time until the slice is exhausted, splitting the last fragment slightly earlier if required to avoid the final slice being too short.

Yes, one could reuse slices.

First thing I'd do to improve quality is either break out multiple palettes, as mentioned above, or drop the block size back down to 4 samples.

Log from crunching the first three segments:
slice  0/ 2 (from 0x0000 to 0x00ff of 0x0000-0x01d9) (255 bytes, rms(err)= 1.493) saving to 0000-00ff
slice  1/ 2 (from 0x00ff to 0x01d9 of 0x0000-0x01d9) (218 bytes, rms(err)= 1.504) saving to 0100-01da
slice  0/13 (from 0x0000 to 0x0026 of 0x0000-0x0c08) ( 38 bytes, rms(err)= 9.024) saving to 01da-0200  (!!!)
slice  1/13 (from 0x0026 to 0x0125 of 0x0000-0x0c08) (255 bytes, rms(err)= 5.192) saving to 0200-02ff
slice  2/13 (from 0x0125 to 0x0224 of 0x0000-0x0c08) (255 bytes, rms(err)= 3.966) saving to 0300-03ff
slice  3/13 (from 0x0224 to 0x0323 of 0x0000-0x0c08) (255 bytes, rms(err)= 3.912) saving to 0400-04ff
slice  4/13 (from 0x0323 to 0x0422 of 0x0000-0x0c08) (255 bytes, rms(err)= 4.269) saving to 0500-05ff
slice  5/13 (from 0x0422 to 0x0521 of 0x0000-0x0c08) (255 bytes, rms(err)= 4.622) saving to 0600-06ff
slice  6/13 (from 0x0521 to 0x0620 of 0x0000-0x0c08) (255 bytes, rms(err)= 3.897) saving to 0700-07ff
slice  7/13 (from 0x0620 to 0x071f of 0x0000-0x0c08) (255 bytes, rms(err)= 3.598) saving to 0800-08ff
slice  8/13 (from 0x071f to 0x081e of 0x0000-0x0c08) (255 bytes, rms(err)= 2.943) saving to 0900-09ff
slice  9/13 (from 0x081e to 0x091d of 0x0000-0x0c08) (255 bytes, rms(err)= 2.832) saving to 0a00-0aff
slice 10/13 (from 0x091d to 0x0a1c of 0x0000-0x0c08) (255 bytes, rms(err)= 3.103) saving to 0b00-0bff
slice 11/13 (from 0x0a1c to 0x0b1b of 0x0000-0x0c08) (255 bytes, rms(err)= 2.442) saving to 0c00-0cff
slice 12/13 (from 0x0b1b to 0x0c08 of 0x0000-0x0c08) (237 bytes, rms(err)= 2.373) saving to 0d00-0ded
slice  0/ 7 (from 0x0000 to 0x00ff of 0x0000-0x067a) (255 bytes, rms(err)= 2.343) saving to 0e00-0eff
slice  1/ 7 (from 0x00ff to 0x01fe of 0x0000-0x067a) (255 bytes, rms(err)= 2.007) saving to 0f00-0fff
slice  2/ 7 (from 0x01fe to 0x02fd of 0x0000-0x067a) (255 bytes, rms(err)= 1.980) saving to 1000-10ff
slice  3/ 7 (from 0x02fd to 0x03fc of 0x0000-0x067a) (255 bytes, rms(err)= 1.654) saving to 1100-11ff
slice  4/ 7 (from 0x03fc to 0x04fb of 0x0000-0x067a) (255 bytes, rms(err)= 1.330) saving to 1200-12ff
slice  5/ 7 (from 0x04fb to 0x05fa of 0x0000-0x067a) (255 bytes, rms(err)= 1.334) saving to 1300-13ff
slice  6/ 7 (from 0x05fa to 0x067a of 0x0000-0x067a) (128 bytes, rms(err)= 1.167) saving to 1400-1480
2019-01-24 17:52
Oswald

Registered: Apr 2002
Posts: 4365
Quote: The longer the block, the worse the errors. Block size of 4, and I was getting better quality than 2 bits per sample ADPCM (at least for single segments). Block size of 6, and the quality was a little worse but still tolerable.

Odd block sizes are annoying to implement, as it's harder to dodge badlines.

RMS error usually varies from 1 to 5 depending on the segment. I'd do better if I had a separate 1.5k palette for each category of segment (eg one for vocals, another for percussion heavy segments, a third for more bassy stuff)

Slices are mostly 255 blocks long, segments 3-15 slices. There's a minimum slice length of around 28 blocks, as I only update the "next slice" pointer once per frame. So, I just finish the last partial page (assuming more than 28 blocks free), then grab 255 blocks at a time until the slice is exhausted, splitting the last fragment slightly earlier if required to avoid the final slice being too short.

Yes, one could reuse slices.

First thing I'd do to improve quality is either break out multiple palettes, as mentioned above, or drop the block size back down to 4 samples.

Log from crunching the first three segments:
slice  0/ 2 (from 0x0000 to 0x00ff of 0x0000-0x01d9) (255 bytes, rms(err)= 1.493) saving to 0000-00ff
slice  1/ 2 (from 0x00ff to 0x01d9 of 0x0000-0x01d9) (218 bytes, rms(err)= 1.504) saving to 0100-01da
slice  0/13 (from 0x0000 to 0x0026 of 0x0000-0x0c08) ( 38 bytes, rms(err)= 9.024) saving to 01da-0200  (!!!)
slice  1/13 (from 0x0026 to 0x0125 of 0x0000-0x0c08) (255 bytes, rms(err)= 5.192) saving to 0200-02ff
slice  2/13 (from 0x0125 to 0x0224 of 0x0000-0x0c08) (255 bytes, rms(err)= 3.966) saving to 0300-03ff
slice  3/13 (from 0x0224 to 0x0323 of 0x0000-0x0c08) (255 bytes, rms(err)= 3.912) saving to 0400-04ff
slice  4/13 (from 0x0323 to 0x0422 of 0x0000-0x0c08) (255 bytes, rms(err)= 4.269) saving to 0500-05ff
slice  5/13 (from 0x0422 to 0x0521 of 0x0000-0x0c08) (255 bytes, rms(err)= 4.622) saving to 0600-06ff
slice  6/13 (from 0x0521 to 0x0620 of 0x0000-0x0c08) (255 bytes, rms(err)= 3.897) saving to 0700-07ff
slice  7/13 (from 0x0620 to 0x071f of 0x0000-0x0c08) (255 bytes, rms(err)= 3.598) saving to 0800-08ff
slice  8/13 (from 0x071f to 0x081e of 0x0000-0x0c08) (255 bytes, rms(err)= 2.943) saving to 0900-09ff
slice  9/13 (from 0x081e to 0x091d of 0x0000-0x0c08) (255 bytes, rms(err)= 2.832) saving to 0a00-0aff
slice 10/13 (from 0x091d to 0x0a1c of 0x0000-0x0c08) (255 bytes, rms(err)= 3.103) saving to 0b00-0bff
slice 11/13 (from 0x0a1c to 0x0b1b of 0x0000-0x0c08) (255 bytes, rms(err)= 2.442) saving to 0c00-0cff
slice 12/13 (from 0x0b1b to 0x0c08 of 0x0000-0x0c08) (237 bytes, rms(err)= 2.373) saving to 0d00-0ded
slice  0/ 7 (from 0x0000 to 0x00ff of 0x0000-0x067a) (255 bytes, rms(err)= 2.343) saving to 0e00-0eff
slice  1/ 7 (from 0x00ff to 0x01fe of 0x0000-0x067a) (255 bytes, rms(err)= 2.007) saving to 0f00-0fff
slice  2/ 7 (from 0x01fe to 0x02fd of 0x0000-0x067a) (255 bytes, rms(err)= 1.980) saving to 1000-10ff
slice  3/ 7 (from 0x02fd to 0x03fc of 0x0000-0x067a) (255 bytes, rms(err)= 1.654) saving to 1100-11ff
slice  4/ 7 (from 0x03fc to 0x04fb of 0x0000-0x067a) (255 bytes, rms(err)= 1.330) saving to 1200-12ff
slice  5/ 7 (from 0x04fb to 0x05fa of 0x0000-0x067a) (255 bytes, rms(err)= 1.334) saving to 1300-13ff
slice  6/ 7 (from 0x05fa to 0x067a of 0x0000-0x067a) (128 bytes, rms(err)= 1.167) saving to 1400-1480


maybe next time block size of 4, and mixing a few channels for some music action ? :) using it for instruments should also improve quality as you will know what type of palette to use for each.
2019-01-24 18:21
ChristopherJam

Registered: Aug 2004
Posts: 901
Yes, that sounds like a plan. Maybe just blank the screen or use a DMA free mode, mind..
2019-01-24 19:51
dano

Registered: Jul 2004
Posts: 171
Sorry for the OT, but why does it say "<Message ignored>" with Christophers's messages here? Did i press some wrong button?!
2019-01-24 19:55
Groepaz

Registered: Dec 2001
Posts: 9033
you clicked on "ignore all messages from this user" =)
2019-01-24 19:58
dano

Registered: Jul 2004
Posts: 171
thx! damn you tiny screen, must have happened some time somehow ^^. back to samples!
RefreshSubscribe to this thread:

You need to be logged in to post in the forum.

Search the forum:
Search   for   in  
All times are CET.
Search CSDb
Advanced
Users Online
Sentinel/Excess
markus sinalco
Moloch/TRIAD
swasti
JCH/Vibrants
Compyx/Focus
0xDB/NOOP
Scan/House Designs
Guests online: 69
Top Demos
1 Unboxed  (9.7)
2 Uncensored  (9.7)
3 Edge of Disgrace  (9.7)
4 Coma Light 13  (9.6)
5 Comaland 100%  (9.6)
6 The Shores of Reflec..  (9.6)
7 Lunatico  (9.6)
8 C=Bit 18  (9.6)
9 Wonderland XII  (9.5)
10 X Marks the Spot  (9.5)
Top onefile Demos
1 Smile to the Sky  (9.6)
2 Daah, Those Acid Pil..  (9.5)
3 Dawnfall V1.1  (9.4)
4 FMX Music Demo  (9.4)
5 Crystal Gazer  (9.4)
6 Rewind  (9.4)
7 Pandemoniac Part 2 o..  (9.4)
8 Official X2018 Report  (9.4)
9 Arok 20 Invitation  (9.4)
10 Party Horse  (9.3)
Top Groups
1 PriorArt  (9.7)
2 Performers  (9.5)
3 Oxyron  (9.5)
4 Booze Design  (9.4)
5 Censor Design  (9.3)
Top Hardware-Gurus
1 Soci  (9.9)
2 Wiesel  (9.9)
3 Grue  (9.8)
4 Zer0-X  (9.8)
5 Lemming  (9.7)

Home - Disclaimer
Copyright © No Name 2001-2019
Page generated in: 0.058 sec.