/* Copyright (c) 2002-2004 by Stanley M. Swanson.
Distributed under the GNU General Public License, version 2 (GPL v2). */
/* globals.h from midivamp.c 035.26 */
/* midivamp.c 1-sep-2002 xml like supercommands to control repetitions, vamping */
/* 29-jan-2003: events, params, chunk changes.. (major cleanup) */
/* add command driven generation 7-May-2002 */
/* split off miditest.c 18-Feb-2001 */
/* start parsing of abc like files for pitch-tune and rhythm info */
/* midigen.c, stan swanson 7-Jan-2001 */
/* merge melody line (tune), rhythm, and dynamics to produce MIDI file */
# include
/* # include */
# include /* for time stamp on logfile */
# include
# include
# include
# define MAXOUT 80000 /* size of MIDI out buffer bout[] */
# define MXNOTE 4096 /* decoded abc stuff (melody, vamp, chords) */
# define MXHELP 17 /* command options printed with help '?'*/
# define MXMFILE 50 /* number of temporary MIDI output files */
# define MXATFILE 10 /* depth of indirect file nesting '@' */
# define MXLIST 23 /* maximum list elements +3 */
# define MAXIN 136 /* length of input buffers */
# define MXCHUNK 400 /* number of abc chunks input */
# define MXMETA 21 /* number of */
# define MXCHAR 4096 /* characters for string storage */
# define MXGC 2048 /* characters in guitar chords */
# define MXACC 4096 /* accent entries for phrasing */
# define MXFRAG 4096 /* fragment storage (repeats, chord limits) */
# define MXVAR 400 /* events for program-variation */
# define MXPT 512 /* selected notes stone[], stick[]; veloc[], emphasis[] */
# define NCHORDS 24
/* global variables, defined in globals.c */
# ifndef _GLOBALS_C_
extern int Q_META, Q_ABC, Q_PHRASE, Q_CHORD, Q_VAMP, Q_LOOP, Q_EVENT,
Q_ACCENT, Q_EXPERT, V_CLASS,
Q_VERBOSE, Q_PLAY, Q_BLUR, Q_TESTA, Q_TESTB, EXPAND_CHORDS;
float H_raw_part, H_root_wt;
/* pseudo enums for abc syntactic constructs (non-notes) cf. nextnote() */
extern const int E_REST, E_KEY, E_START_CHORD, E_END_CHORD, E_GUITAR_CHORD,
E_TIE, E_BAR, E_REP, E_REP_1, E_REP_2, E_REP_last;
/* for chunk[].type */
extern const int T_MEL, T_VAMP, T_CHORD, T_ACCENT, T_PHRASE, T_SPECIAL;
extern int lch, nline, chunks, kphr,nstr,n_meta,ntoken,n_save_chr,
ixgch, error_count, over_flows;
extern int qswap, nout, quantum,npitch,nbeat, repeats, chordflag,
beat_usec, total_ticks, quarterticks, staccato;
extern float bpm;
extern int measure, tictoc, previ, ticks_in_meas, meter_num, meter_denom, default_note;
extern int n_meas_tick, meas_tick[6], meas_tick_count[6]; /* measure length statistics */
extern int gen_ticks, gen_meas, gen_rep, next_event_epoch, gen_epoch;
extern int doremi[25], intervals[27], last_tone, tune_tonic,
tonal_center, mode_delta, key_major, central_tone;
/* for relative pitch and intervals */
extern int tuple_p, tuple_q, tuple_r, tuple_count, broken_rhythm; /* 020.11 */
int tonic, key, kromote[10], whitenote[10], barnote[10], dwell[12];
int cur_chr, ix_chr; /* global current character and index in line[] */
extern char line[MAXIN]; /* global character input buffer */
/* session prefix for .log, .nnn.midi files, comments for midi_info */
extern char session[MAXIN], commenta[MAXIN],commentb[MAXIN],title[MAXIN],
token_buf[MAXIN], *tok_start, *copyleft, made_id[16];
extern FILE *fout; /* global output file pointer */
extern FILE *fin[MXATFILE], *flog, *filin;
extern int at_file, ksession, kc, dot_sess, abc_index;
extern char bout[MAXOUT]; /* MIDI output buffer */
extern char *guitar_ch_1, *guitar_ch_2, *guitar_ch_3, *guitar_ch_4;
extern char chunkname[MXCHUNK][8], sav_strings[MXCHAR], guitar_ch[MXGC],
*tokens[MXCHUNK];
extern int pitch[MXNOTE], tics[MXNOTE], scale[128]; /* 031.29 vel[MXNOTE] */
extern int epoch[MXNOTE], event[MXNOTE], efirst[MXCHUNK],elast[MXCHUNK];
/* pointers to repetition structure in current tune (: [n etc.) */
extern int krep, rep_mark[20];
extern int solo_chan, map_voice_to_chan[16]; /* 032.20 instrument mappings */
/* 031.29: a structure to handle named melodies, vamps, chord sequences and accents */
extern struct {char* name; int type, count, ix, lx; } chunk[MXCHUNK];
/* sanity counters for chunks, also used for defaulting */
extern int accent_count, melody_count, chord_count, vamp_count, phrase_count;
extern int last_mel, last_chord, last_intro, last_vamp;
/* 031.29 start:(stop+1) pairs for complicated chunks(count>0) */
extern int kfrag, kev, frags[MXFRAG], jot[100];
/* 031.29: params for staccato, mix volume, pan, etc. may go into voice struct */
extern int mix_mel, mix_ch, stac_mel, stac_ch, pan_mel, pan_ch;
extern int trans_mel, trans_ch; /* transpose delta in halftones */
/* a start on varation/program events for generation: */
extern struct { int type, rep, meas, tick, chunk, data; } events[MXVAR];
extern int nmeta;
extern char *metacmd[MXMETA];
/* pseudo enum for metacommand ID (== index postion of string) */
# define MC_QUIT 1
# define MC_MELODY 2
# define MC_VAMP 3
# define MC_CHORDS 4
# define MC_ACCENT 5
# define MC_VARIATION 6
# define MC_LOOP 7
# define MC_INSTRUM 8
# define MC_TEMPO 9
# define MC_GEN 10
# define MC_HARMONY 11
# define MC_REPEAT 12
# define MC_MIDI 13
# define MC_PARAM 14
# define MC_EVENT 15
# define MC_XTRA 16
# define MC_PHRASE 17
/* trial velocities for vamp phrasing, 028.25, phrase and dynamics 042.27 */
extern int iacc, lacc, kacc, macc; /* accent limits and counter */
extern int idyn, kdyn, ldyn, deldown, delup, deloff, master_volume, volume_delta;
extern int nphrase, kphrase, iphrase, lphrase,n_emph;
extern int phrasing[MXACC],veloc[MXPT],emphasis[MXPT];
/* commands and short explanations for help */
extern char *help[MXHELP];
/* x_list[0] is a flag: 0: enumerated, 1: 'for' list
if enumerated, n = x_list[1] is the number of elements,
x_list[2] is current element in the enumeration
and x_list[3...n+2] are the values
if 'for', one iterates (for i=x_list[3]; i0 if exact,
<0 for "best approximate match" ("longest" partial match) */
/* 035.17 nlist<0 means search backwards (from top of list) */
int match_token(char *token, char **list, int nlist, int exact);
int save_token(char *token, char **list, int *nlist);
char *make_id(char *token, char *prefix, int kount);
FILE* new_file(char* name, char* how);
int stack_files(FILE* fi);
int pop_file(void);
int abc_ticks(int ip, int lp);
int find_measures(int chunk, int verbose);
int select_notes(int nstart, int nend, int period, int mode, int barbreak);
void select_accented(int beats);
int pedometer(int dur); /* which step (beat) in phrase */
/* loops parser lin vamp_loops.c */
int loop_in(void);
/* in vamp_midi.c ======================*/
void lowendian(int n, char *in, char *out);
void intout(int i);
void shout(short sh);
void strout(char *str, int n);
void byteout(int v); /* positive byte output 0-127 */
void delta(int v); /* MIDI variable count, eventually up to 128^4 - 1 */
void command(int cmd, int chan, int note, int veloc);
void change(int cmd, int chan, int prog);
void midi_file_header(int org, int tracks, int delta_time, char *name);
void microseconds_in_beat(float bpm);
void midi_info(char *title);
int spawn_play(char *midifile);
void generate_loops(char *midiout);
void session_prefix(void);
void pack_event( int *kx, int ticks, int cmd, int chan, int d1, int d2);
int sort_gen_events(int *kx, int *previous, int now);
int start_midi_music_track(int instrum, int chan, int chords);
int gen_midi_music_track(int npi, int npf, int chan, int chords);
int write_midi_music_track(void);
/* deal with fragments (from repeats) and possible endings
"[3" for last time through and (coda != 0) */
/* also translate chord list into fragments,
vamp should work since count==0 */
void gen_midi_frags(int kchunk, int chan, int chords, int coda);
/* in vamp_abc.c =====================*/
void set_meter(void); /* look at line[] for meter info */
void set_default_note(void); /* look for default note length */
int kromatic( int delta, int octave, char accidental);
void set_key(void); /* look at line[] for key signature */
int nextnote(int *tone, int *duration);
void read_music(void);
/* read .abc file to get both pitch contour and rhythm */
int read_abc(int act, char* filnam);
/* convert rep_mark[0:krep] to fragments for current melody */
void repeat_frags(void);
/* ------------ in vamp_harm.c ---------------*/
void analyse_harmony(char *line);
/* total abc duration tics[ip] ... tics[lp-1] */
void print_all_chords(int tonic, int nchords);
int chord_number(char *gc); /* convert guitar chord string to internal code */
void save_chord_scores(int meas, int *jot, int n);
int consonances(int nstart, int nend);
/* try to find tonal center from notes */
int find_center(int nstart, int nend, int meas, int tonic,
int period, int verbose );
void set_chord_prefs(int tn);
int analyse_notes(int tonic, int verbose, int mode); /* chord matches for multiple measures */
void find_chord(int nstart, int nend, int tonic, int period, int verbose);
int print_chord_matches(int n, int *jot, float *dwells, int dur, int verbose, FILE* fo);
int calc_wt_sums(int *jot, float *dwells, int *diver, int *durat);
int test_all_chords(int tonic, int verbose, int mode);
int halfmeas(int ki, int kf); /* compare full to half measure scores */
int other_alg(int ki, int kf); /* root emphasis, long notes, leaps (Kaufmann, Couch) */
/* int major_minor(int nstart, int nend, int meas, int tonic, int period, int verbose); */
void print_stats(FILE *fo);
# endif /* ndef _GLOBALS_C_ */