SIDcog - The sound of the Commodore 64 ! (Now in the OBEX)



  • Ahle2Ahle2 Posts: 976
    edited 2014-11-02 - 23:59:05
    "Do you recall what you used to create the music byte DATA itself?"
    Propeller Tool + patience!

    "I was able to determine that your note2freq routine appears to be using a midi note scale"
    That is what I recall as well, but I was not sure!

    I am developing "Midi to .rmu" support in the Retrontius editor. The hard part is not to convert notes, the hard part is to quantize, multiplex and prioritize notes... :)

  • pik33pik33 Posts: 792
    edited 2014-11-10 - 09:14:21
    Ahle2 wrote: »
    The pseudo code for the multi mode 6db/octave filter looks like this!
    [B]Each sample:[/B]
        filter_H  = input_sample - filter_B * filter_resonance - filter_L      
        filter_B += filter_freq * filter_H
        filter_L += filter_freq * filter_B

    filter_H = Highpass filtered sample
    filter_B = Bandpass filtered sample
    filter_L = Lowpass filtered sample
    filter_freq = Cutoff frequency ( a value between 0 - 1, max freq = sample_rate/2 )
    filter_resonance = Resonance amount ( a value between 0 - 1 )
    input_sample = The incoming sample

    If you for an instance want a bandpass filtered sample use: output_sample = filter_B
    If you for an instance want a bandpass reject filter use: output_sample = filter_L + filter_H

    The logarithmic envelope decay function works like this
    [B]Each frame:[/B]
      amplitude_level-= decay_rate
      if amplitude_level < reference_level
        decay_rate /= 2
        reference_level /= 2

    Post Edited (Ahle2) : 1/30/2010 3:39:36 PM GMT

    I tested these filters because (1) I am patching sidcog for my de2-115 retromachine (2) I need a filters for the other purpose.

    Low pass and high pass filter made with this algorithm are 12 dB/octave, and not 6!
    The band pass filter is 6 dB/octave.

    This is exactly what the SID has, so there is no need to add second filter bank.

    If the SID's filter is as in the Commodore 64 instructions - 30 Hz+5.8*amount - then @ 44100 Hz the amount should be divided by 1223 and then be no more than 1200 - the filter characteristic is non linear.

    But as I saw some SID filter characteristics, they are nonlinear, too :) and no two sids are the same.

    At 44100Hz sampling, the band pass frq is 355 Hz for 0.05, 720 Hz for 0.1, 1485 for 0.2, 3220 for 0.4, 5430 for 0.6, 9010 for 0.8 and 13050 Hz for 0.9 (then 22050 Hz for 1.0)
  • Ahle2Ahle2 Posts: 976
    edited 2014-11-10 - 11:14:24
    The filter implementation was made in 2009, and I don't remember all the details (because I haven't done any changes to the code since then, just parameter changes). What I do remember is that A LOT of short cuts had to be made because the Propeller lacks a multiplication instruction. I was extremely satisfied that I was able to squeeeze the filter in at all. (without sacrificing too many cycles) Shifts are used instead of multiplications in some cases and there are other short cuts as well. (5 years are too long ago to remember all the short cuts) The pseudo code was what I was aiming for.

    I own 5 C64's and I can confirm that the filter differs A LOT and not one of them is even close to the official documentation. Just forget about using the documentation as a reference... ;) My breadbin C64's and C128's with 6581 in them are WAAAAAAY of the chart and has all that wonderful distortion that real purist loves; Even the amount of distortion differs between them. Rob Hubbard, Martin Galway and other musicians refused to use the filter in early titles because they couldn't make their tunes sound good on all C64's. This changed in 1986 when the C64c with 8580 SID became more common. The 8580 is much closer to the official documentation and (sadly?!) doesn't have any distortion.

    SIDcog was calibrated by ear using my 8580 equipped C64's as references. Of course, the cutoff linearity and the cutoff slope couldn't be made perfect thanks to all short cuts listed above, but the most important thing is that the offset is as close as possible to the real SID. Otherwise all modern tunes that uses a sweeping resonant lowpass filter in combination with a sweeping triangle wave to emulate kicks would sound AWFUL!! Have a listen to "Harden your horns" for the perfect example of this.

    I have DC patched one of my 8580 equipped C64's to be able to play 4 bits samples using the main volume "trick". This should theoretically work with SIDcog as well, if the DC offset value is set to something other than 0x8000000. Someday I will connect SIDcog to a real C64... then I will be able to test if this works.

  • pik33pik33 Posts: 792
    edited 2014-11-10 - 11:59:13
    I was surprised with these 12db/oct characteristics - "they" say everywhere Sidcog has 6 dB/oct filter... then this is simply not true. It has the same filters as real thing.

    I don't have a C64 :( so I haven't any possibility to tune my implementation of filters. There is possibility to check the original filters: program the sid to make a (as close as possible) white noise; then pass it by the filter with several settings, then make a spectral analysis of the output.
  • Oldbitcollector (Jeff)Oldbitcollector (Jeff) Posts: 8,090
    edited 2014-11-16 - 09:11:38
    Ahle2 wrote: »
    Retronitus has awaken from its sleep, I am working on a LameStation game that will use it. Retronitus may actually end up as part of the standard library for this cool console.
    And I am about to finish the tools for Retronitus as we speak, then it will be possible to easily make music and sfx for it.


    I was wondering if we could get an update on this? I'd love to implement a version of this in the Micromite Companion project.
    The youtube videos of this are simply amazing.
  • potatoheadpotatohead Posts: 9,957
    edited 2014-11-22 - 10:44:10

    I really want to compose on Retronitus. Just make some chip music. No pressure of course. Anything is done when it's done, but I sure like reading things are moving along in some fashion!

    Of course, I will test anything. :)
  • GadgetoidGadgetoid Posts: 47
    edited 2014-11-24 - 11:35:33
    This has to be the most beautiful thing I've ever played with on a Microcontroller, the sheer, grungy, ear-bleeding sound you can coax out of this thing by abusing it with analogue control values is staggering.

    I put together a quick and dirty logic level shifter to translate the control voltage and gate values of the Sparkfun Sparkpunk Sequencer, hooked the two together, and hacked up the Play Routine example to poll the ADC on my ASC+ and pass the values, with a little scaling, straight into the noteOn and setCutoff methods of SIDcog.

    The result is interesting, to say the least:

    I plan to assemble a slightly less hacky version of my setup and add a handful of pots to let me tweak some other values on the fly. Who needs trackers when you can twist and distort the SID sound live!
  • Ahle2Ahle2 Posts: 976
    edited 2014-11-24 - 13:49:14
    @OBC and potatohead
    Patience is a virtue! ;) I will make an update as soon as I have anything interesting to show... Of that you can be sure!

    Welcome to the forum!
    Cool project... It would be nice to see a YouTube clip of that "thing" in action.

  • GadgetoidGadgetoid Posts: 47
    edited 2014-11-25 - 05:36:53
    Ahle2 wrote: »

    It would be nice to see a YouTube clip of that "thing" in action.

    Your wish is my command!

    We got some 3.5mm jack sockets in today, so I tidied up my still-breadboarded SparkPunk adapter, tweaked the code to separate drums/melody onto different portions of the sliders, and had a 5-minute jam session and tour. It's now uploading!

    And here we go:
  • potatoheadpotatohead Posts: 9,957
    edited 2014-11-25 - 14:52:52
    That is all kinds of cool fun! Thanks for sharing it.

    @Ahle: Indeed. Looking forward to fun times. :)
  • pik33pik33 Posts: 792
    edited 2014-11-26 - 00:04:20
    This reminds me the bitbuf:

    Maybe making something like this using the propeller instead of atmega can give interesting results...
  • GadgetoidGadgetoid Posts: 47
    edited 2014-11-26 - 02:21:19
    @pik33 that's a pretty nifty setup, I like the concept. I don't know why I didn't think of something like this in the first place.

    I've decoupled my ADC sampling from the main logic using another COG, if I slow this down to a reasonable frequency then I can store a sequence of 8 notes, including the intermediate values that give the sound such a unique timbre, and run these back through SIDcog while I feed in the melody.

    The sequencer has signals for Run/Stop and Clock, which I could level shift and use to keep everything in sync.
  • Ahle2Ahle2 Posts: 976
    edited 2015-04-23 - 13:03:46
    I just want to share this, Released TODAY by LMan! It hit the top position at CSDB within the first hour.

    Such an amazing tune using some unusual combination of SID techniques at the same time. The chords are samples played through a sweeping resonant low pass filter. :) The filter is nothing special for a C64 tune because that is part of the original SID design, but the cool thing is that samples are played trough the filter using "timed triangle wave tricks". (in lack of better words) It used to be impossible to play samples through the filter using old sample techniques.

  • potatoheadpotatohead Posts: 9,957
    edited 2015-04-23 - 14:06:34
    Oh man! That tune is seriously great. Thanks for linking it here. I would not have seen it right away.
  • GenetixGenetix Posts: 1,451
    edited 2015-04-24 - 11:34:41
    Sounds really good!

    Johannes, what hardware is needed for SIDcog?
  • StefanL38StefanL38 Posts: 2,287
    edited 2015-04-24 - 23:41:34
    Genetix wrote: »
    Sounds really good!

    Johannes, what hardware is needed for SIDcog?

    nothing special propeller-chip, with standard µC-things like crystal, EEPROM etc.
    all sound-effects is created by software.

    Dgital-to-analog-conversion through capacitor and resistor

    best regards

  • davidsaundersdavidsaunders Posts: 1,559
    edited 2015-04-25 - 08:26:49
    Now someone needs to write a Propeller CSG 4510 CPU emulator (the CPU of the C65), a VIC-III emulator, a good external memory interface, and put together a Commodore 65 compatible computer, with 4MB of RAM :) .
  • mstrammstram Posts: 41
    edited 2015-04-26 - 08:27:09
    Is there a (Windows) propeller emulator that will run SIDcog ?

    I have Gear but it seems like it doesn't emulate audio ?

    I've been looking for an audio plugin for it or how to write one.
  • Ahle2Ahle2 Posts: 976
    edited 2015-04-26 - 12:26:35
    It shouldn't be that hard to do what you want, the FRQA/FRQB registers holds each 32 bit unsigned sample that SIDcog generates. Simply shifting these values 16 steps to the right and feeding them to the sound card at the right rate, should do the trick. No need to emulate duty mode + RC filter. (If perfect emulation is important, then you need to do duty+RC of course) The difference compared to a real Prop is that the audio will be too clean and lack all those juice artifacts that duty mode generates. But on the other hand you will get aliasing distortion converting from whatever rate the Prop is generating to the rate that the sound card is outputing.

  • mstrammstram Posts: 41
    edited 2015-04-26 - 23:03:32
    Ok, thanks for the info.

    I've managed to get sound output from Gear (though not related to the Sidcog yet).

    I used the totally unrelated vt100 terminal plugin and added :
    using System.Media;

    to the top of the terminal.xml of the file and :
    (new SoundPlayer(@"c:\w1.wav")).PlaySync();
    to the sendBtn_Click routine.

    It looks like I need to use WaveOut to play individual samples.

    But meanwhile, I've been trying to figure out how to access the FRQA/FRQB registers from a plugin XML file.

    I have the Gear source code, but it's not obvious how the XML file "connects" to any variables defined in a SPIN file
  • GatunoGatuno Posts: 22
    edited 2015-04-27 - 09:54:23
    Hello Ahle2:
    I think it is possible to build a GEAR plugin that read the FRQA/FRQB registers and dumps to a file periodically, but I don't know if that is what is needeed.
    Normally the content of those registers depends on what counter mode are running, and in what moment of time are you sampling (derived from sampling rate). What counter mode SIDCog is using? I had look inside of it (v1.3 in OBEX), but I coudn't figure out...

    PS: I'm one of the people who is updating the GEAR emulator, so I understand the possibilities.
  • GatunoGatuno Posts: 22
    edited 2015-04-27 - 11:55:57
    Hello mstram:

    In that version of GEAR plugin, if you have declared
    private Propeller Chip;
    inside your new plugin, you can access a Cog method ReadLong(uint address), and read directly FRQA or FRQB. I recomend the following as example:
    class terminal : PluginBase             //assuming your plugin class is called terminal
        private Propeller Chip;
        private Cog cogSelected;            //add this reference
        public override void PresentChip(Propeller host)
            cogSelected = Chip.GetCog(1);   //assuming SIM PASM code running on cog 1
       public override void OnClock(double time)
            if (cogSelected != null)
                uint value1 = cogSelected.ReadLong(CogSpecialAddress.FRQA);    //also you could use cogSelected.ReadLong(0x1FA), but is more tidy this way.
                uint value2 = cogSelected.ReadLong(CogSpecialAddress.FRQB);
                //do something with value1 & value2

    Currently the plugin system is mainly oriented to read & write pins when the clock ticks (using OnClock() method), or when a pin changes (using OnPinChange() method), offering Chip.DrivePin() method to affect pins or Chip.PinStates[] array to read their states. But is possible to access all the public methods and properties of Propeller and Cog class (later as show here).
  • mstrammstram Posts: 41
    edited 2015-04-27 - 13:46:43
    Hi Gatuno,

    Great !
    //do something with value1 & value2

    I've been trying to put some file - i/o into the plugin, but am running into some kind of syntax error that CompileAssemblyFromSource doesn't like.

    Btw, the CheckCode is very nice in Gear, but it would be very helpful the editor displayed line numbers !

    Not a huge problem, as thankfully the cut&paste works, so I just transfer it to another editor then back

    ** After some searching, I see it's not that simple for the line #'s, but I found a couple of examples and will see what I can do**

    ** But FIRST the FRQA data ! ** ;)

  • mstrammstram Posts: 41
    edited 2015-04-28 - 03:03:54
    I entered an issue on the Github repo.

    Any plugin I try to run with the ver 15.0 sources I built is failing with a "constructor not found" message.

    The same plugins run on ver (aside from the minor name changes that have been made to the Gear classes)

    I'm building the sources with VcS 2010 / .net 4.0, is that the problem ?

  • GatunoGatuno Posts: 22
    edited 2015-04-28 - 07:20:46
    Hello mstram:
    I would recommend you to use the version of GEAR, because is the stable one. The github version is under development to improve the plugin system, but if you like to help us to test it there is no problem ;-)
    About your issue in Github, is about the changes in the base class: a required parameter. See the details in

  • mstrammstram Posts: 41
    edited 2015-04-28 - 08:13:44
    Hi Antonio,

    Glad to see that it was not a problem with my VCS / net versions !

    And duh, I (obviously probably to you), didn't even look at the plugin examples in the repo.

    Well, I sorta did, I saw that the file names were the same as the ones in 14.7, so I ASSumed that nothing had changed ;)

    Could have saved a LOT of time, had I looked at them :/

    ** Is the source for 14.7.3 available ? *

    I looked on the SourceForge site, didn't see it.

  • mstrammstram Posts: 41
    edited 2015-04-28 - 15:22:36
    In ver 15, this is giving a NullReference Exception was unhandled / Object reference not set to an instance of an object
    class Terminal : PluginBase
       private Cog cogSelected;         
       private PropellerCPU Chip;
     public override void PresentChip()
         Cog cogSelected = Chip.GetCog(1); 

    The exception is happening at (Emulator.cs)
    private void AttachPlugin(PluginBase plugin)
                Chip.IncludePlugin(plugin);     //include into plugin lists of a PropellerCPU instance
                plugin.PresentChip();     <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

    There doesn't seem to be much code at : (PluginBase.cs)
    public virtual void PresentChip() { }    
  • GatunoGatuno Posts: 22
    edited 2015-04-28 - 15:30:10
    Hello Mike:
    Now you can find the source code under

  • GatunoGatuno Posts: 22
    edited 2015-04-28 - 15:47:51
    Hello Mike:

    > In ver 15, this is giving a NullReference Exception was unhandled / Object reference not set to an instance of an object

    If you are in Ver 15, Do you have defined in your plugin code the method OnClock(..)? The error you described look like there is no overrided method to invoke...
    public override void OnClock(double time, uint sysCounter) 
       //react to every clock changes here with your code...

  • mstrammstram Posts: 41
    edited 2015-04-28 - 16:59:39
    Umm, yah I have the OnClock code, but what has that got to do with PresentChip ? (which seems to be the problem).
Sign In or Register to comment.