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


Forums > CSDb Discussions > Track Times in SID files?
2011-02-17 21:33
pmprog
Account closed

Registered: Nov 2005
Posts: 54
Track Times in SID files?

I've always wondered this, but why doesn't any of the SID file formats support a track time.

A couple of extra bytes per subtune per SID wouldn't be a huge loss, and it would mean any individual player doesn't need access to the 3MB file from HVSC to correctly know when to move on to the next track.

Given the database exists, it would also be pretty easy to write a program to go through all the files in HVSC, check if they match whichever SID file format supports the tracks times, and updates them with the tune lengths from the text file.

Does that not seem a good idea?
 
... 68 posts hidden. Click here to view all posts....
 
2011-03-01 16:48
MagerValp

Registered: Dec 2001
Posts: 1074
OK, cool.

Just for fun though I spent a lunch break adding chunks to sid files, but I got stuck on the md5 checksum in songlengths.txt. How is that calculated? The checksums in songlengths.txt is different from what I get if I hash the file with /sbin/md5 or python's hashlib.md5(). I also tried hashing just the raw sid data, but that didn't work either.
2011-03-01 19:34
Steppe

Registered: Jan 2002
Posts: 1510
The whole core of the MD5 code is very small:

        // Include C64 data.
        myMD5.append(cache.get()+fileOffset,info.c64dataLen);
        unsigned char tmp[2];

        // Include INIT and PLAY address.
        writeLEword(tmp,info.initAddr);
        myMD5.append(tmp,sizeof(tmp));
        writeLEword(tmp,info.playAddr);
        myMD5.append(tmp,sizeof(tmp));
        // Include number of songs.
        writeLEword(tmp,info.songs);
        myMD5.append(tmp,sizeof(tmp));
        // Include song speed for each song.
        for (unsigned int s = 1; s <= info.songs; s++)
        {
            selectSong(s);
            myMD5.append(&info.songSpeed,sizeof(info.songSpeed));
        }
        // Deal with PSID v2NG clock speed flags: Let only NTSC
        // clock speed change the MD5 fingerprint. That way the
        // fingerprint of a PAL-speed sidtune in PSID v1, v2, and
        // PSID v2NG format is the same.
        if ( info.clockSpeed == SIDTUNE_CLOCK_NTSC )
            myMD5.append(&info.clockSpeed,sizeof(info.clockSpeed));

        // NB! If the fingerprint is used as an index into a
        // song-lengths database or cache, modify above code to
        // allow for PSID v2NG files which have clock speed set to
        // SIDTUNE_CLOCK_ANY. If the SID player program fully
        // supports the SIDTUNE_CLOCK_ANY setting, a sidtune could
        // either create two different fingerprints depending on
        // the clock speed chosen by the player, or there could be
        // two different values stored in the database/cache.


And here's some clarification from Wilfred about this:

But the "selectSong(s)" is the not trivial part of the whole calculation which sets the songSpeed for every song.

If you convert the selectSong method in the loop, for the things needed for the MD5 calculation, you will get:

   uint8 u8CiaSpeed = 60;
   uint8 u8VblSpeed = 0;

   for (i = 0; I < u16NumSongs; i++) {
      if (!boPSIDSpecific) {
        if (i < 31)  // check tune 0-30 (bit 0 - 30)
          boVbiSpeed = !(u32Speed & (1 << i));
        else
          boVbiSpeed = !(u32Speed & (1 << 31));// last bit sets speed for tunes >31
      } else {
        // old PlaySID implementation
        boVbiSpeed = !(u32Speed & (1 << (i % 32)));
      }

      // speed setting
      if (boVbiSpeed)
        md5_append(&u8VblSpeed, 1);
      else
        md5_append(&u8CiaSpeed, 1);
   }



Hope that helps, I don't understand a line of what's written up there. :-/
2011-03-01 19:36
Radiant

Registered: Sep 2004
Posts: 639
MagerValp: If you can figure it out, pray tell - nobody seems to know for sure. :-)
2011-03-01 19:52
Steppe

Registered: Jan 2002
Posts: 1510
From what I gathered this is Delphi code. There also exists a C conversion of this. I'm sure Wilfred Bos will be available if you need help.
2011-03-01 20:12
Mr. SID

Registered: Jan 2003
Posts: 424
It's not pretty code, but it's simple enough once you think about it. The complexity really comes from the way the speed flags work in the PSID header, which is a huge mess and limited to 32 songs too.
2011-03-01 20:31
MagerValp

Registered: Dec 2001
Posts: 1074
OK, so here's my attempt at converting it to Python:
    m = hashlib.md5()
    m.update(sid_data)
    m.update(struct.pack("<H", sid_header[HDR_INITADDRESS]))
    m.update(struct.pack("<H", sid_header[HDR_PLAYADDRESS]))
    m.update(struct.pack("<H", sid_header[HDR_SONGS]))
    for i in range(sid_header[HDR_SONGS]):
        if sid_header[HDR_SPEED] & (1<<i):
            m.update(chr(60))
        else:
            m.update(chr(0))
Something's not right though, as the checksum still doesn't match (and I'm testing with a PAL tune with less than 32 subtunes).
2011-03-01 23:37
MagerValp

Registered: Dec 2001
Posts: 1074
The missing detail was that you need to skip the load address when calculating the md5 sum:
    m = hashlib.md5()
    m.update(sid_data[2:])
    m.update(struct.pack("<H", sid_header[HDR_INITADDRESS]))
    m.update(struct.pack("<H", sid_header[HDR_PLAYADDRESS]))
    m.update(struct.pack("<H", sid_header[HDR_SONGS]))
    for i in range(sid_header[HDR_SONGS]):
        if sid_header[HDR_SPEED] & (1<<i):
            m.update(chr(60))
        else:
            m.update(chr(0))
Now for the rest...
2011-03-02 00:13
MagerValp

Registered: Dec 2001
Posts: 1074
And here we go:
    sid_header = unpack_header(data)
    sid_version = sid_header[HDR_VERSION]
    sid_data = data[sid_header[HDR_DATAOFFSET]:]
    m = hashlib.md5()
    m.update(sid_data[2:])
    m.update(struct.pack("<H", sid_header[HDR_INITADDRESS]))
    m.update(struct.pack("<H", sid_header[HDR_PLAYADDRESS]))
    m.update(struct.pack("<H", sid_header[HDR_SONGS]))
    for i in range(sid_header[HDR_SONGS]):
        if sid_header[HDR_MAGIC] == "RSID":
            m.update(chr(60))
        else:
            if sid_header[HDR_SPEED] & (1<<min(i, 31)):
                m.update(chr(60))
            else:
                m.update(chr(0))
    if sid_version == 2:
        if (sid_header[HDR_FLAGS] & 0x0c) == 0x08:
            m.update(chr(2))
That is one seriously fugly algorithm...
2011-03-02 16:04
MagerValp

Registered: Dec 2001
Posts: 1074
So in case anyone's still playing with this, here's what my tools spits out now:
/MUSICIANS/J/JCH/Tecnetium.sid
{'COMM': 'I always get mixed feelings when I play this
  music. The title- tune is\nlong and I put a lot of work
  into it in april 1989, but today I can\nhear loads of
  harmonic errors here and there. The game was done for
  a\nsideways shoot\'em up which a couple of totally
  unknown danish guys was\nmaking. They soon lost all
  interest in their game, however. The\nhiscore theme was a
  conversion of the old Cliff Richard
  hit\n"Congratulations" done right out my head. I always
  wanted to make such\na hiscore tune, because I always
  thought Rob Hubbard did it all wrong\nwhen he made "sad"
  hiscore tunes. It is a sad thing when the game\nends, but
  getting a high score is supposed to be a GOOD thing! :)',
 'TUNS': [{'LENG': 23330816, 'NAME': 'Title Screen'},
          {'ARTI': 'Cliff Richard',
           'LENG': 5963776,
           'TITL': 'Congratulations'},
          {'LENG': 262144},
          {'LENG': 196608},
          {'LENG': 2883584},
          {'LENG': 65536, 'LOOP': 'G'},
          {'LENG': 196608, 'LOOP': 'G'},
          {'LENG': 65536, 'LOOP': 'G'},
          {'LENG': 65536, 'LOOP': 'G'},
          {'LENG': 65536, 'LOOP': 'G'},
          {'LENG': 65536, 'LOOP': 'G'},
          {'LENG': 65536, 'LOOP': 'G'},
          {'LENG': 65536, 'LOOP': 'G'},
          {'LENG': 65536, 'LOOP': 'G'},
          {'LENG': 196608, 'LOOP': 'G'},
          {'LENG': 131072, 'LOOP': 'G'},
          {'LENG': 65536, 'LOOP': 'G'},
          {'LENG': 65536, 'LOOP': 'G'}]}

Supported chunks are:
TITL: Title
ARTI: Artist
AUTH: Author
NAME: Name
COMM: Comment
BUGS: Text from buglist
TUNS: List of subtunes
LENG: Song length as 16.16 fp
LOOP: Loop flag
2011-03-02 16:45
MagerValp

Registered: Dec 2001
Posts: 1074
Oh, and just to keep the monologue going: attaching chunks to the end of SIDv2 files will break backwards compatibility with songlengths.txt, as the checksum is calculated from all data after the header. That kills the idea, so to extend the file format beyond what was done with v3 (stereo sid and zero termination) we'll need a new file format.
Previous - 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 - Next
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
CyberBrain/NoName
DeeKay/Crest
juN3bula/N3U
Magnar
Guests online: 88
Top Demos
1 Next Level  (9.7)
2 13:37  (9.7)
3 Coma Light 13  (9.7)
4 Edge of Disgrace  (9.6)
5 Mojo  (9.6)
6 Uncensored  (9.6)
7 Wonderland XIV  (9.6)
8 Comaland 100%  (9.6)
9 Fishbomb  (9.6)
10 No Bounds  (9.6)
Top onefile Demos
1 Layers  (9.6)
2 Party Elk 2  (9.6)
3 Cubic Dream  (9.6)
4 Copper Booze  (9.6)
5 Libertongo  (9.5)
6 Rainbow Connection  (9.5)
7 Onscreen 5k  (9.5)
8 Morph  (9.5)
9 Dawnfall V1.1  (9.5)
10 It's More Fun to Com..  (9.5)
Top Groups
1 Performers  (9.3)
2 Booze Design  (9.3)
3 Oxyron  (9.3)
4 Nostalgia  (9.3)
5 Censor Design  (9.3)
Top Swappers
1 Derbyshire Ram  (10)
2 Jerry  (9.8)
3 Violator  (9.7)
4 Acidchild  (9.7)
5 Cash  (9.6)

Home - Disclaimer
Copyright © No Name 2001-2024
Page generated in: 0.043 sec.