electro-music.com   Dedicated to experimental electro-acoustic
and electronic music
 
    Front Page  |  Radio
 |  Media  |  Forum  |  Wiki  |  Links
Forum with support of Syndicator RSS
 FAQFAQ   CalendarCalendar   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   LinksLinks
 RegisterRegister   ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in  Chat RoomChat Room 
 Forum index » DIY Hardware and Software » ChucK programming language
Note to frequency table
Post new topic   Reply to topic Moderators: Kassen
Page 1 of 1 [17 Posts]
View unread posts
View new posts in the last week
Mark the topic unread :: View previous topic :: View next topic
Author Message
kruhft



Joined: Oct 20, 2006
Posts: 50
Location: Canada
Audio files: 5

PostPosted: Mon Oct 23, 2006 8:05 am    Post subject: Note to frequency table
Subject description: C5 => inst.freq;
Reply with quote  Mark this post and the followings unread

I wrote this to make working with ChucK ugens easier and for those that prefer working with note names (A4, Cs5, etc) rather than MIDI note numbers and Std.htof. This lets you write notes like this:

TubeBell tb => dac;
C3 => tb.freq;
1.0 => tb.noteOn;

Rather than looking up the MIDI values and so on and so forth. It makes setting frequencies prettier and easier, let's say. It might not be that useful right now since chuck doesn't support include files yet, but you can cut and paste the table into your code for now until that time comes.

Unfortunately I wrote it in C since it was just easier to hack it together for me at the time. There's instructions on how to build and use it for the unfamiliar, and, well if you don't have a C compiler you might be out of luck.

Just to make things easier on everyone, here's the table the program generates for A5=440Hz tuning:

Code:

8.17579892 => float C0;
8.66195722 => float Cs0;
8.66195722 => float Db0;
9.17702400 => float D0;
9.72271824 => float Ds0;
9.72271824 => float Eb0;
10.30086115 => float E0;
10.91338223 => float F0;
11.56232571 => float Fs0;
11.56232571 => float Gb0;
12.24985737 => float G0;
12.97827180 => float @s0;
12.97827180 => float Ab0;
13.75000000 => float A0;
14.56761755 => float As0;
14.56761755 => float Bb0;
15.43385316 => float B0;
16.35159783 => float C1;
17.32391444 => float Cs1;
17.32391444 => float Db1;
18.35404799 => float D1;
19.44543648 => float Ds1;
19.44543648 => float Eb1;
20.60172231 => float E1;
21.82676446 => float F1;
23.12465142 => float Fs1;
23.12465142 => float Gb1;
24.49971475 => float G1;
25.95654360 => float @s1;
25.95654360 => float Ab1;
27.50000000 => float A1;
29.13523509 => float As1;
29.13523509 => float Bb1;
30.86770633 => float B1;
32.70319566 => float C2;
34.64782887 => float Cs2;
34.64782887 => float Db2;
36.70809599 => float D2;
38.89087297 => float Ds2;
38.89087297 => float Eb2;
41.20344461 => float E2;
43.65352893 => float F2;
46.24930284 => float Fs2;
46.24930284 => float Gb2;
48.99942950 => float G2;
51.91308720 => float @s2;
51.91308720 => float Ab2;
55.00000000 => float A2;
58.27047019 => float As2;
58.27047019 => float Bb2;
61.73541266 => float B2;
65.40639133 => float C3;
69.29565774 => float Cs3;
69.29565774 => float Db3;
73.41619198 => float D3;
77.78174593 => float Ds3;
77.78174593 => float Eb3;
82.40688923 => float E3;
87.30705786 => float F3;
92.49860568 => float Fs3;
92.49860568 => float Gb3;
97.99885900 => float G3;
103.82617439 => float @s3;
103.82617439 => float Ab3;
110.00000000 => float A3;
116.54094038 => float As3;
116.54094038 => float Bb3;
123.47082531 => float B3;
130.81278265 => float C4;
138.59131549 => float Cs4;
138.59131549 => float Db4;
146.83238396 => float D4;
155.56349186 => float Ds4;
155.56349186 => float Eb4;
164.81377846 => float E4;
174.61411572 => float F4;
184.99721136 => float Fs4;
184.99721136 => float Gb4;
195.99771799 => float G4;
207.65234879 => float @s4;
207.65234879 => float Ab4;
220.00000000 => float A4;
233.08188076 => float As4;
233.08188076 => float Bb4;
246.94165063 => float B4;
261.62556530 => float C5;
277.18263098 => float Cs5;
277.18263098 => float Db5;
293.66476792 => float D5;
311.12698372 => float Ds5;
311.12698372 => float Eb5;
329.62755691 => float E5;
349.22823143 => float F5;
369.99442271 => float Fs5;
369.99442271 => float Gb5;
391.99543598 => float G5;
415.30469758 => float @s5;
415.30469758 => float Ab5;
440.00000000 => float A5;
466.16376152 => float As5;
466.16376152 => float Bb5;
493.88330126 => float B5;
523.25113060 => float C6;
554.36526195 => float Cs6;
554.36526195 => float Db6;
587.32953583 => float D6;
622.25396744 => float Ds6;
622.25396744 => float Eb6;
659.25511383 => float E6;
698.45646287 => float F6;
739.98884542 => float Fs6;
739.98884542 => float Gb6;
783.99087196 => float G6;
830.60939516 => float @s6;
830.60939516 => float Ab6;
880.00000000 => float A6;
932.32752304 => float As6;
932.32752304 => float Bb6;
987.76660251 => float B6;
1046.50226120 => float C7;
1108.73052391 => float Cs7;
1108.73052391 => float Db7;
1174.65907167 => float D7;
1244.50793489 => float Ds7;
1244.50793489 => float Eb7;
1318.51022765 => float E7;
1396.91292573 => float F7;
1479.97769085 => float Fs7;
1479.97769085 => float Gb7;
1567.98174393 => float G7;
1661.21879032 => float @s7;
1661.21879032 => float Ab7;
1760.00000000 => float A7;
1864.65504607 => float As7;
1864.65504607 => float Bb7;
1975.53320502 => float B7;
2093.00452240 => float C8;
2217.46104781 => float Cs8;
2217.46104781 => float Db8;
2349.31814334 => float D8;
2489.01586978 => float Ds8;
2489.01586978 => float Eb8;
2637.02045530 => float E8;
2793.82585146 => float F8;
2959.95538169 => float Fs8;
2959.95538169 => float Gb8;
3135.96348785 => float G8;
3322.43758064 => float @s8;
3322.43758064 => float Ab8;
3520.00000000 => float A8;
3729.31009214 => float As8;
3729.31009214 => float Bb8;
3951.06641005 => float B8;
4186.00904481 => float C9;
4434.92209563 => float Cs9;
4434.92209563 => float Db9;
4698.63628668 => float D9;
4978.03173955 => float Ds9;
4978.03173955 => float Eb9;
5274.04091061 => float E9;
5587.65170293 => float F9;
5919.91076339 => float Fs9;
5919.91076339 => float Gb9;
6271.92697571 => float G9;
6644.87516128 => float @s9;
6644.87516128 => float Ab9;
7040.00000000 => float A9;
7458.62018429 => float As9;
7458.62018429 => float Bb9;
7902.13282010 => float B9;
8372.01808962 => float C10;
8869.84419126 => float Cs10;
8869.84419126 => float Db10;
9397.27257336 => float D10;
9956.06347911 => float Ds10;
9956.06347911 => float Eb10;
10548.08182121 => float E10;
11175.30340586 => float F10;
11839.82152677 => float Fs10;
11839.82152677 => float Gb10;
12543.85395142 => float G10;


Here's the C source code:

Code:

// chuck_note2hz.c
//
// Creates a list of note variables assigned to their frequencies.
// Makes working with ChucK ugen instruments easier.
//
// eg.
//      TubeBell tb => dac;
//      C3 => tb.freq;
//      1.0 => tb.noteOn;
//
// Frequency values created with the following formula:
//
// 0 < n < 128:
// A = 440;
// (A/32) * (2^((n-9)/12))
//
// Build: cc -o chuck_note2hz chuck_note2hz.c -lm
//
// Usage: For the standard A5=440.0 tuning:
//            chuck_note2hz > midi2hz.ck
//        For a nonstandard tuning A5 != 440.0 HZ
//            A5=321.0 ./chuck_note2hz > midi2hz_A5_321.0.ck
//
// Author: Burton Samograd aka. kruhft .at. gmail - 2006
//
// License: Public Domain.  Do as thou wish.
//          Same with the generated code.

#define A5 440.0

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

int main() {
  int i;
  double a5;
  char *tmp = getenv("A5");

  if(tmp) a5 = strtod(tmp, 0);
  else  a5 = A5;

  char *n[] = { "C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B" };
 
  for(i=0;i<128;i++) {
   int note = i%12;
   double hz = (a5 / 32.0) * pow(2.0, (((double)i-9.0)/12.0));
   if(*(n[note]+1)) {
     printf("%.8f => float %cs%d;\n", hz, (*n[note])-1, i/12);
     printf("%.8f => float %s%d;\n", hz, n[note], i/12);
   } else
     printf("%.8f => float %s%d;\n", hz, n[note], i/12);
  }
}


Hopefully this is useful to some.


chuck_note2hz.c
 Description:
C Source code for note -> hz table generator.

Download (listen)
 Filename:  chuck_note2hz.c
 Filesize:  1.29 KB
 Downloaded:  433 Time(s)


note2hz.ck
 Description:
Resulting table from chuck_note2hz.c

Download (listen)
 Filename:  note2hz.ck
 Filesize:  4.71 KB
 Downloaded:  509 Time(s)


_________________
http://www.myspace.com/kruhft
http://kruhft.info
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
kruhft



Joined: Oct 20, 2006
Posts: 50
Location: Canada
Audio files: 5

PostPosted: Mon Oct 23, 2006 9:08 am    Post subject: Reply with quote  Mark this post and the followings unread

Here's the same program in bash, which is how I wanted to write it in the first place. It gives slightly different values near the bottom couple of digits in the numbers, probably from using bc, but I doubt it will do anything to the actual sound. Plus you don't have to compile this. You run it the same way.

Code:

#!/bin/bash
#
# chuck_note2hz.sh
#
# Creates a list of note variables assigned to their frequencies.
# Makes working with ChucK ugen instruments easier.
#
# eg.
#      TubeBell tb => dac;
#      C3 => tb.freq;
#      1.0 => tb.noteOn;
#
# Frequency values created with the following formula:
#
# 0 < n < 128:
# A = 440;
# (A/32) * (2^((n-9)/12))
#
# Usage: For the standard A5=440.0 tuning:
#            chuck_note2hz > midi2hz.ck
#        For a nonstandard tuning A5 != 440.0 HZ
#            A5=321.0 ./chuck_note2hz > midi2hz_A5_321.0.ck
#
# Author: Burton Samograd aka. kruhft .at. gmail - 2006
#
# License: Public Domain.  Do as thou wish.
#          Same with the generated code.

n=( C Db D Eb E F Gb G Ab A Bb B );
for i in `seq 0 127`; do
    a5=${A5:-440.0}
    octave=$(($i/12))
    note=${n[$(($i%12))]};
    hz=`echo "scale=8; ($a5 / 32.0) * e(l(2.0)*(($i-9.0)/12.0))" | bc -l`
    if [ ${#note} == 2 ]; then
   echo $hz '=>' ${note:0:1}s$octave';'
   echo $hz '=>' $note$octave';'
    else
   echo $hz '=>' $note$octave';'
    fi
done

_________________
http://www.myspace.com/kruhft
http://kruhft.info
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
mosc
Site Admin


Joined: Jan 31, 2003
Posts: 18240
Location: Durham, NC
Audio files: 224
G2 patch files: 60

PostPosted: Mon Oct 23, 2006 11:17 am    Post subject: Reply with quote  Mark this post and the followings unread

Just noted that we don't allow uploading of shell programs, .sh extensions. I just fixed this. Very Happy
_________________
--Howard
my music and other stuff
Back to top
View user's profile Send private message Visit poster's website AIM Address
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 7678
Location: The Hague, NL
G2 patch files: 3

PostPosted: Tue Oct 24, 2006 5:51 pm    Post subject: Reply with quote  Mark this post and the followings unread

kruhft, did you see "std.motf()"?
_________________
Kassen
Back to top
View user's profile Send private message Send e-mail Visit poster's website
kruhft



Joined: Oct 20, 2006
Posts: 50
Location: Canada
Audio files: 5

PostPosted: Tue Oct 24, 2006 6:23 pm    Post subject: Reply with quote  Mark this post and the followings unread

Yup, but this let's you write:

C4 => inst.freq;

as opposed to:

Std.mtof( // uhhh...what was the number for C4 again???
// google: midi c4, search.......what was I doing again?

You see what I'm saying? Just a nicer style for those that would like to use notes instead of numbers.

Plus using a directly assigned symbol is faster than calling a function, not that you're changing notes that frequently that it should matter that much.

_________________
http://www.myspace.com/kruhft
http://kruhft.info
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 7678
Location: The Hague, NL
G2 patch files: 3

PostPosted: Tue Oct 24, 2006 8:09 pm    Post subject: Reply with quote  Mark this post and the followings unread

Yeah, I get it, makes lots of sense for writing a score.

For a moment I feared you had done lots of work because of missing the mtof function, that would have been sad.

_________________
Kassen
Back to top
View user's profile Send private message Send e-mail Visit poster's website
kruhft



Joined: Oct 20, 2006
Posts: 50
Location: Canada
Audio files: 5

PostPosted: Tue Oct 24, 2006 8:20 pm    Post subject: Reply with quote  Mark this post and the followings unread

No work is lost work if you learned something or got experience from doing it... well, if you don't have someone that's paying you breathing down your neck that is...

Thanks for the concern though Smile

_________________
http://www.myspace.com/kruhft
http://kruhft.info
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
ge



Joined: Aug 13, 2006
Posts: 108
Location: Palo Alto, CA

PostPosted: Tue Oct 24, 2006 10:43 pm    Post subject: Reply with quote  Mark this post and the followings unread

Here is a Note class with a lot of static members, if you don't want to copy or generate the code every time. Just run Note.ck once in the VM, and then refer to notes as Note.A4 or ...

The only thing is now you gotta prefix the note with Note.

Not sure if this is an improvement.


Note.ck
 Description:

Download (listen)
 Filename:  Note.ck
 Filesize:  8.42 KB
 Downloaded:  503 Time(s)

Back to top
View user's profile Send private message Visit poster's website
kruhft



Joined: Oct 20, 2006
Posts: 50
Location: Canada
Audio files: 5

PostPosted: Wed Oct 25, 2006 2:23 am    Post subject: Reply with quote  Mark this post and the followings unread

I noticed the keyword 'global' in the parser source. This seems to fix the 'problem' with all variables being global instead of file local but I haven't gotten to test yet. Would this help with cross module references?

I shouldn't write this when I am as drunk as I am...haha er...ha?

werd

_________________
http://www.myspace.com/kruhft
http://kruhft.info
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
kijjaz



Joined: Sep 20, 2004
Posts: 765
Location: bangkok, thailand
Audio files: 4

PostPosted: Wed Oct 25, 2006 12:54 pm    Post subject: Reply with quote  Mark this post and the followings unread

i've got an idea..
hmm let's write a function that we can pass on the note letter
(a b c d e f g)
and accidental (bb b # x)
and octave number


Code:
fun float ntof(string note, string accidental, int octave) {
      0 => int m;
      if (note == "c") 0 => m;
      else if (note == "d") 2 => m;
      else if (note == "e") 4 => m;
      else if (note == "f") 5 => m;
      else if (note == "g") 7 => m;
      else if (note == "a") 9 => m;
      else if (note == "b") 11 => m;
      
      if (accidental == "#") 1 +=> m;
      else if (accidental == "x") 2 +=> m;
      else if (accidental == "b") 1 -=> m;
      else if (accidental == "bb") 2 -=> m;
      
      octave * 12 +=> m;
      return Std.mtof(m);      
}

// example of use:
<<< ntof("a", "​", 5) >>>; // a natural (octave 5)
<<< ntof("a", "#", 5) >>>; // a sharp
<<< ntof("a", "x", 5) >>>; // a double sharp
<<< ntof("a", "b", 5) >>>; // a flat
<<< ntof("a", "bb", 5) >>>; // a double flat


i hope it'd be more flexible for general use ^^"
(but now it's only for int midi number..
no microtones this time lol... Embarassed
Back to top
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger MSN Messenger
ian-s



Joined: Apr 01, 2004
Posts: 2672
Location: Auckland, New Zealand
Audio files: 42
G2 patch files: 626

PostPosted: Wed Oct 25, 2006 1:36 pm    Post subject: Reply with quote  Mark this post and the followings unread

Wow, Chuck doesn't have a switch/case statement. Shocked
Back to top
View user's profile Send private message
kijjaz



Joined: Sep 20, 2004
Posts: 765
Location: bangkok, thailand
Audio files: 4

PostPosted: Wed Oct 25, 2006 9:54 pm    Post subject: Reply with quote  Mark this post and the followings unread

Shocked last night i wondered about it too.
i hope we'll see it soon in the next version ^_^
Back to top
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger MSN Messenger
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 7678
Location: The Hague, NL
G2 patch files: 3

PostPosted: Wed Oct 25, 2006 10:36 pm    Post subject: Reply with quote  Mark this post and the followings unread

kijjaz wrote:
[color=#113355]i've got an idea..
hmm let's write a function that we can pass on the note letter



Cool, I have another idea; let's use overloading, write a version of kijaz's code, then hope it works. Smile


Code:

//this will make us lose the quotes later for nicer looking statements.
"a" => string a;
"b" => string b;
"c" => string c;
"d" => string d;
"e" => string e;
"f" => string f;
"g" => string g;

//first half of the function; natural notes

fun float ntof(string note, int octave) {
      0 => int m;
      if (note == "c") 0 => m;
      else if (note == "d") 2 => m;
      else if (note == "e") 4 => m;
      else if (note == "f") 5 => m;
      else if (note == "g") 7 => m;
      else if (note == "a") 9 => m;
      else if (note == "b") 11 => m;
      else <<< "ntof; error", note,  "is not a note" >>>;


      octave * 12 +=> m;
      return Std.mtof(m);      
}

//second half; everything else.

fun float ntof(string note, string accidental, int octave) {
      0 => int m;
      if (note == "c") 0 => m;
      else if (note == "d") 2 => m;
      else if (note == "e") 4 => m;
      else if (note == "f") 5 => m;
      else if (note == "g") 7 => m;
      else if (note == "a") 9 => m;
      else if (note == "b") 11 => m;
      else <<< "ntof; error", note,  "is not a note" >>>;


      if (accidental == "#") 1 +=> m;
      else if (accidental == "x") 2 +=> m;
      else if (accidental == "b") 1 -=> m;
      else if (accidental == "bb") 2 -=> m;
      else <<< "ntof; error", accidental,  "is not a accidental" >>>;


      octave * 12 +=> m;
      return Std.mtof(m);      
}

// example of use:
<<< ntof(a,  5) >>>; // a natural (octave 5)
<<< ntof(a, "#", 5) >>>; // a sharp
<<< ntof(a, "x", 5) >>>; // a double sharp
<<< ntof(a, "b", 5) >>>; // a flat
<<< ntof(a, "bb", 5) >>>; // a double flat


So; I didn't test this but I'm fairly certain it should work. Note that calling natural notes is now a bit less awkward, we also get to lose some of the quotes in the call though not all of them (I don't think you can name a string "#"). I also threw in some rudimentary error checking because this looks like a bit of code that has a good chance of having to deal with lots of manual input, chances are there'll be some errors in in that might otherwise be hard to trace.

All of this should get way better as soon as we get real string management....

_________________
Kassen
Back to top
View user's profile Send private message Send e-mail Visit poster's website
kijjaz



Joined: Sep 20, 2004
Posts: 765
Location: bangkok, thailand
Audio files: 4

PostPosted: Wed Oct 25, 2006 11:03 pm    Post subject:   Reply with quote  Mark this post and the followings unread

wow Kassen!
yes that's more like it, it's convenient.

{ i'll add that and to my library lol..
but i might force the strings to be all Capital letters (A B C D E F G)
so that we can use a b c d e f g with something else in the future.. }

i haven't been chucking around lately -_-" sigh..
Back to top
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger MSN Messenger
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 7678
Location: The Hague, NL
G2 patch files: 3

PostPosted: Thu Oct 26, 2006 12:02 am    Post subject: Reply with quote  Mark this post and the followings unread

Happy to have been of asistance. Maybe it should indeed be uppercase; I don't know that much about tradional notation and I'm into ChucK partially to be able to deal with things like that on my own terms so I have no real use for this myself.

One thing that uccured to me while taking a morning walk to ge tthe all-esential nicotine is that perhaps it could be overlaoaded still more. Maybe it would be convenient to have a seperate variable that would keep track of the last octave used so t yhat you could just refer to note names (without the octave) as long as they are in the same ovtave as the last, the function would fill in the last used octave if noe was specified.

That sounds quite natural to me, when musicians talk about a "F" they tend to know what F was meant and they don't go down to 10.9Hz just because no octave got specified and talking about octaves all the time gets tedious.

Might not be suitable for you, of cource, I'm not realy sure what you want to do with this.

Once this turns out to be usefull in practice we could put it on the Wiki and make ChucK look apealing to traditional musicians.

Another note, maybe it would be nice if we could feed stk.mtof() Scala files, that way we could tune ChucK to Werckmeister without needing a huge train of exceptionally boring lines

_________________
Kassen
Back to top
View user's profile Send private message Send e-mail Visit poster's website
moudi



Joined: Oct 07, 2006
Posts: 63
Location: Bern Switzerland

PostPosted: Thu Oct 26, 2006 8:03 am    Post subject: Reply with quote  Mark this post and the followings unread

wow Cool
both ways will make chucking much more easier!
but... now i have to think about wich one to take Wink

big up to all of you
/moudi
Back to top
View user's profile Send private message Visit poster's website
utenzil



Joined: Apr 10, 2006
Posts: 58
Location: maryland

PostPosted: Wed Jan 24, 2007 4:59 pm    Post subject: table of midi, freq, note labels and octave Reply with quote  Mark this post and the followings unread

I used the frequencies posted by kruhft to create this table, feel free to use it as you like, particularly if you would like to use it in a lookup structure of note objects where one could basically pull out the corresponding other thing given any correct thing input Smile

http://utenzil.com/notes_contd.txt

For example, the frequency by asking asking for "C#0"
For example, the midi note number by asking asking for "C#0"

(The "midi" value is off by one, I know, it should start at 0 [edit] this was a special use table used to populate an array, the 1 based count made it easier at the time)

Here is a generic table that includes the 1-based ordinal and the actual midi note value

http://www.utenzil.com/midi_note_table.htm

_________________
Utenzil
http://utenzil.com
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic Moderators: Kassen
Page 1 of 1 [17 Posts]
View unread posts
View new posts in the last week
Mark the topic unread :: View previous topic :: View next topic
 Forum index » DIY Hardware and Software » ChucK programming language
Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Forum with support of Syndicator RSS
Powered by phpBB © 2001, 2005 phpBB Group
Copyright © 2003 through 2009 by electro-music.com - Conditions Of Use