Propellamin - Need help from those familiar with music + audio programming
watermoccasin
Posts: 1
Hi, I'm new to the forums and just started working with the propeller, and have a few questions for my first project.
First a little about the project . . .
Currently dubbed the propellamin, the device will be a propeller-controlled theremin-like instrument, using sonar (PING) rather than radio-freqency as input for frequency and volume.
I have many ideas that will be able to take advantage of a digitized version of this instrument, and the first is programming a specific pitch to a range, allowing the musician to easily play in any key. With the help of forum member Casslan, I have tied an average (AVG) of ping readings to an existing pitch-generator program with a table linking range to pitch, but I cannot seem to play frequencies that are not a whole number. I am able to get very close to an actual scale, but especially at lower frequencies this is very limiting. Below is the code I currently have for playing this instrument in C Maj.
Below is how the table should read:
My first questions for the forum are these:
**How can I get the pitch generator to generate a pitch that is not a whole number?
Does anyone have an idea for the code that would allow the pitch to slide smoothly from one specific note to the next while playing?
Is there a way to control the volume for the pitch generator with programming? If not I plan on using a digital potentiometer to control the signal coming from the generator.
Thanks for your help. I will try to keep progress updated, and if anyone has any other ideas for this project I am happy to hear any advice!
First a little about the project . . .
Currently dubbed the propellamin, the device will be a propeller-controlled theremin-like instrument, using sonar (PING) rather than radio-freqency as input for frequency and volume.
I have many ideas that will be able to take advantage of a digitized version of this instrument, and the first is programming a specific pitch to a range, allowing the musician to easily play in any key. With the help of forum member Casslan, I have tied an average (AVG) of ping readings to an existing pitch-generator program with a table linking range to pitch, but I cannot seem to play frequencies that are not a whole number. I am able to get very close to an actual scale, but especially at lower frequencies this is very limiting. Below is the code I currently have for playing this instrument in C Maj.
VAR long range long Samples, AVG, SUM byte counter long Frequency byte numofsamples OBJ Term : "FullDuplexSerialPlus" ping : "ping" Synth : "Synth" PUB Start Term.StartPST(115200) numofsamples:= 5 repeat Term.CursorHome repeat counter from 0 to numofsamples ' Repeat Forever Samples[noparse][[/noparse]counter+1] := Samples[noparse][[/noparse]Counter] Samples[noparse][[/noparse]0] := ping.Ticks(PING_Pin) ' Position Cursor ' Print Fractional Part 'waitcnt(clkfreq / 10 + cnt) ' Pause 1/10 Second SUM:=0 repeat counter from 0 to numofsamples SUM := SUM + Samples[noparse][[/noparse]counter] AVG := (SUM/numofsamples) AVG := AVG -100 case AVG 0..100: Frequency := 131 'C3 101..200: Frequency := 147 'D3 201..300: Frequency := 165 'E3 301..400: Frequency := 175 'F3 401..500: Frequency := 196 'G3 501..600: Frequency := 220 'A3 601..700: Frequency := 245 'B3 701..800: Frequency := 262 'C4 801..900: Frequency := 294 'D4 901..1000: Frequency := 330 'E4 1001..1100: Frequency := 349 'F4 1101..1200: Frequency := 392 'G4 1201..1300: Frequency := 440 'A4 1301..1400: Frequency := 494 'B4 1401..1500: Frequency := 523 'C5 Synth.Synth("A", 10, Frequency) Term.Str(String("AVG-100: ")) Term.dec(AVG) Term.str(string(" ")) ' Print Inches Term.CarriageReturn Term.Str(String("FRE: ")) Term.dec(Frequency) Term.str(string(" ")) ' Print Inches Term.CarriageReturn
Below is how the table should read:
0..100: Frequency := 130.81 'C3 101..200: Frequency := 146.83 'D3 201..300: Frequency := 164.81 'E3 301..400: Frequency := 174.61 'F3 401..500: Frequency := 196 'G3 501..600: Frequency := 220 'A3 601..700: Frequency := 246.94 'B3 701..800: Frequency := 261.63 'C4 801..900: Frequency := 293.66 'D4 901..1000: Frequency := 329.63 'E4 1001..1100: Frequency := 349.23 'F4 1101..1200: Frequency := 392 'G4 1201..1300: Frequency := 440 'A4 1301..1400: Frequency := 493.88 'B4 1401..1500: Frequency := 523.25 'C5
My first questions for the forum are these:
**How can I get the pitch generator to generate a pitch that is not a whole number?
Does anyone have an idea for the code that would allow the pitch to slide smoothly from one specific note to the next while playing?
Is there a way to control the volume for the pitch generator with programming? If not I plan on using a digital potentiometer to control the signal coming from the generator.
Thanks for your help. I will try to keep progress updated, and if anyone has any other ideas for this project I am happy to hear any advice!
Comments
You may want to look at the counters as a method to generate high res frequencies. Then take those hi frequencies and divide them down to a usable frequency for the real world. This way you can move from note to note (gliss) in large numbers (up to 32 bits, but the output is divided down to notes in a usable range. So for every counter pulse, you output a counter value divided by X (maybe even 10, 100, or 1000).
Someone else may know a way to divide the counter output, but two ideas that come to mind:
1. Output a counter at frequency X on a pin that represents a hi res note value (i.e. A440 would be counter freq of 440,000, send back to an input, divide the input by some fixed value to produce usable musical frequencies and output the result.
or
2. Operate a counter at a frequency, divide the counter with some means internally. My counter experience is limited but there is an app note on the Prop info areathat is very informative.
Either method should allow sliding between notes once you get it sorted out. The hi res frequency can be easily added to or subtracted from to.
Using low res (real world frequencies) as you are dong in your code will not allow for any smooth transitions between whole or half notes.
The Ping input could be the controlling factor for the counters frequency, and you could change the counters output in real time with the Ping. You could also quantize the output with case statements.
As for the the smooth transition, it would be a math function... you could try this: Frequency := -56036 / AVG + 560
I think I did that right.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
April, 2008: when I discovered the answers to all my micro-computational-botherations!
HSS
I will be releasing my code for my musical device, along with the schematics, and with it you can eaisly attach a theremin.
And it would be very easy to program a theremin input on it and have it represent one of many sound waveform modifiers.
I do it with my prop fx/sequencer.
I don't have a theremin, or its schematics, but im sure if I looked into it, it would be easy to make it be a frequency modifier.
The same could be done with a 1-axis accelerometer. 3 axis would get fun.
I have the one below and plan to program it to do whatever i want.
http://www.parallax.com/Store/Sensors/AccelerationTilt/tabid/172/CategoryID/47/List/0/Level/a/ProductID/97/Default.aspx?SortField=ProductName,ProductName
Post Edited (Clock Loop) : 7/22/2009 9:38:38 PM GMT
What you need is a DDS Tone Generator (DDS=Direct Digital Synthesis) with a PWM modulated output to control
the volume.
There are some objects for the Hydra (i.e. the HSS that ClockLoop suggested). They normally need to be coded
in Assembly, but for a simple Test (and to show the concept) it's also possible within Spin:
This starts a new cog for generating a frequency with volume control. You can control this parameters
from the Main loop with the 2 variables: freq and volume (for range see comments in VAR section).
There are 3 waveforms in the example which you can change by uncommenting 1 of the 3 "frqa := ..." lines.
For your Theremin you can have 2 Ping sensors.
The first ping controls the frequency:
freq := AVG1 * 100_000
The second controls the volume:
volume := AVG2 * 2000
Andy
The frequency is spec'd as integer Hertz, but you could probably modify it to work in hundredths of Hertz...
(I.e., Instead of giving it 440 for 440 Hz, just give it 44000 and then modify the code as required...)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
My Prop Info&Apps: ·http://www.rayslogic.com/propeller/propeller.htm
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
My Prop Info&Apps: ·http://www.rayslogic.com/propeller/propeller.htm