+OLD CS1 Posted November 25, 2017 Share Posted November 25, 2017 This is an abridged work-in-progress conversion of the Commodore 64 music from 1942 by Mark Cooksey. The Commodore 64 is one of the only home computer conversions of the game which has music. The C64 music is three minutes and four seconds long due to a LOT of repeated segments. This skeletal release is not that long as it only has each segment play once, with a short repeat of the first couple of segments, and no segue from the full song end to beginning. The final product will have some tremolo and vibrato in appropriate spots, and I have been working up new parts of my manipulation script to output VGM modules and data compatible with Tursi's VGMPlayer. The script parts are not perfected yet but getting closer to producing usable output. Anyway, I hope you enjoy my musical rendition. 1942 title music on TMS-9919 (newer version in later post) 1942_parts1-2(nb)(abridged)(wip)(adj).mp3 Original C64 SID music (full length clipped at song repeat segue) 1942(subtune_1).mp3 3 Quote Link to comment Share on other sites More sharing options...
Asmusr Posted November 25, 2017 Share Posted November 25, 2017 Very nice. So this is played using Tursi's VGM player? Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted November 25, 2017 Author Share Posted November 25, 2017 Very nice. So this is played using Tursi's VGM player? Thank you. It is not, yet. This is ISR format played by your SoundListRipper. My Rexx script for manipulating sound list binaries now outputs VGM and VGMPlayer data, BUT so far neither produces working output (they are both quick-n-dirty write-ups.) I will be working on them. Quote Link to comment Share on other sites More sharing options...
Tursi Posted November 26, 2017 Share Posted November 26, 2017 Sounding nice! Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted November 26, 2017 Author Share Posted November 26, 2017 Thanks. Here is another quick put-together. I lengthened the song by adding another repeated middle and the last verse/segue with a full repeat. I am done with it for now until I add a little more body. It will definitely benefit from conversion as even with just the individual patterns it runs about 4k (soooo much repeated data.) I will also increase attenuation a little. Everything is "0" right now, and to avoid popping between notes I use 14 rather than 15. This makes the space between notes a little fuller and gives an echo-like quality in some places. 1942(nb)(abridged)(wip-IABCDABCDE)(adj).mp3 2 Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted December 16, 2017 Author Share Posted December 16, 2017 Give this a try. 1942.vgm My problem was trying to use v1.01 VGM spec. Changed to v1.10 and AudioOverload plays output files properly. For any Rexx geeks, the procedure to produce is below where the stem variable sound_list contains rows of sound data in ISR format, and leaf 0 contains the number of rows. I originally sent the variable vgmcmd directly to the file but I had to prepare for the "Total # samples" field at 0x18 to be required, so I build a new stem variable vgmstring to output after the modified header if necessary (along with the unused vgmlength variable.) (EDIT: using another song I found the code below does not handle durations longer than 89 jiffies, resulting in a wait longer than 65536 ticks. I will fix this in my next iteration.) save_vgm: procedure expose sound_list. parse arg filename if filename = '' then do say 'Output filename must be given to save sound list as a VGM.' return 30 end if ~open(filename, filename, 'w') then return 50 vgmheader = 'Vgm '||'00 00 00 00 10 01 00 00 94 9e 36 00'x vgmheader = vgmheader||copies('00'x,20)||'3c 00 00 00 09'x vgmheader = vgmheader||copies('00'x,23) vgmstring. = '' vgmlength = 0 do row = 1 to sound_list.0 duration = c2d(right(sound_list.row, 1)) select when duration == 0 then break when duration < 3 then vgmwait = copies('62'x, duration) otherwise do duration = duration * 735 vgmwait = '61'x || reverse(d2c(duration)) end end vgmcmd = '' do vgmbyte = 1 to c2d(left(sound_list.row, 1)) vgmcmd = vgmcmd || 'P' || substr(sound_list.row, vgmbyte+1, 1) end vgmstring.row = vgmcmd || vgmwait end vgmstring.row = vgmstring.row || '66'x vgmstring.0 = vgmheader do vgmrow = 0 to row select when arch=='ARexx' then call writech filename, vgmstring.vgmrow otherwise call charout filename, vgmstring.vgmrow end end call close filename return 0 1 Quote Link to comment Share on other sites More sharing options...
Asmusr Posted December 16, 2017 Share Posted December 16, 2017 VGMPlay says "Warning! Invalid EOF Offset 0x00! (should be: 0x1D01)". It plays, but it doesn't know the duration. Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted December 16, 2017 Author Share Posted December 16, 2017 VGMPlay says "Warning! Invalid EOF Offset 0x00! (should be: 0x1D01)". It plays, but it doesn't know the duration. Bah... I am prepared for that but hoped I could avoid it. Bloody standards, though the spec says this field is "mainly used to find the next track when concatanating player stubs and multiple files." Also, I just found that VLC Player will play VGMs, and it plays the ones I am generating without a fuss (except P3 noises are out of tune.) EDIT: I assume it stops playing and the duration is just for display sake, correct? I terminate the file with the required 0x66 command. Quote Link to comment Share on other sites More sharing options...
Asmusr Posted December 16, 2017 Share Posted December 16, 2017 EDIT: I assume it stops playing and the duration is just for display sake, correct? I terminate the file with the required 0x66 command. Yes it stops. Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted December 17, 2017 Author Share Posted December 17, 2017 This VGM has the EOF offset fixed and VGMPlay recognizes it properly (no errors) but still does not show the duration, probably because of the missing number of wait fields*. I had to set values of other PSG-related fields at 0x28 (SN76489 feedback) and 0x2A (SN76489 shift register width,) values 0x06 and 0x10, respectively. It still does not sound correct in VLC Player. Too bad. I also attached a GD3 tag which displays fine in AudioOverload but not in VGMPlay. 1942_eof-fix_gd3.vgm * Well, this gives a hint: Warning! Header Samples: 0 Counted Samples: 3442740 Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted December 17, 2017 Author Share Posted December 17, 2017 Last update. This has the "EoF offset," "Total # samples," and necessary PSG values, plus a GD3 tag. The GD3 tag still does not show in VGMPlay, and AudioOverload seems to ignore the "notes" element and just displays the title, again. 1942_994a.vgm Again for the Rexx nerds, below is the working and cleaned up script excerpt. /* save_vgm */ save_vgm: procedure expose sound_list. parse arg filename if filename == '' then do say 'Output filename must be given to save sound list as a VGM.' return 30 end if ~open(filename, filename, 'w') then return 50 vgmheader = 'Vgm '||'00 00 00 00 10 01 00 00 94 9e 36 00'x vgmheader = vgmheader||copies('00'x,20)||'3c 00 00 00 06 00 10 00'x vgmheader = vgmheader||copies('00'x,20) vgmstring. = '' vgmlength = 0 vgmsamples = 0 do row = 1 to sound_list.0 duration = c2d(right(sound_list.row, 1)) * 735 vgmsamples = vgmsamples + duration select when duration == 0 then leave when duration < 1471 then vgmwait = copies('b', duration / 735) /* 0x62 */ otherwise vgmwait = 'a' || reverse(d2c(duration)) /* 0x61 */ end vgmcmd = '' do vgmbyte = 1 to c2d(left(sound_list.row, 1)) vgmcmd = vgmcmd || 'P' || substr(sound_list.row, vgmbyte+1, 1) /* 0x50 */ end vgmstring.row = vgmcmd || vgmwait vgmlength = vgmlength + length(vgmstring.row) end vgmheader = overlay(reverse(d2c(vgmlength + 61)), vgmheader, 5) /* length in bytes */ vgmheader = overlay(reverse(d2c(vgmsamples)), vgmheader, 25) /* length in samples */ vgmstring.row = 'f' /* 0x66 terminator byte */ vgmstring.0 = vgmheader /* header */ do vgmrow = 0 to row select when arch=='ARexx' then call writech filename, vgmstring.vgmrow otherwise call charout filename, vgmstring.vgmrow end end call close filename return 0 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.