BS2 Code Help for "arrays"
TonyA
Posts: 226
Hi,
This is modified code based on a midi out example in O'Sullivan's book "Physical Computing".
Notice the "array". I was wondering how I could go about creating 12 of these arrays, whose elements would be the notes of each of the 12 musical keys. So I thought there would be a total of 12 arrays (like the one in the example), each array would have 8 elements (which are the 8 notes of each musical key). My idea was to have a rotary switch that could be used to switch to different input pins, each diff input pin would be responcible for each of the 12 different arrays, hence you can switch to different keys.
But, when I tried adding the 12 arrays I received the "out of variable space" message. So I'm wondering if any more experienced programmers here might be able to offer advice or referrences. It would be greatly appreciated. Thank you in advance for any help.
(I've only worked with analog stuff before last week, I just learning pBasic, so maybe my idea can be simplified via programming.) I can post the code I wrote with the 12 different "arrays" if it would be useful.
' the 12 elements of the array called pitch are 12 notes of a scale.
pitch(0) = 58' middle C
pitch(1) = 35' C#
pitch(2) = 62' D
pitch(3) = 63' D#
pitch(4) = 74' E
pitch(5) = 87' F
pitch(6) = 52' F#
pitch(7) = 67' G
pitch(8) = 68' A
pitch(9) = 69' A#
pitch(10) = 70' B
pitch(11) = 100' C
Main:
' This is the note section. The sensor goes on pin 8, midiout is on pin 7
'
HIGH 8
PAUSE 1
RCTIME 8, 1, RCTIMEVar
note = RCTIMEVar / 60 ' convert to a range from 0 to 11
SEROUT 7, 12, [noparse][[/noparse]$90, pitch(note), $40]
'etc.
This is modified code based on a midi out example in O'Sullivan's book "Physical Computing".
Notice the "array". I was wondering how I could go about creating 12 of these arrays, whose elements would be the notes of each of the 12 musical keys. So I thought there would be a total of 12 arrays (like the one in the example), each array would have 8 elements (which are the 8 notes of each musical key). My idea was to have a rotary switch that could be used to switch to different input pins, each diff input pin would be responcible for each of the 12 different arrays, hence you can switch to different keys.
But, when I tried adding the 12 arrays I received the "out of variable space" message. So I'm wondering if any more experienced programmers here might be able to offer advice or referrences. It would be greatly appreciated. Thank you in advance for any help.
(I've only worked with analog stuff before last week, I just learning pBasic, so maybe my idea can be simplified via programming.) I can post the code I wrote with the 12 different "arrays" if it would be useful.
' the 12 elements of the array called pitch are 12 notes of a scale.
pitch(0) = 58' middle C
pitch(1) = 35' C#
pitch(2) = 62' D
pitch(3) = 63' D#
pitch(4) = 74' E
pitch(5) = 87' F
pitch(6) = 52' F#
pitch(7) = 67' G
pitch(8) = 68' A
pitch(9) = 69' A#
pitch(10) = 70' B
pitch(11) = 100' C
Main:
' This is the note section. The sensor goes on pin 8, midiout is on pin 7
'
HIGH 8
PAUSE 1
RCTIME 8, 1, RCTIMEVar
note = RCTIMEVar / 60 ' convert to a range from 0 to 11
SEROUT 7, 12, [noparse][[/noparse]$90, pitch(note), $40]
'etc.
Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·1+1=10
Thank you. Could you give me an example of how I would use LOOKUP in this case?
Tony
For the code you supplied the corresponding LOOKUP version would be:
LOOKUP index, [noparse][[/noparse]58, 35, 62, 63, 74, 87, 52, 67, 68, 69, 70, 100], result
index is the same value you used in defining your index, LOOKUP retrieves the value at location index and returns the value in result. You should have as few LOOKUP commands in your code since each occurance in the code results all the values being stored in your program space which leads to unnessesary code bloat. If you have serveral places in your program you need to access the same LOOKUP list, place the LOOKUP in a subroutine and call the subroutine instead.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·1+1=10
Thanks again. I see what you did. But what if I had 12 arrays each containing a different set of elements? Do I write that LOOKUP command 12 times (for the 12 arrays) or just once and put all of the different elements inside?
Tony
Notes··· DATA··· 10, 20, 30
········ DATA··· 40, 50, 60
········ DATA··· 70, 80, 90
You could keep two variables (nibs would work for your app) that store the row and col.· If you wanted to get the value from row #2, column #0 you could get it like this:
· READ (Notes * row + col), result
... which would return 70 in result.· By naming your table and using the name in the equation, it can be placed in anywhere, even when other DATA statments are used.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Post Edited (Jon Williams (Parallax)) : 7/29/2005 10:30:32 PM GMT
I'm starting to understand. I'll try both LOOKUP and DATA. Thanks again, Paul & John.
Tony
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·1+1=10
Would it look something like this:
index VAR Byte
result VAR Byte
rctimeVar VAR Word
HIGH pin#
PAUSE 1
RCTIME pin#, 1, rctimeVar
LOOKUP index, [noparse][[/noparse]values of the notes in the key of C...], result
LOOKUP index, [noparse][[/noparse]values of the notes in the key of C sharp...], result
(etc. up to 12 "LOOKUPs" for each musical key?)
index = rctimeVar/x (or would this be: result = rctimeVar/x) ' converts to a suitable range for the sensor or pot used.
serout pin#, baud, [noparse][[/noparse]$90, index1, $40]
How do you distinguish between each "index". Would you make each "index" a variable like index1, index2, etc.?
If "index" retrieves values (in my case the values are the notes in a particular key), I will need "index" to be a variable in order to constantly retrieve different values at any given time (it will need to retreive different notes in the key based on the input of a pot or other sensor using RCTime, etc.
Thanks again for any insight.
Tony
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Thanks for your help, I appreciate it very much.
The code I posted at the beginning of the thread (above) contained an "array" of notes for a simple midi out program that uses a variable resistor (pot or fsr, or photocell). The original program above is based on what I saw in O'Sullivan's book. With that program you can play all notes, but my idea is to be able to switch to different keys.
My goal is to build a midi controller that will allow you to switch to each of the 12 musical keys (i.e., key of C, key of C#, Key of D, and so on). Suppose I turn a 12 position rotary switch to the key of D, I will only be able to play the 8 notes of the key of D using my photocell or pot, then I swith to key of F#, I'll then only be able to play the 8 notes in the key of F#, and so on.
I want to write a program that will allow you to choose a specific musical key. I need to be able to choose from any of the 12 keys (each key would of course contain the 8 notes of that specific key) and be able to play any of the notes in that chosen key by using an fsr, or pot, or photocell.
Just to show you the inspiration for this idea here is the code based on O'Sullivan's example uses 1 array with 12 elements like this:
' the 12 elements of the array called pitch are 12 notes of a scale.
pitch(0) = 58' middle C
pitch(1) = 35' C#
pitch(2) = 62' D
pitch(3) = 63' D#
pitch(4) = 74' E
pitch(5) = 87' F
pitch(6) = 52' F#
pitch(7) = 67' G
pitch(8) = 68' A
pitch(9) = 69' A#
pitch(10) = 70' B
pitch(11) = 100' C
Main:
' This is the note section. The sensor goes on pin 8, midiout is on pin 7
'
HIGH 8
PAUSE 1
RCTIME 8, 1, RCTIMEVar
note = RCTIMEVar / 60 ' convert to a range from 0 to 11
SEROUT 7, 12, [noparse][[/noparse]$90, pitch(note), $40]
'etc.
I thought I could just make 12 arrays (one array for each of the 12 musical keys), and each of the 12 arrays would contain 8 elements which are the 8 notes of each key, but I have a lot of learning to do.
I'm still studying the DATA and LOOKUP commands. Hopefully one day I'll understand [noparse]:)[/noparse]
Thanks again
Tony
I whipped this up on my PDB and it works as expected.· Add a second version for reading the octave.· Valid MIDI notes are 0 - 127, so that is something less than the 144 a 12x12 array would give you, and the lowest note on the piano is well above 0, the highest well below 127.· I think your octave section -- if you want to stick to valid piano notes -- needs only to be 8 (0..7).
Here's the pot code:
Get_Note:
· HIGH NotePot
· PAUSE 1
· RCTIME NotePot, 1, noteVal
· noteVal = noteVal / 53
· RETURN
The variable, noteVal, is a Word.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
This is very cool, but where I am confused is how to set up the DATA statements, and then how to refer to the DATA in my main code.
(But I am slowly starting to see how this works. You mentioned using 2 pots; one for the col and one for the row?)
Thanks again, very much appreciated.
Tony
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
That's awesome. I'm studying what you did and I'll see if I can come up with my own versions. Thanks very much for the tremendous help, it's greatly appreciated.
Tony
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
One thing I'm working on is having multiple DATA tables (11 all together), that are referenced via different input pins and pots.
Each DATA table would consist of only the notes in a certain Key (rather than all notes and all octaves), with a couple of upper octaves and a couple of lower octaves for each key.
Something like this:
C, D, E, F, G, A, B, C
KeyofCmajor DATA Oct, Oct, Oct, etc.
DATA, etc.
DATA, etc.
C#, etc
KeyofCsharp DATA Oct, Oct, Oct, etc.
DATA, etc.
DATA, etc.
D, etc.
KeyofD DATA Oct, Oct, Oct, etc.
DATA, etc.
DATA, etc.
Coming up with the DATA tables will be fine, but I wonder if I'll run out of eeprom space or variable space. And also I'm working out who to reference eack individual DATA table.
Thanks for any insight.
Tony
Am I missing something? There's only 128 valid MIDI notes, so the table in the example I provided is all the EE space you should need. You can of course break that big table into smaller ones, but I don't think it will make your program any more effective.
If you want to give each octave a name, you can do it like this:
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Post Edited (Jon Williams (Parallax)) : 8/1/2005 5:16:34 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Yes, That's exactly it. I'm trying to create a scale in each key, that's why I thought of having multiple DATA tabes. There would be a rotary switch that would allow to acess the different scales via different input pins.
Suppose I had a force sensitive resistor that was attached to a 12 position rotary switch, I could access each pf 12 input pins, each input pin would access via programming each of 12 scales.
I have some idea of how to set of the individual DATA tables with the scales, etc.
I see what you did in your previous example, naming the octaves. Would it be possible to just change each octave to just different scales, or would I need to create a new table for each scale.
Does that make sense? I'm sorry for any confusion, I really do appreciate all of the help, I am learning a lot from you.
Thank you,
Tony
I don't think that would work, Yanow but thanks for your input, I appreciate it. Let's see if I can simplify what I'm trying to explain.
Jon's DATA table is great. But what if I just wanted to select a particular scale of notes to play, not all of the midi notes.
You select the DATA table that contains only the notes in the key of F#. Now when you play with your pot, or FSR you can only produce the notes of the scale F# and its octaves, no other notes are allowed. Then you want to switch to the scale C major, well then you can only play the notes in C major and its octaves, etc.
I think with the great help from Jon I can construct the DATA tables for each scale with octaves. I'll try to come up with something and then post it here.
I would have an FSR that would trigger the notes, then a pot that would switch ocatves in the scale, and then a rotary switch that will switch the FSR to different input pins, different input pins would allow access to the different DATA tables and hence different scales. Although, I'm not sure yet if I would need to access different input pins for this to occur.
Thanks again,
Tony
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Yes, I would use one pot for changing the note values and another for changing the octave values, which is what I want. But I was thinking of using separate DATA tables, one for each scale (12 major scales). We don't need to add separate tables for the minor scales because we can just play the relative minor scales of each major scale (just start on a different note, like playing a mode).
Thanks again,
Tony
Silly··· DATA··· 3, 0, 2, 4
The first value in the table is the number of notes -- the rest are the note values relative to a base.· You would set the base note (hence key) before calling a routine that might look like this:
PlayScale:
· LOOKUP scale, [noparse][[/noparse]Scale1, Scale2, Scale3], scaleAddr······· ' get address of scale
· READ scaleAddr, numNotes································ ' read number of notes in that scale
· FOR idx = 1 TO numNotes··································' cycle through scale
··· READ scaleAddr + idx, offset·························· ' read note offset
··· READ Notes + baseNote + offset, theNote··············· ' get note from table
··· SEROUt MidiOut, Baud, [noparse][[/noparse]$90, theNote, velocity]·········' send to MIDI device
··· PAUSE NoteTiming······································ ' delay as required
· NEXT
· RETURN
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
I think I came up with something. It's a much larger program with 12 DATA tables. I used the first program you wrote as a guide.
(I'm not sure, but I think I am not communicating the actual use of this prog clearly enough here, this is my fault. I think maybe if you saw what I wrote, even if it's wrong you'd probably see what I'm trying to do, and then probably show me a huge short cut.)
I'm pretty sure it could be condensed and made into a much smaller/cleaner prog. But I am learning a lot, particularly from your use of constants, subroutines, the use of eeprom data and read command.
I still have to study the new ideas you wrote, using the LOOKUP command above.
As soon as I check to see if it actually works and get my nerve up I'll post so you can have a look.
Thanks again for the great help and eductaion.
Tony