Karplus-Strong on the Propeller?
jeff-o
Posts: 181
Hi everyone, I searched the forums and found a mention here and there about Karplus-Strong, but it would seem that no-one has done it on the Propeller yet.
Karplus-Strong is a head-slappingly simple way of modeling the behavior of a plucked string. See the wiki entry here:
http://en.wikipedia.org/wiki/Karplus-Strong_string_synthesis
Basically, a noise burst is sent through a delay line and then a filter. The resulting waveform is then added back into a loop and sent to an output. Each time the waveform passes through the loop, it becomes more "filtered" and closer to the fundamental frequency determined by the total delay of the loop.
This algorithm was first modeled on 80's era computers and VLSI chips, so surely the Propeller is up to the task, right? Sadly my programming skills are not where they need to be to pull this off, but I'm hoping someone here can manage it, or at least point me in the right direction.
Here are some other resources that may be useful:
https://ccrma.stanford.edu/realsimple/faust_strings/faust_strings.pdf
http://ccrma.stanford.edu/~jos/pasp/Karplus_Strong_Algorithm.html
The end goal is some sort of musical instrument, like a guitar or harp. However, this algorithm can be used to simulate drums or almost any other plucked or struck instrument, with the right parameters.
Thanks for any help!
Karplus-Strong is a head-slappingly simple way of modeling the behavior of a plucked string. See the wiki entry here:
http://en.wikipedia.org/wiki/Karplus-Strong_string_synthesis
Basically, a noise burst is sent through a delay line and then a filter. The resulting waveform is then added back into a loop and sent to an output. Each time the waveform passes through the loop, it becomes more "filtered" and closer to the fundamental frequency determined by the total delay of the loop.
This algorithm was first modeled on 80's era computers and VLSI chips, so surely the Propeller is up to the task, right? Sadly my programming skills are not where they need to be to pull this off, but I'm hoping someone here can manage it, or at least point me in the right direction.
Here are some other resources that may be useful:
https://ccrma.stanford.edu/realsimple/faust_strings/faust_strings.pdf
http://ccrma.stanford.edu/~jos/pasp/Karplus_Strong_Algorithm.html
The end goal is some sort of musical instrument, like a guitar or harp. However, this algorithm can be used to simulate drums or almost any other plucked or struck instrument, with the right parameters.
Thanks for any help!
Comments
Of course, it's possible to make filters which don't require full multiplies, which would be even faster.
Of course, later implementations of the algorithm require fancier math.
Another quote I found interesting is about wavetable modification:
Would that be a viable alternative? There's far less information on that method, however.
That could be good enough, since a guitar string has fundamentals that max out at 659Hz and harmonics that max out at 5 or 6kHz. An FIR filter would be nice because it allows for fractional delays.
http://courses.cit.cornell.edu/ee476/FinalProjects/s2009/cgg27_jpv23/cgg27_jpv23/webpagef.htm
And here, using an atmega32:
http://instruct1.cit.cornell.edu/courses/ee476/FinalProjects/s2007/apb36_yn47/ECE_476_Website.html
Jonathan
Woohoo! I know what I'll be doing tonight!!
In the demo it cycles through 15 frequencies. I tried subbing in values but I'm not exactly sure what to put in there.
Thanks a million!
Definitely. So far I've managed to import the code into 12blocks so I can play around with values more easily. The code itself is a step or two above my head so I'm looking forward to any more work lonesock does with it!
You can already change the sustain length...search for the word "decay" in the PASM source.
The period that you pass to the pluck routine is in fixed point format. I think in that version you have 4 fractional bits, so basically the period would be N / 16, to within the nearest 16th of a sample. In this next version there is a constant to select how many fractional bits you care about.
Hopefully I can upload the next version within 1/2 hour or so.
Jonathan
Wow, sounds great! I'm looking forward to trying it out. Tonight my goal is to get four separate "strings" running on four cogs and sending output to four different pins for further mixing and analog filtering.
Jonathan
Oh, it's like magic in text format. I wonder if I could skip out early and go home...
Or do what I do...start a work project using the propeller, so I can play with it all day!
Jonathan
Someday I may just get a chance to do that. Someday...
Also, I think I owe you a peanut butter sandwich or two.
I once jokingly told someone they could pay me in chocolate milk, and a week later some arrived...I didn't know you could drop ship it from amazon.com!
Jonathan
Well, as far as sandwiches are concerned the best I could do on amazon is a recipe book. Or a sandwich press.
-Phil
Nice to have different sound generators on the Prop.
Hanno
All credit should go to Jonathan! I'm playing around with it right now. I *think* I managed to calculate the right "Period" based on the frequency I want in Excel, then matching it to an online tuning fork. Things aren't matching up quite right so I think I must have missed something. I'm using Period=((1/frequency)*2^fraction_bits)*100000 at the moment, it give results that are sorta close. Of course, it's also 1am and I'm hungry so I might be way off.
The period should be something close to :
period_fixed_point = sample_rate * 2^fraction_bits / frequency
It will be off a bit (I'm guessing), because of the filtering I'm using when sampling the delay buffer...I will be sitting down to try to figure out the exact equation soon, but that should get you started. I should just have the PASM code timestamp the last 0-crossings, and compute the frequency for you (using the actual sample rate, etc.)
Jonathan
With this info I can generate a table that contains all the fret positions and their associated periods. I may hold off, however, if the plan is to ultimately use frequency and not period as the input value.
Jonathan
And yeah, I see what you mean regarding the low notes, LOL.
The attached zip contains the latest code, with the demo portion of the object split out, and it uses an array of 2 mono Karplus-Strong objects, so it should be able to scale to 4 objects just fine. This demo shows the left and right channels running at independent sampling rates. (Note: I had to change how each note's period is calculated to be able to handle the sampling rate specified at run-time instead of compile-time.)
You can pass in a value to the start routine to decide how to use the doubler: 0 means never, 1 means always switch, and any other value means always use the doubler. You can hear the difference in the sound (off has a fuller sound, on gets a lower note...I was hoping the automatic switch would give me the best of both worlds, but unless I can find th problem I'll just have to disable it).
Jonathan
Looks great! I can see from the demo how you'd go about adding more pins. Do they need to be different sampling rates, or can they be the same? I can't wait till I get home and can try it out!
Jonathan