/* Copyright (c) 2002-2004 by Stanley M. Swanson. Distributed under the GNU Geneeral Public License, version 2 (GPL v2). */ /* globals.c for 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 _GLOBALS_C_ # include "globals.h" # if (0) /* mirror of real definitions in globals.h */ # 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 /* maximum 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[] */ # endif int Q_META=1, Q_ABC=0, Q_PHRASE=0, Q_CHORD=0, Q_VAMP=0, Q_LOOP=0, Q_EVENT=0, Q_ACCENT=0, Q_EXPERT=0, V_CLASS=0, Q_VERBOSE=1, Q_PLAY=1, Q_BLUR=0, Q_TESTA=0, Q_TESTB=0, EXPAND_CHORDS=0; float H_raw_part=1.0, H_root_wt=1.0; /* pseudo enums for abc syntactic constructs (non-notes) cf. nextnote() */ const int E_REST=128, E_KEY=-2, E_START_CHORD=-4, E_END_CHORD=-5, E_GUITAR_CHORD = -6, E_TIE = -7, E_BAR=-9, E_REP=-10, E_REP_1=-11, E_REP_2=-12, E_REP_last=-13; /* for chunk[].type */ const int T_MEL=1, T_VAMP=0, T_CHORD=2, T_ACCENT=-1, T_PHRASE=-2, T_SPECIAL=-4; int lch=0, nline=0, chunks=0, kphr=16,nstr=0,n_meta,ntoken,n_save_chr=0, ixgch=0, error_count=0, over_flows=0; int qswap = 1, nout=0, quantum,npitch,nbeat, repeats=1, chordflag=0, beat_usec, total_ticks, quarterticks, staccato; float bpm = 120.0; int measure, tictoc, previ, ticks_in_meas, meter_num=4, meter_denom=4, default_note=8; int n_meas_tick, meas_tick[6], meas_tick_count[6]; /* measure length statistics */ int gen_ticks, gen_meas, gen_rep, next_event_epoch, gen_epoch; int doremi[25], intervals[27], last_tone, tune_tonic, tonal_center, mode_delta, key_major, central_tone; /* for relative pitch and intervals */ int tuple_p, tuple_q, tuple_r, tuple_count, broken_rhythm; /* 020.11 */ int tonic=60, key, kromote[10], whitenote[10], barnote[10], dwell[12]; int cur_chr=0, ix_chr=0; /* global current character and index in line[] */ char line[MAXIN]; /* global character input buffer */ /* session prefix for .log, .nnn.midi files, comments for midi_info */ char session[MAXIN], commenta[MAXIN],commentb[MAXIN],title[MAXIN], token_buf[MAXIN], *tok_start, *copyleft=NULL, made_id[16]; FILE *fout; /* global output file pointer */ FILE *fin[MXATFILE], *flog, *filin; int at_file=0, ksession=0, kc=0, dot_sess, abc_index=0; char bout[MAXOUT]; /* MIDI output buffer */ char *guitar_ch_1, *guitar_ch_2, *guitar_ch_3, *guitar_ch_4; char chunkname[MXCHUNK][8], sav_strings[MXCHAR], guitar_ch[MXGC], *tokens[MXCHUNK] = { "tune","chords"};; int pitch[MXNOTE], tics[MXNOTE], scale[128]; /* 031.29 vel[MXNOTE] */ int epoch[MXNOTE], event[MXNOTE], efirst[MXCHUNK],elast[MXCHUNK]; /* pointers to repetition structure in current tune (: [n etc.) */ int krep, rep_mark[20]; 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 */ struct {char* name; int type, count, ix, lx; } chunk[MXCHUNK]; /* sanity counters for chunks, also used for defaulting */ int accent_count=0, melody_count=0, chord_count=0, vamp_count=0, phrase_count; int last_mel= -1, last_chord= -1, last_intro= -1, last_vamp= -1; /* 031.29 start:(stop+1) pairs for complicated chunks(count>0) */ int kfrag=0, kev, frags[MXFRAG], jot[100]; /* 031.29: params for staccato, mix volume, pan, etc. may go into voice struct */ int mix_mel=104, mix_ch=104, stac_mel=5, stac_ch=30, pan_mel=64, pan_ch=64; int trans_mel=0, trans_ch=0; /* transpose delta in halftones */ /* a start on varation/program events for generation: */ struct { int type, rep, meas, tick, chunk, data; } events[MXVAR]; int nmeta = 18; char *metacmd[MXMETA] = { NULL,"quit","melody","vamp","chords","accent", "variations","loops","instrument","tempo","generate","harmony", "repeat", "midi","param", "events","xtra","phrase", NULL,NULL }; /* pseudo enum for metacommand ID (== index postion of string) * # if (0) # 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 # endif /* default velocities for vamp phrasing, 028.25, 042.27:phrase and dynamics */ int nphrase=2, kphrase=6, iphrase=6, lphrase=8; /* phrase limits and counter */ int idyn=0, kdyn=0, ldyn=0, deldown=0, delup=0, deloff=0; /* velocity contour */ int master_volume=104, volume_delta=0; int iacc=8, lacc=24, kacc=8, macc=24; /* accent limits and counter */ int phrasing[MXACC] = { 6,8, 0,0, 0,0, 8,8, /* [0:7] are default phrase chunk */ 120,1060,80,1060, 90,1060,80,1060, 100,1060,80,1060, 90,1060,80,1060 }; int n_emph, veloc[MXPT], emphasis[MXPT]; /* commands and short explanations for help */ char *help[MXHELP] = { "? help: print this list", "# comment text to output file","% comment line: ignored", "r rhythm (sequence of note lengths in MIDI ticks)", "t tune (note += key base)", "v velocity/volume for r/t sequence (add 2000 or 1000 for accent)", " numbers are a space separated list e.g. 12 20 1 3", " or 'for' parameters: '=' start end incr", "i instruments (MIDI 1-128, drums 135-181)", "a accent used for velocity + 2000, +1000", "g [file]: generate MIDI file", "p play [current]/n/sequence", "k key: base notes [default 0] added to tune values", "o order of looping [default: r l a i ]", "l loop repetitions (lid) [1]", "c (MIDI) code_insert: lid c1 c2 ... cn", "d dump lists (unimplemented)" }; /* end of help[] */ /* 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]; i