aboutsummaryrefslogtreecommitdiff
path: root/n2m.c
diff options
context:
space:
mode:
Diffstat (limited to 'n2m.c')
-rw-r--r--n2m.c131
1 files changed, 131 insertions, 0 deletions
diff --git a/n2m.c b/n2m.c
new file mode 100644
index 0000000..bd0f0ee
--- /dev/null
+++ b/n2m.c
@@ -0,0 +1,131 @@
+#ifdef NT
+#include "stdafx.h"
+#include <io.h>
+#include<stdio.h>
+#endif
+#include "m_pd.h"
+#include <stdlib.h>
+#include<time.h>
+#include "n2m.h"
+
+char* notes_up[12] = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};
+int octaveoffset[11] = { 0 , 12, 24 ,36, 48, 60, 72, 84, 96, 108 ,120 };
+
+/**
+* The n2m object is designed to output a midi note number
+* in response to a note name of the form <note name><octave>
+* for example C5 or D#3.
+*/
+
+static t_class *n2m_class;
+
+/*
+* make a new n2m it takes one parameter - the percentage error
+*/
+
+static void *n2m_new( t_float f )
+{
+ t_n2m *x = (t_n2m *)pd_new(n2m_class);
+ // make us an output for the note number
+ outlet_new(&x->x_obj, gensym("float"));
+ return (x);
+}
+
+static void n2m_free(t_n2m *x)
+{
+ // nothing doing here for now
+}
+
+/**
+* set the error factor
+*/
+
+static void n2m_notename( t_n2m *x, t_symbol *s, int ac, t_atom *av )
+{
+ char buf[255];
+ char note[255];
+ int octave;
+ int i;
+ for( i = 0 ; i < ac ; i++ )
+ {
+ atom_string( &av[i] , buf, 255 );
+ //post("Symbol [%s]", buf );
+ splitsym( buf , note , &octave );
+ //post( "Which is %s note and %u octave and midi value %d" , note , octave , midilookup( note , octave ) );
+ outlet_float( x->x_obj.ob_outlet , midilookup( note , octave ) );
+ }
+}
+
+/**
+* make a new one and setup all of our messages
+*/
+
+ void n2m_setup(void)
+{
+ n2m_class = class_new(gensym("n2m"), (t_newmethod)n2m_new,
+ (t_method)n2m_free, sizeof(t_n2m), 0, 0);
+ class_addmethod(n2m_class, (t_method)n2m_notename, gensym("note" ), A_GIMME, 0);
+ class_sethelpsymbol(n2m_class, gensym("mjLib/n2m"));
+}
+
+/**
+* splitsym takes a note symbol and splits it into note and octave
+* if note not specified it defaults to C and if octave not specified
+* it defaults to 4
+*/
+
+static void splitsym( char* buf , char* note, int* octave )
+{
+ int i,j;
+ int split = -1;
+ for( i = 0 ; buf[i] != 0 ; i++ )
+ {
+ if ( ( buf[i] >= '0' ) && ( buf[i] <= '9'))
+ {
+ split = i;
+ if ( i > 0 )
+ {
+ for( j=0; j < i;j++) { note[j] = buf[j]; }
+ note[i] = 0;
+ }
+ else
+ {
+ note[0] = 'C';
+ note[1] = 0;
+ }
+ sscanf( buf + i , "%u" , octave );
+ break;
+ }
+ }
+ if ( split == -1 )
+ {
+ i = 0;
+ while( buf[i] != 0 )
+ {
+ note[i] = buf[i];
+ i++;
+ }
+ note[i] = 0;
+ *octave = 4;
+ }
+}
+
+/**
+* return a midi note value for a given note name and octave
+*/
+
+static int midilookup( char* note , int octave )
+{
+ int i,j;
+ int nnum = 4;
+ for( i = 0 ; i < 12 ; i++ )
+ {
+ if ( stricmp( note , notes_up[i]) == 0)
+ {
+ nnum = i;
+ break;
+ }
+ }
+ return octaveoffset[octave + 1 ] + nnum;
+}
+