home *** CD-ROM | disk | FTP | other *** search
- /* pitchnames.c
- Copyright (c) 1993 by Thomas E. Janzen
- All Rights Reserved
-
- THIS SOFTWARE IS FURNISHED FREE OF CHARGE FOR STUDY AND USE AND MAY
- BE COPIED ONLY FOR PERSONAL USE OR COMPLETELY AS OFFERED WITH NO
- CHANGES FOR FREE DISTRIBUTION. NO TITLE TO AND OWNERSHIP OF THE
- SOFTWARE IS HEREBY TRANSFERRED. THOMAS E. JANZEN ASSUMES NO
- RESPONSIBILITY FOR THE USE OR RELIABILITY OF THIS SOFTWARE.
-
- Thomas E. Janzen
- 208A Olde Derby Road
- Norwood, MA 02062-1761
- (617)769-7733
-
- ** FACILITY:
- **
- ** AlgoRhythms music improviser on Commodore (TM) Amiga (TM)
- ** compiled with SAS/C Amiga Compiler 6.50
- **
- ** ABSTRACT:
- **
- ** pitchnames.c inter-converts pitch name strings and MIDI note numbers
- **
- ** AUTHORS: Thomas E. Janzen
- **
- ** CREATION DATE: 26-OCT-1993
- **
- ** MODIFICATION HISTORY:
- ** DATE NAME DESCRIPTION
- **--
- */
- #include <stdlib.h>
- #include <ctype.h>
- #include <string.h>
- #include <stdio.h>
- #include "pitchnames.h"
-
- #define C_HAS_ACCIDENTAL (3)
- #define C_NO_ACCIDENTAL (2)
- #define C_SMALL_SCALE_LEN (7)
- #define C_NOTES_PER_OCTAVE (12)
- #define C_A (9)
- #define C_B (11)
- #define C_C (0)
- #define C_D (2)
- #define C_E (4)
- #define C_F (5)
- #define C_G (7)
-
- int pitch_to_midi(const char *pitch_name)
- /*
- ** FUNCTIONAL DESCRIPTION:
- ** Converts a pitch name string to the represented MIDI note number
- ** ("C4" is middle C is MIDI 60; "C#4" is c-sharp above middle c (61);
- ** "Cb4" and "CB4" are the C-flat (B) below middle C (59).)
- ** If pitch_name was invalid, a zero is returned.
- **
- ** RETURN VALUE:
- ** description: MIDI note number
- ** data_type: int
- **
- ** ARGUMENTS:
- **
- ** pitch_name-
- ** description: name of pitch, e.g. C4, D#2, Gb6
- ** data_type: pointer char
- ** access: read only
- **
- ** DESIGN:
- ** ROUTINE
- ** : put length of input string into pitch_name_len
- ** : pitch_name_letter = toupper(force pitch_name[0])
- ** : IF pitch_name[0] is A..G, or pitch_name length is 2 or 3
- ** : THEN
- ** : : pitch_midi = small_scale[pitch_name_letter - 'A']
- ** : : IF (pitch_name_len == C_HAS_ACCIDENTAL)
- ** : : : SELECT toupper(pitch_name[1])
- ** : : : : CASE 'B'
- ** : : : : : lower pitch_midi by 1
- ** : : : : CASE '#'
- ** : : : : : raise pitch_midi by 1
- ** : : : ENDSELECT
- ** : : : octave = strtol(pitch_name[pitch_name_len - 1])
- ** : : : pitch_midi = pitch_midi + (C_NOTES_PER_OCTAVE * (octave + 1));
- ** : ELSE
- ** : : pitch_midi = 0
- ** : ENDIF
- ** : return pitch_midi
- ** ENDROUTINE
- */
- {
- auto int pitch_midi,
- pitch_name_len,
- octave,
- pitch_name_letter;
- const static int small_scale[C_SMALL_SCALE_LEN]
- = {C_A, C_B, C_C, C_D, C_E, C_F, C_G};
-
- /*
- ** Pre-compute the string length
- ** and force pitch_name[0] to uppercase and put into pitch_name_letter
- */
- pitch_name_len = strlen(pitch_name);
- pitch_name_letter = toupper(pitch_name[0]);
-
- if ( (pitch_name_letter >= 'A')
- || (pitch_name_letter <= 'G')
- || (pitch_name_len <= C_HAS_ACCIDENTAL)
- || (pitch_name_len >= C_NO_ACCIDENTAL)
- )
- {
- /*
- ** find the pre-accidental pitch number (A..G natural)
- */
- pitch_midi = small_scale[pitch_name_letter - 'A'];
- if (C_HAS_ACCIDENTAL == pitch_name_len)
- {
- /*
- ** If there is an accidental (sharp # or flat b)
- ** then adjust the pitch up or down a semitone
- */
- switch (toupper(pitch_name[1]))
- {
- case 'B': /* a flat */
- pitch_midi -= 1;
- break;
- case '#':
- pitch_midi += 1; /* a sharp */
- break;
- default:
- break;
- }
- }
- /*
- ** Extract the octave from the input string
- */
- octave = strtol(&(pitch_name[pitch_name_len - 1]), NULL, 10);
- /*
- ** Computer the MIDI pitch number
- */
- pitch_midi += (C_NOTES_PER_OCTAVE * (octave + 1));
- }
- else
- {
- /*
- ** input string was bad data, so return a zero.
- */
- pitch_midi = 0;
- }
- return pitch_midi;
- }
-
-
-
- void midi_to_pitch(const int note_num, char *pitch_name)
- /*
- ** FUNCTIONAL DESCRIPTION:
- **
- ** ARGUMENTS:
- **
- ** note_num-
- ** description: MIDI note number
- ** data_type: int
- ** access: read only
- **
- ** pitch_name-
- ** description: string of pitch name e.g. C#4, D#2, F1, E6
- ** data_type: pointer to char
- ** access: write only
- **
- ** DESIGN:
- */
- {
- /* convert MIDI note numbers to pitch name string */
- /* C4 is middle C is MIDI 60 */
- const char note_names[12][4] =
- {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};
- sprintf(pitch_name, "%s%1d", note_names[note_num % 12],
- (note_num / 12) - 1);
- return;
- }
-
-