"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...
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
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)
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.
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.
@6581
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.
/Johannes
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.
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!
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.
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!
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!
@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.
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.
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 .
@mstram
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.
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.
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)
{
...
Chip.NotifyOnClock();
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).
Hello mstram:
I would recommend you to use the version 14.7.3.0 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 https://github.com/davispuh/gear-emu/issues/13.
> 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...
}
Comments
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...
/Johannes
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)
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.
/Johannes
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.
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.
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.
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: https://vine.co/v/O1viO6KIiP2
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!
Patience is a virtue! I will make an update as soon as I have anything interesting to show... Of that you can be sure!
@Gadgetoid
Welcome to the forum!
Cool project... It would be nice to see a YouTube clip of that "thing" in action.
/Johannes
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:
@Ahle: Indeed. Looking forward to fun times.
http://linusakesson.net/bitbuf/index.php
Maybe making something like this using the propeller instead of atmega can give interesting results...
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.
https://www.youtube.com/watch?v=eI5d6Y0Fzl4
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.
/Johannes
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
Stefan
I have Gear 14.7.3.0 but it seems like it doesn't emulate audio ?
I've been looking for an audio plugin for it or how to write one.
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.
/Johannes
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 :
to the top of the terminal.xml of the file and :
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
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.
In that version of GEAR plugin, if you have declared 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:
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).
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 ! **
Mike
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 14.7.3.0 (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 ?
Mike
I would recommend you to use the version 14.7.3.0 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 https://github.com/davispuh/gear-emu/issues/13.
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.
Mike
The exception is happening at (Emulator.cs)
There doesn't seem to be much code at : (PluginBase.cs)
Now you can find the source code under https://github.com/davispuh/gear-emu/releases.
Antonio
> 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...
Antonio