Thanks for the code. I'll keep it in mind if/when I'm writing code in spin directly. I should pass it on to Hanno (who wrote 12blocks) to see if it could be implemented in a future release.
I'd sure like to know which loop is running at 200Hz! I tried something else; I added a kill code to my loop, so that when an external switch is pressed all four KS cogs are stopped. They can be humming away, but when I hit that button the guitar goes silent. The main loop is still running, taking ADC measurements and checking if the strings are "plucked," but of course no sound is produced once the strings are killed.
If I kill three of the four strings, there is still a 200Hz signal, but it is much quieter. Ditto with two strings killed, about half the amplitude. It would appear that each string is producing a hum, they are roughly in phase, and adding more strings causes the hum to add each time. This is reflected in the Conduit output; if I kill three strings then the periodic waveform does disappear from those strings.
I let just one string run, and according to the Conduit the period of the hum is about 3.8mS, or 263 Hz. Surely it must be in the KS code somewhere. Actually, there's one thing that I noticed. If you listen very carefully (ie. turn up the volume), you can hear that in some cases the string never really dies away completely (in this case, MIDI note 50, sustain 8). If I temporarily drop the sustain to say, 4, then the remainder of the string "vibration" dies off. Hum is always there, though. Could the two effects be somehow related? The inability to eventually fade out, and the constant hum?
I assume that the source of the hum is somewhere in the assembly portion of the KS code. It's a little over my head to analyze, unfortunately.
I love reading the "journal", keep it up! Sorry for not responding sooner, I was out of town for the weekend.
I can't see any way the KS code can be directly causing noise at ~263 Hz. The only code that runs in a loop is the PASM code, and it is running at your specified sampling rate. There are weird audio artifacts that can be generated by the counter output (which is in part why Lawson was encouraging me to change modes), but those should be filtered out by the analog low-pass filter.
Regarding the sustain not dying off completely, you are correct. I'm using an integer solution, which I limited to 16 bits per sample to save on hub RAM. So, each value is in the -32000 to +32000-ish range. If you use a sustain of 8, that means the sustain codeis performing "value -= value / 256". Once the values hit 255 or lower, nothing is subtracted, so those values will be left as-is. This will modify the waveform (over time), so it would end up with the string "ringing" forever with a very small semi-square wave. This might be the noise you are hearing...was the plucked note around 263 Hz? The easy fix for this is costly...go to 32-bits per sample, doubling your storage requirements.
Here is a modification you can add to the KS object to see what the waveform looks like:
Then from the calling code you can do something like:
'{ Just play a note, stop the KS cog, then grab the buffer, then restart the cog
ks[0].set_frequency( 1000 )
ks[0].pluck( 255 )
waitcnt( clkfreq >> 3 + cnt )
ks[0].stop
repeat p from 0 to constant( ks#buf_size - 1 )
term.dec( p )
term.tx( "," )
term.dec( ks[0].dump_buf( p ) )
term.tx( 10 )
The buffer should show up with the variables, so worst case scenario is doubling that...you have room. I'll whip up the "Deluxe Edition" featuring 32-bit samples [8^). What is the lowest note you plan to play at 48kHz sampling rate (to determine the default buffer size)?
The buffer should show up with the variables, so worst case scenario is doubling that...you have room. I'll whip up the "Deluxe Edition" featuring 32-bit samples [8^). What is the lowest note you plan to play at 48kHz sampling rate (to determine the default buffer size)?
Jonathan
Yeah, I've got room, and there are some variables that I can trim from my code (if I need to) that are really only there for troubleshooting. Lowest note would be 30.8677Hz (the lowest normal bass guitar string).
I'm just working on getting the buffer dump working; 12blocks uses its own terminal rather than full duplex serial...
Sounds awesome guys! I just plugged some headphones into a demoboard and ran your demo- very realistic sounds. This is for sure getting into 12Blocks- with the code I wrote to let kids type notes. Let me know when you think it's ready to integrate...
Hanno
Sounds awesome guys! I just plugged some headphones into a demoboard and ran your demo- very realistic sounds. This is for sure getting into 12Blocks- with the code I wrote to let kids type notes. Let me know when you think it's ready to integrate...
Hanno
Thanks, Hanno! Every new build is like receiving another package from Amazon in the mail, and I sure love receiving new stuff from Amazon! Are you aiming to implement the single string version, or the multi string version?
@lonesock: you could try having the "value -= value / 256" code round up/down when value/256 returns zero. (i.e. return a 1 or -1 depending on the sign of 'value' and only return zero if 'value' is zero) Effectively this would automatically ramp down the sustain as a note got close to dying out.
Hi, Lawson. I tried that, but I got a weird buzz as the sustain deformed the waveform (after letting it ring for quite a while). The best thing I found to do was use the PRNG to generate a dithering value to add to each sample prior to the shift. The PRNG is scaled automatically to match the low bit of the sample that will be discarded in the shift. It seems to work pretty well.
So, here's the latest version:
* still 16 bits per sample
* dithering on the sustain so the "left-it-ringing-for-a-long-time" sound is better
* you can select either the DUTY or NCO counter mode so hear the difference (set "use_DUTY_mode" to 0 or 1)
These are basically noise free (to my ears) on the demo-board (I do hear a strange buzz when using NCO mode and the audio is very quiet...I may be doing something wrong). Jeff, if you can test this one out, maybe trying both counter modes, and let me know what you find.
Just as a side note, I'd be interested in knowing the update rate of the 12Blocks sync cog. I'm betting it depends on how many variables you are watching/controlling.
So the audio was very quiet for you, too? I'd been having trouble with quiet audio for a while, even before NCO, and eventually "fixed" it by reducing the resistor at my output. Before NCO, I had to be very selective about how I did my loops and such - do them "properly" and the audio was nice and loud. Do it wrong and it was quiet. After NCO nothing I did made the audio loud again (thus the resistor fix), but the reduction in noise was worth it.
Howdy,
I integrated the code into 12Blocks- very nice! I'm running it on the very first production TBot- straight from the assembly line- it's still warm! Kudos to Chad for an amazing job.
Hanno
First off, I compared the same code running on my guitar and on my stripped down demo board. Here's the code I used:
{{
Karplus-Strong demo
}}
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
sr = 44_100 ' let's run at the CD sampling rate
sustain_value = 8
OBJ
ks[4] : "Karplus-Strong" ' left channel information should be heard from your left speaker...
PUB test_KS
' set up using the demo board pins for the headphones
ks[0].start( 10, -1, sr )
ks[1].start( 11, -1, sr )
ks[2].start( 12, -1, sr )
ks[3].start( 13, -1, sr )
waitcnt( clkfreq >> 3 + cnt )
ks[0].set_sustain( 8 )
ks[1].set_sustain( 8 )
ks[2].set_sustain( 8 )
ks[3].set_sustain( 8 )
waitcnt( clkfreq / 4 + cnt )
' set a note (MIDI spec), immediately updated, whether you pluck the string or not
ks[0].set_note( 50 )
ks[1].set_note( 55 )
ks[2].set_note( 59 )
ks[3].set_note( 64 )
ks[0].pluck( 255 )
So, it sets up four strings, and plucks the first one once. Then I can listen to any noise that remains. On the guitar, there's a 312Hz hum. On the demo board, nothing. Therefore, I have a hardware problem somewhere (shorted pin? feedback from somewhere? something to do with my summing amp? Maybe the ADC?) I need to experiment a bit more. But the good news is, the strings now settle down as expected. I MUST use NCO mode, as duty mode simply has an unbearable amount of noise now. Perhaps once I track down my hardware issue it'll be suitable for use again.
As a side note, I should add that there is only noise when anything Karplus-Strong related is running. If I kill all four cogs that the strings are running on (using an external switch), the guitar goes silent.
Do you have a schematic I could review and/or build and/or simulate (I like http://www.linear.com/designtools/software/#LTspice)? Specifically the DAC section, but I'm interested in the rest of it [8^) If you'd like me to sign a NDA I'm fine with that.
Do you have a schematic I could review and/or build and/or simulate (I like http://www.linear.com/designtools/software/#LTspice)? Specifically the DAC section, but I'm interested in the rest of it [8^) If you'd like me to sign a NDA I'm fine with that.
Jonathan
Actually, I was thinking of sending you a laser guitar PCB anyway, but when it's working. I've got a few things to try yet; including modding and installing a second board, and isolating various parts of the board to take measurements and whatnot. At least now I know that my hardware is to blame so I know what to concentrate on.
*snip*
So, it sets up four strings, and plucks the first one once. Then I can listen to any noise that remains. On the guitar, there's a 312Hz hum. On the demo board, nothing. Therefore, I have a hardware problem somewhere (shorted pin? feedback from somewhere? something to do with my summing amp? Maybe the ADC?) I need to experiment a bit more. But the good news is, the strings now settle down as expected. I MUST use NCO mode, as duty mode simply has an unbearable amount of noise now. Perhaps once I track down my hardware issue it'll be suitable for use again.
To be precise, your hum is locating in the differences between the demo board and the laser guitar board. Since you used stripped down software on the demo board, there is still a (small) chance your code is causing the hum.
Assuming the hum is from hardware, the 3.3 volts supplied to the propeller is a likely culprit. When the KS cogs are killed the outputs will be reset to inputs. Assuming your low pass filter is just an RC filter right at each output pin, with nothing driving them the RC filter will just hold it's last value. Basically I'm guessing the power to the Propeller might need better decoupling.
Well here we go, the first of my investigation into the hardware. First up, some screenshots from my scope. It would seem that my 3.3V line has a bit of noise, but it's hard to pin down (NewFile1), though my 5V is definitely not very clean (NewFile0). Still only millivolts of noise, though. Ground is a little noisy, at about 20mVp-p (NewFile2).
Made a few more changes, I beefed up my LPF to a double pole, now the sampling rate frequency component is nearly gone. Did some other poking around, there's not much to see really. For one thing, it's really hard to capture that hum on a scope!
Tomorrow I'll try adding a bunch of filter caps to the power lines to see if that helps. I could also see if I can dig up some cleaner power supplies.
Every switching power supply I've looked at always had switching noise at the output. Usually only at >10KHz though, that low frequency component is odd. You could try running the propeller with a linear regulator from the +5v rail? You might also want to make a super short grounding lead for your scope probes. (i.e. pull off the wire hook, and wind up a ground probe to parallel the probe point) I've found that the three inch loop on most scope probes can pick up a lot of environmental magnetic noise. A fun and useful demo of this is to just clip the ground lead to the probe tip and wave it around looking for noise sources.
Every switching power supply I've looked at always had switching noise at the output. Usually only at >10KHz though, that low frequency component is odd. You could try running the propeller with a linear regulator from the +5v rail? You might also want to make a super short grounding lead for your scope probes. (i.e. pull off the wire hook, and wind up a ground probe to parallel the probe point) I've found that the three inch loop on most scope probes can pick up a lot of environmental magnetic noise. A fun and useful demo of this is to just clip the ground lead to the probe tip and wave it around looking for noise sources.
Lawson
Yep, I can see the switching noise from the power supply, it's up in the hundreds of thousands of Hertz. There's still more testing to be done, including rigging up a second laser guitar PCB to see if it works differently, and using a different power supply (I have a stash of computer power supplies as well as other single voltage ones.)
More power supply ugliness for you. The first image is the unfiltered output of the +5V line. By unfiltered, I mean there is no capacitor to smooth things out, thus all the noisy spikes. Why bother with this measurement? Well, the 330uF filter cap is on the laser guitar board, and I wanted to see what the power rail looked like when disconnected from the board, just in case the board was at fault and not the PS. Turns out the power supply is indeed being rather naughty.
Tonight I'll first try a different computer power supply to see if it's any better. If yes, I'll start using it instead. If not... then I guess I'll have to make my own power supply. Ugh.
I wasn't able to get another computer PSU running, so instead I dumped on a bunch of extra capacitors on the power supply rails. Both the 3V and 5V lines were increased by 1000uF. The high frequency noise was certainly reduced, though it had little effect on my hum. I suspect I would need capacitors a whole magnitude larger to put a dent in that hum.
Tomorrow I'll bring the whole shebang to work where I'll hook it up to some decent power supplies.
Write this down under "Why the heck didn't I do this sooner?" As suspected, it was indeed the (lousy) computer power supply I was using. This morning I hooked up my board to a set of nice bench power supplies, and the hum was gone. Just sweet guitar sounds and a bit of fuzz (likely from me holding the headphone jack against the output terminals with my bare hands).
So!!! Next steps are:
1. Build a better power supply to replace the lousy one I'm using now.
2. Invest in a decent bench power supply or two, to save myself from these frustrations in the future
3. Inform the community at large that computer power supplies make lousy bench supplies, and to never use them despite how inexpensive they are. You get what you pay for.
Thank you all for bearing with me as I get this sorted out. I may now concentrate on making the laser guitar super-awesome again.
Just came back from the electronics store with parts in hand to build a nice custom linear power supply. Hopefully I can be up and running sometime this weekend.
Comments
I'd sure like to know which loop is running at 200Hz! I tried something else; I added a kill code to my loop, so that when an external switch is pressed all four KS cogs are stopped. They can be humming away, but when I hit that button the guitar goes silent. The main loop is still running, taking ADC measurements and checking if the strings are "plucked," but of course no sound is produced once the strings are killed.
If I kill three of the four strings, there is still a 200Hz signal, but it is much quieter. Ditto with two strings killed, about half the amplitude. It would appear that each string is producing a hum, they are roughly in phase, and adding more strings causes the hum to add each time. This is reflected in the Conduit output; if I kill three strings then the periodic waveform does disappear from those strings.
I let just one string run, and according to the Conduit the period of the hum is about 3.8mS, or 263 Hz. Surely it must be in the KS code somewhere. Actually, there's one thing that I noticed. If you listen very carefully (ie. turn up the volume), you can hear that in some cases the string never really dies away completely (in this case, MIDI note 50, sustain 8). If I temporarily drop the sustain to say, 4, then the remainder of the string "vibration" dies off. Hum is always there, though. Could the two effects be somehow related? The inability to eventually fade out, and the constant hum?
I assume that the source of the hum is somewhere in the assembly portion of the KS code. It's a little over my head to analyze, unfortunately.
I can't see any way the KS code can be directly causing noise at ~263 Hz. The only code that runs in a loop is the PASM code, and it is running at your specified sampling rate. There are weird audio artifacts that can be generated by the counter output (which is in part why Lawson was encouraging me to change modes), but those should be filtered out by the analog low-pass filter.
Regarding the sustain not dying off completely, you are correct. I'm using an integer solution, which I limited to 16 bits per sample to save on hub RAM. So, each value is in the -32000 to +32000-ish range. If you use a sustain of 8, that means the sustain codeis performing "value -= value / 256". Once the values hit 255 or lower, nothing is subtracted, so those values will be left as-is. This will modify the waveform (over time), so it would end up with the string "ringing" forever with a very small semi-square wave. This might be the noise you are hearing...was the plucked note around 263 Hz? The easy fix for this is costly...go to 32-bits per sample, doubling your storage requirements.
Here is a modification you can add to the KS object to see what the waveform looks like: Then from the calling code you can do something like: Note that "term" is the FullDuplexSerial object.
Jonathan
Is there an easy way to tell how much hub ram I'm using?
I'll try adding that code to see what it reports...
Jonathan
OK, right now the program is using 1409 longs, the variables 2153 longs, and free space is 4626 longs.
Jonathan
Yeah, I've got room, and there are some variables that I can trim from my code (if I need to) that are really only there for troubleshooting. Lowest note would be 30.8677Hz (the lowest normal bass guitar string).
I'm just working on getting the buffer dump working; 12blocks uses its own terminal rather than full duplex serial...
Hanno
Thanks, Hanno! Every new build is like receiving another package from Amazon in the mail, and I sure love receiving new stuff from Amazon! Are you aiming to implement the single string version, or the multi string version?
Lawson
So, here's the latest version:
* still 16 bits per sample
* dithering on the sustain so the "left-it-ringing-for-a-long-time" sound is better
* you can select either the DUTY or NCO counter mode so hear the difference (set "use_DUTY_mode" to 0 or 1)
These are basically noise free (to my ears) on the demo-board (I do hear a strange buzz when using NCO mode and the audio is very quiet...I may be doing something wrong). Jeff, if you can test this one out, maybe trying both counter modes, and let me know what you find.
Just as a side note, I'd be interested in knowing the update rate of the 12Blocks sync cog. I'm betting it depends on how many variables you are watching/controlling.
Jonathan
So the audio was very quiet for you, too? I'd been having trouble with quiet audio for a while, even before NCO, and eventually "fixed" it by reducing the resistor at my output. Before NCO, I had to be very selective about how I did my loops and such - do them "properly" and the audio was nice and loud. Do it wrong and it was quiet. After NCO nothing I did made the audio loud again (thus the resistor fix), but the reduction in noise was worth it.
I'll let you know which one works out better.
I integrated the code into 12Blocks- very nice! I'm running it on the very first production TBot- straight from the assembly line- it's still warm! Kudos to Chad for an amazing job.
Hanno
First off, I compared the same code running on my guitar and on my stripped down demo board. Here's the code I used:
So, it sets up four strings, and plucks the first one once. Then I can listen to any noise that remains. On the guitar, there's a 312Hz hum. On the demo board, nothing. Therefore, I have a hardware problem somewhere (shorted pin? feedback from somewhere? something to do with my summing amp? Maybe the ADC?) I need to experiment a bit more. But the good news is, the strings now settle down as expected. I MUST use NCO mode, as duty mode simply has an unbearable amount of noise now. Perhaps once I track down my hardware issue it'll be suitable for use again.
Jonathan
Actually, I was thinking of sending you a laser guitar PCB anyway, but when it's working. I've got a few things to try yet; including modding and installing a second board, and isolating various parts of the board to take measurements and whatnot. At least now I know that my hardware is to blame so I know what to concentrate on.
To be precise, your hum is locating in the differences between the demo board and the laser guitar board. Since you used stripped down software on the demo board, there is still a (small) chance your code is causing the hum.
Assuming the hum is from hardware, the 3.3 volts supplied to the propeller is a likely culprit. When the KS cogs are killed the outputs will be reset to inputs. Assuming your low pass filter is just an RC filter right at each output pin, with nothing driving them the RC filter will just hold it's last value. Basically I'm guessing the power to the Propeller might need better decoupling.
Lawson
Tomorrow I'll try adding a bunch of filter caps to the power lines to see if that helps. I could also see if I can dig up some cleaner power supplies.
Lawson
Yep, I can see the switching noise from the power supply, it's up in the hundreds of thousands of Hertz. There's still more testing to be done, including rigging up a second laser guitar PCB to see if it works differently, and using a different power supply (I have a stash of computer power supplies as well as other single voltage ones.)
NewFile3.bmp
For reference, here's the output from a nice military-grade chassis mount power supply I got for free from work. Argh, if only I had more of these!
NewFile4.bmp
Tonight I'll first try a different computer power supply to see if it's any better. If yes, I'll start using it instead. If not... then I guess I'll have to make my own power supply. Ugh.
Tomorrow I'll bring the whole shebang to work where I'll hook it up to some decent power supplies.
Write this down under "Why the heck didn't I do this sooner?" As suspected, it was indeed the (lousy) computer power supply I was using. This morning I hooked up my board to a set of nice bench power supplies, and the hum was gone. Just sweet guitar sounds and a bit of fuzz (likely from me holding the headphone jack against the output terminals with my bare hands).
So!!! Next steps are:
1. Build a better power supply to replace the lousy one I'm using now.
2. Invest in a decent bench power supply or two, to save myself from these frustrations in the future
3. Inform the community at large that computer power supplies make lousy bench supplies, and to never use them despite how inexpensive they are. You get what you pay for.
Thank you all for bearing with me as I get this sorted out. I may now concentrate on making the laser guitar super-awesome again.
Jonathan