gosu 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (204) hide show
  1. checksums.yaml +4 -4
  2. data/dependencies/SDL/include/SDL.h +108 -14
  3. data/dependencies/SDL/include/SDL_assert.h +81 -50
  4. data/dependencies/SDL/include/SDL_atomic.h +135 -35
  5. data/dependencies/SDL/include/SDL_audio.h +960 -355
  6. data/dependencies/SDL/include/SDL_bits.h +11 -6
  7. data/dependencies/SDL/include/SDL_blendmode.h +91 -14
  8. data/dependencies/SDL/include/SDL_clipboard.h +30 -7
  9. data/dependencies/SDL/include/SDL_config.h +277 -27
  10. data/dependencies/SDL/include/SDL_config_android.h +13 -38
  11. data/dependencies/SDL/include/SDL_config_iphoneos.h +21 -62
  12. data/dependencies/SDL/include/SDL_config_macosx.h +23 -92
  13. data/dependencies/SDL/include/SDL_config_minimal.h +1 -4
  14. data/dependencies/SDL/include/SDL_config_pandora.h +15 -22
  15. data/dependencies/SDL/include/SDL_config_psp.h +16 -37
  16. data/dependencies/SDL/include/SDL_config_windows.h +28 -91
  17. data/dependencies/SDL/include/SDL_config_winrt.h +33 -61
  18. data/dependencies/SDL/include/SDL_config_wiz.h +28 -56
  19. data/dependencies/SDL/include/SDL_copying.h +1 -1
  20. data/dependencies/SDL/include/SDL_cpuinfo.h +331 -71
  21. data/dependencies/SDL/include/SDL_egl.h +906 -280
  22. data/dependencies/SDL/include/SDL_endian.h +101 -47
  23. data/dependencies/SDL/include/SDL_error.h +70 -19
  24. data/dependencies/SDL/include/SDL_events.h +387 -79
  25. data/dependencies/SDL/include/SDL_filesystem.h +73 -64
  26. data/dependencies/SDL/include/SDL_gamecontroller.h +585 -125
  27. data/dependencies/SDL/include/SDL_gesture.h +36 -6
  28. data/dependencies/SDL/include/SDL_haptic.h +304 -210
  29. data/dependencies/SDL/include/SDL_hidapi.h +451 -0
  30. data/dependencies/SDL/include/SDL_hints.h +1286 -897
  31. data/dependencies/SDL/include/SDL_joystick.h +577 -130
  32. data/dependencies/SDL/include/SDL_keyboard.h +162 -63
  33. data/dependencies/SDL/include/SDL_keycode.h +7 -5
  34. data/dependencies/SDL/include/SDL_loadso.h +42 -8
  35. data/dependencies/SDL/include/SDL_locale.h +34 -32
  36. data/dependencies/SDL/include/SDL_log.h +212 -19
  37. data/dependencies/SDL/include/SDL_main.h +72 -17
  38. data/dependencies/SDL/include/SDL_messagebox.h +70 -23
  39. data/dependencies/SDL/include/SDL_metal.h +27 -32
  40. data/dependencies/SDL/include/SDL_misc.h +19 -15
  41. data/dependencies/SDL/include/SDL_mouse.h +262 -110
  42. data/dependencies/SDL/include/SDL_mutex.h +286 -66
  43. data/dependencies/SDL/include/SDL_name.h +1 -1
  44. data/dependencies/SDL/include/SDL_opengl.h +1 -1
  45. data/dependencies/SDL/include/SDL_opengles.h +1 -1
  46. data/dependencies/SDL/include/SDL_opengles2.h +2 -2
  47. data/dependencies/SDL/include/SDL_pixels.h +199 -34
  48. data/dependencies/SDL/include/SDL_platform.h +39 -2
  49. data/dependencies/SDL/include/SDL_power.h +23 -10
  50. data/dependencies/SDL/include/SDL_quit.h +1 -1
  51. data/dependencies/SDL/include/SDL_rect.h +78 -28
  52. data/dependencies/SDL/include/SDL_render.h +1204 -472
  53. data/dependencies/SDL/include/SDL_revision.h +2 -2
  54. data/dependencies/SDL/include/SDL_rwops.h +605 -33
  55. data/dependencies/SDL/include/SDL_scancode.h +1 -1
  56. data/dependencies/SDL/include/SDL_sensor.h +76 -42
  57. data/dependencies/SDL/include/SDL_shape.h +38 -27
  58. data/dependencies/SDL/include/SDL_stdinc.h +96 -24
  59. data/dependencies/SDL/include/SDL_surface.h +571 -139
  60. data/dependencies/SDL/include/SDL_system.h +339 -101
  61. data/dependencies/SDL/include/SDL_syswm.h +50 -20
  62. data/dependencies/SDL/include/SDL_test.h +1 -1
  63. data/dependencies/SDL/include/SDL_test_assert.h +2 -2
  64. data/dependencies/SDL/include/SDL_test_common.h +23 -6
  65. data/dependencies/SDL/include/SDL_test_compare.h +1 -1
  66. data/dependencies/SDL/include/SDL_test_crc32.h +1 -1
  67. data/dependencies/SDL/include/SDL_test_font.h +3 -3
  68. data/dependencies/SDL/include/SDL_test_fuzzer.h +28 -26
  69. data/dependencies/SDL/include/SDL_test_harness.h +6 -6
  70. data/dependencies/SDL/include/SDL_test_images.h +1 -1
  71. data/dependencies/SDL/include/SDL_test_log.h +1 -1
  72. data/dependencies/SDL/include/SDL_test_md5.h +1 -1
  73. data/dependencies/SDL/include/SDL_test_memory.h +1 -1
  74. data/dependencies/SDL/include/SDL_test_random.h +2 -2
  75. data/dependencies/SDL/include/SDL_thread.h +226 -128
  76. data/dependencies/SDL/include/SDL_timer.h +129 -22
  77. data/dependencies/SDL/include/SDL_touch.h +48 -8
  78. data/dependencies/SDL/include/SDL_types.h +1 -1
  79. data/dependencies/SDL/include/SDL_version.h +72 -46
  80. data/dependencies/SDL/include/SDL_video.h +1266 -460
  81. data/dependencies/SDL/include/SDL_vulkan.h +100 -161
  82. data/dependencies/SDL/include/begin_code.h +22 -1
  83. data/dependencies/SDL/include/close_code.h +1 -1
  84. data/dependencies/SDL/lib/x64/libSDL2.dll.a +0 -0
  85. data/dependencies/SDL/lib/x86/libSDL2.dll.a +0 -0
  86. data/dependencies/SDL_sound/SDL_sound.c +83 -7
  87. data/dependencies/SDL_sound/SDL_sound.h +4 -4
  88. data/dependencies/SDL_sound/SDL_sound_aiff.c +9 -12
  89. data/dependencies/SDL_sound/SDL_sound_au.c +7 -7
  90. data/dependencies/SDL_sound/SDL_sound_coreaudio.c +3 -3
  91. data/dependencies/SDL_sound/SDL_sound_flac.c +1 -1
  92. data/dependencies/SDL_sound/SDL_sound_internal.h +17 -10
  93. data/dependencies/SDL_sound/SDL_sound_modplug.c +25 -27
  94. data/dependencies/SDL_sound/SDL_sound_mp3.c +5 -17
  95. data/dependencies/SDL_sound/SDL_sound_raw.c +11 -11
  96. data/dependencies/SDL_sound/SDL_sound_shn.c +8 -7
  97. data/dependencies/SDL_sound/SDL_sound_voc.c +6 -4
  98. data/dependencies/SDL_sound/SDL_sound_vorbis.c +6 -11
  99. data/dependencies/SDL_sound/SDL_sound_wav.c +35 -29
  100. data/dependencies/SDL_sound/dr_flac.h +618 -220
  101. data/dependencies/SDL_sound/dr_mp3.h +263 -94
  102. data/dependencies/SDL_sound/libmodplug/fastmix.c +58 -64
  103. data/dependencies/SDL_sound/libmodplug/libmodplug.h +25 -103
  104. data/dependencies/SDL_sound/libmodplug/load_669.c +14 -17
  105. data/dependencies/SDL_sound/libmodplug/load_amf.c +11 -7
  106. data/dependencies/SDL_sound/libmodplug/load_ams.c +65 -22
  107. data/dependencies/SDL_sound/libmodplug/load_dbm.c +8 -4
  108. data/dependencies/SDL_sound/libmodplug/load_dmf.c +55 -25
  109. data/dependencies/SDL_sound/libmodplug/load_far.c +9 -13
  110. data/dependencies/SDL_sound/libmodplug/load_gdm.c +448 -0
  111. data/dependencies/SDL_sound/libmodplug/load_it.c +45 -49
  112. data/dependencies/SDL_sound/libmodplug/load_mdl.c +80 -53
  113. data/dependencies/SDL_sound/libmodplug/load_med.c +20 -12
  114. data/dependencies/SDL_sound/libmodplug/load_mod.c +40 -15
  115. data/dependencies/SDL_sound/libmodplug/load_mt2.c +29 -17
  116. data/dependencies/SDL_sound/libmodplug/load_okt.c +12 -8
  117. data/dependencies/SDL_sound/libmodplug/load_psm.c +101 -78
  118. data/dependencies/SDL_sound/libmodplug/load_ptm.c +18 -17
  119. data/dependencies/SDL_sound/libmodplug/load_s3m.c +9 -7
  120. data/dependencies/SDL_sound/libmodplug/load_stm.c +3 -2
  121. data/dependencies/SDL_sound/libmodplug/load_ult.c +2 -2
  122. data/dependencies/SDL_sound/libmodplug/load_umx.c +315 -35
  123. data/dependencies/SDL_sound/libmodplug/load_xm.c +25 -21
  124. data/dependencies/SDL_sound/libmodplug/mmcmp.c +295 -149
  125. data/dependencies/SDL_sound/libmodplug/modplug.c +7 -123
  126. data/dependencies/SDL_sound/libmodplug/modplug.h +32 -29
  127. data/dependencies/SDL_sound/libmodplug/snd_dsp.c +0 -1
  128. data/dependencies/SDL_sound/libmodplug/snd_flt.c +2 -2
  129. data/dependencies/SDL_sound/libmodplug/snd_fx.c +24 -18
  130. data/dependencies/SDL_sound/libmodplug/sndfile.c +55 -156
  131. data/dependencies/SDL_sound/libmodplug/sndmix.c +7 -12
  132. data/dependencies/SDL_sound/libmodplug/tables.h +10 -15
  133. data/dependencies/SDL_sound/stb_vorbis.h +508 -325
  134. data/dependencies/{al_soft → mojoAL}/AL/al.h +38 -30
  135. data/dependencies/{al_soft → mojoAL}/AL/alc.h +27 -56
  136. data/dependencies/mojoAL/mojoal.c +4594 -0
  137. data/ext/gosu/extconf.rb +29 -30
  138. data/include/Gosu/Audio.hpp +70 -85
  139. data/include/Gosu/Color.hpp +19 -11
  140. data/include/Gosu/Font.hpp +40 -44
  141. data/include/Gosu/Graphics.hpp +58 -71
  142. data/include/Gosu/GraphicsBase.hpp +26 -33
  143. data/include/Gosu/Image.hpp +56 -62
  144. data/include/Gosu/ImageData.hpp +23 -27
  145. data/include/Gosu/Inspection.hpp +1 -4
  146. data/include/Gosu/TextInput.hpp +34 -40
  147. data/include/Gosu/Version.hpp +1 -1
  148. data/include/Gosu/Window.hpp +71 -70
  149. data/lib/SDL2.dll +0 -0
  150. data/lib/gosu/compat.rb +24 -37
  151. data/lib/gosu.rb +2 -2
  152. data/lib64/SDL2.dll +0 -0
  153. data/src/Audio.cpp +86 -86
  154. data/src/AudioFile.hpp +6 -6
  155. data/src/AudioFileAudioToolbox.cpp +1 -1
  156. data/src/AudioFileSDLSound.cpp +1 -1
  157. data/src/AudioImpl.hpp +5 -5
  158. data/src/BitmapIO.cpp +0 -20
  159. data/src/BlockAllocator.cpp +2 -1
  160. data/src/Channel.cpp +22 -20
  161. data/src/Color.cpp +12 -9
  162. data/src/EmptyImageData.hpp +15 -17
  163. data/src/FileUnix.cpp +1 -1
  164. data/src/FileWin.cpp +1 -1
  165. data/src/Font.cpp +48 -53
  166. data/src/Graphics.cpp +135 -143
  167. data/src/Image.cpp +41 -42
  168. data/src/Input.cpp +1 -1
  169. data/src/InputUIKit.cpp +1 -1
  170. data/src/LargeImageData.cpp +108 -101
  171. data/src/LargeImageData.hpp +17 -15
  172. data/src/Log.hpp +6 -6
  173. data/src/Macro.cpp +35 -37
  174. data/src/Macro.hpp +11 -11
  175. data/src/Math.cpp +8 -1
  176. data/src/Resolution.cpp +12 -7
  177. data/src/RubyGosu.cxx +5 -5
  178. data/src/TexChunk.cpp +50 -41
  179. data/src/TexChunk.hpp +22 -22
  180. data/src/Text.cpp +37 -37
  181. data/src/TextBuilder.cpp +60 -57
  182. data/src/TextBuilder.hpp +20 -20
  183. data/src/TextInput.cpp +127 -135
  184. data/src/TrueTypeFont.cpp +107 -107
  185. data/src/TrueTypeFont.hpp +39 -38
  186. data/src/TrueTypeFontApple.cpp +19 -22
  187. data/src/TrueTypeFontUnix.cpp +21 -26
  188. data/src/TrueTypeFontWin.cpp +30 -30
  189. data/src/Window.cpp +95 -86
  190. data/src/WindowUIKit.cpp +46 -49
  191. metadata +7 -17
  192. data/dependencies/SDL/include/SDL_config_os2.h +0 -188
  193. data/dependencies/SDL_sound/libmodplug/load_abc.c +0 -4725
  194. data/dependencies/SDL_sound/libmodplug/load_mid.c +0 -1405
  195. data/dependencies/SDL_sound/libmodplug/load_pat.c +0 -1143
  196. data/dependencies/SDL_sound/libmodplug/load_pat.h +0 -25
  197. data/dependencies/al_soft/AL/alext.h +0 -585
  198. data/dependencies/al_soft/AL/efx-creative.h +0 -3
  199. data/dependencies/al_soft/AL/efx-presets.h +0 -402
  200. data/dependencies/al_soft/AL/efx.h +0 -762
  201. data/dependencies/al_soft/x64/libOpenAL32.dll.a +0 -0
  202. data/dependencies/al_soft/x86/libOpenAL32.dll.a +0 -0
  203. data/lib/OpenAL32.dll +0 -0
  204. data/lib64/OpenAL32.dll +0 -0
@@ -1,4725 +0,0 @@
1
- /*
2
-
3
- MikMod Sound System
4
-
5
- By Jake Stine of Divine Entertainment (1996-2000)
6
-
7
- Support:
8
- If you find problems with this code, send mail to:
9
- air@divent.org
10
-
11
- Distribution / Code rights:
12
- Use this source code in any fashion you see fit. Giving me credit where
13
- credit is due is optional, depending on your own levels of integrity and
14
- honesty.
15
-
16
- -----------------------------------------
17
- Module: LOAD_ABC
18
-
19
- ABC module loader.
20
- by Peter Grootswagers (2006)
21
- <email:pgrootswagers@planet.nl>
22
-
23
- Portability:
24
- All systems - all compilers (hopefully)
25
- */
26
-
27
- #include <limits.h>
28
- #include <stdlib.h>
29
- #include <time.h>
30
- #include <string.h>
31
- #include <math.h>
32
- #include <ctype.h>
33
-
34
- #include "libmodplug.h"
35
-
36
- #include "load_pat.h"
37
-
38
- #define MAXABCINCLUDES 8
39
- #define MAXCHORDNAMES 80
40
- #define ABC_ENV_DUMPTRACKS "MMABC_DUMPTRACKS"
41
- #define ABC_ENV_NORANDOMPICK "MMABC_NO_RANDOM_PICK"
42
-
43
- // gchords use tracks with vpos 1 thru 7
44
- // drums use track with vpos 8
45
- // voice chords use vpos 0 and vpos from 11 up
46
- #define GCHORDBPOS 1
47
- #define GCHORDFPOS 2
48
- #define GCHORDCPOS 3
49
- #define DRUMPOS 8
50
- #define DRONEPOS1 9
51
- #define DRONEPOS2 10
52
-
53
- // in the patterns a whole note at unmodified tempo is 16 rows
54
- #define ROWSPERNOTE 16
55
- // a 1/64-th note played in triool equals a 1/96-th note, to be able
56
- // to play them and also to play the 1/64-th we need a resolution of 192
57
- // because 2/192 = 1/96 and 3/192 = 1/64
58
- #define RESOLUTION 192
59
-
60
- #pragma pack(1)
61
-
62
- /**************************************************************************
63
- **************************************************************************/
64
- typedef enum {
65
- note,
66
- octave,
67
- smpno,
68
- volume,
69
- effect,
70
- effoper
71
- } ABCEVENT_X_NOTE;
72
-
73
- typedef enum {
74
- none,
75
- trill,
76
- bow,
77
- accent
78
- } ABCEVENT_X_EFFECT;
79
-
80
- typedef enum {
81
- cmdflag,
82
- command,
83
- chordnum,
84
- chordnote,
85
- chordbase,
86
- jumptype
87
- } ABCEVENT_X_CMD;
88
-
89
- typedef enum {
90
- cmdsegno = '$',
91
- cmdcapo = 'B',
92
- cmdchord = 'C',
93
- cmdfine = 'F',
94
- cmdhide = 'H',
95
- cmdjump = 'J',
96
- cmdloop = 'L',
97
- cmdcoda = 'O',
98
- cmdpartbrk = 'P',
99
- cmdsync = 'S',
100
- cmdtempo = 'T',
101
- cmdvariant = 'V',
102
- cmdtocoda = 'X'
103
- } ABCEVENT_CMD;
104
-
105
- typedef enum {
106
- jumpnormal,
107
- jumpfade,
108
- jumpdacapo,
109
- jumpdcfade,
110
- jumpdasegno,
111
- jumpdsfade,
112
- jumpfine,
113
- jumptocoda,
114
- jumpvariant,
115
- jumpnot
116
- } ABCEVENT_JUMPTYPE;
117
-
118
- typedef struct _ABCEVENT
119
- {
120
- struct _ABCEVENT *next;
121
- uint32_t tracktick;
122
- union {
123
- uint8_t par[6];
124
- struct {
125
- uint8_t flg;
126
- uint8_t cmd;
127
- uint32_t lpar; // for variant selections, bit pattern
128
- };
129
- };
130
- uint8_t part;
131
- uint8_t tiednote;
132
- } ABCEVENT;
133
-
134
- typedef struct _ABCTRACK
135
- {
136
- struct _ABCTRACK *next;
137
- ABCEVENT *head;
138
- ABCEVENT *tail;
139
- ABCEVENT *capostart;
140
- ABCEVENT *tienote;
141
- int transpose;
142
- int octave_shift;
143
- uint32_t slidevoltime; // for crescendo and diminuendo
144
- int slidevol; // -2:fade away, -1:diminuendo, 0:none, +1:crescendo
145
- uint8_t vno; // 0 is track is free for use, from previous song in multi-songbook
146
- uint8_t vpos; // 0 is main voice, other is subtrack for gchords, gchords or drumnotes
147
- uint8_t tiedvpos;
148
- uint8_t mute;
149
- uint8_t chan; // 10 is percussion channel, any other is melodic channel
150
- uint8_t volume;
151
- uint8_t instr; // current instrument for this track
152
- uint8_t legato;
153
- char v[22]; // first twenty characters are significant
154
- } ABCTRACK;
155
-
156
- typedef struct _ABCMACRO
157
- {
158
- struct _ABCMACRO *next;
159
- char *name;
160
- char *subst;
161
- char *n;
162
- } ABCMACRO;
163
-
164
- /**************************************************************************
165
- **************************************************************************/
166
-
167
- typedef struct _ABCHANDLE
168
- {
169
- ABCMACRO *macro;
170
- ABCMACRO *umacro;
171
- ABCTRACK *track;
172
- long int pickrandom;
173
- unsigned int len;
174
- int speed;
175
- char *line;
176
- char *beatstring;
177
- uint8_t beat[4]; // a:first note, b:strong notes, c:weak notes, n:strong note every n
178
- char gchord[80]; // last setting for gchord
179
- char drum[80]; // last setting for drum
180
- char drumins[80]; // last setting for drum
181
- char drumvol[80]; // last setting for drum
182
- uint32_t barticks;
183
- // parse variables, declared here to avoid parameter pollution
184
- int abcchordvol, abcchordprog, abcbassvol, abcbassprog;
185
- int ktrans;
186
- int drumon, gchordon, droneon;
187
- int dronegm, dronepitch[2], dronevol[2];
188
- ABCTRACK *tp, *tpc, *tpr;
189
- uint32_t tracktime;
190
- } ABCHANDLE;
191
-
192
- /* !!! FIXME: global state */
193
- static int global_voiceno, global_octave_shift, global_tempo_factor, global_tempo_divider;
194
- static char global_part;
195
- static uint32_t global_songstart;
196
- /* Named guitar chords */
197
- static char chordname[MAXCHORDNAMES][8];
198
- static int chordnotes[MAXCHORDNAMES][6];
199
- static int chordlen[MAXCHORDNAMES];
200
- static int chordsnamed = 0;
201
-
202
- static const char *sig[] = {
203
- " C D EF G A Bc d ef g a b", // 7 sharps C#
204
- " C D EF G AB c d ef g ab ", // 6 sharps F#
205
- " C DE F G AB c de f g ab ", // 5 sharps B
206
- " C DE F GA B c de f ga b ", // 4 sharps E
207
- " CD E F GA B cd e f ga b ", // 3 sharps A
208
- " CD E FG A B cd e fg a b ", // 2 sharps D
209
- " C D E FG A Bc d e fg a b", // 1 sharps G
210
- " C D EF G A Bc d ef g a b", // 0 sharps C
211
- " C D EF G AB c d ef g ab ", // 1 flats F
212
- " C DE F G AB c de f g ab ", // 2 flats Bb
213
- " C DE F GA B c de f ga b ", // 3 flats Eb
214
- " CD E F GA B cd e f ga b ", // 4 flats Ab
215
- " CD E FG A B cd e fg a b ", // 5 flats Db
216
- "C D E FG A Bc d e fg a b ", // 6 flats Gb
217
- "C D EF G A Bc d ef g a b ", // 7 flats Cb
218
- // 0123456789012345678901234
219
- };
220
-
221
- static const char *keySigs[] = {
222
- /* 0....:....1....:....2....:....3....:....4....:....5. */
223
- "7 sharps: C# A#m G#Mix D#Dor E#Phr F#Lyd B#Loc ",
224
- "6 sharps: F# D#m C#Mix G#Dor A#Phr BLyd E#Loc ",
225
- "5 sharps: B G#m F#Mix C#Dor D#Phr ELyd A#Loc ",
226
- "4 sharps: E C#m BMix F#Dor G#Phr ALyd D#Loc ",
227
- "3 sharps: A F#m EMix BDor C#Phr DLyd G#Loc ",
228
- "2 sharps: D Bm AMix EDor F#Phr GLyd C#Loc ",
229
- "1 sharp : G Em DMix ADor BPhr CLyd F#Loc ",
230
- "0 sharps: C Am GMix DDor EPhr FLyd BLoc ",
231
- "1 flat : F Dm CMix GDor APhr BbLyd ELoc ",
232
- "2 flats : Bb Gm FMix CDor DPhr EbLyd ALoc ",
233
- "3 flats : Eb Cm BbMix FDor GPhr AbLyd DLoc ",
234
- "4 flats : Ab Fm EbMix BbDor CPhr DbLyd GLoc ",
235
- "5 flats : Db Bbm AbMix EbDor FPhr GbLyd CLoc ",
236
- "6 flats : Gb Ebm DbMix AbDor BbPhr CbLyd FLoc ",
237
- "7 flats : Cb Abm GbMix DbDor EbPhr FbLyd BbLoc ",
238
- 0
239
- };
240
-
241
- // local prototypes
242
- static int abc_getnumber(const char *p, int *number);
243
- static ABCTRACK *abc_locate_track(ABCHANDLE *h, const char *voice, int pos);
244
- static void abc_add_event(ABCHANDLE *h, ABCTRACK *tp, ABCEVENT *e);
245
- static void abc_add_setloop(ABCHANDLE *h, ABCTRACK *tp, uint32_t tracktime);
246
- static void abc_add_setjumploop(ABCHANDLE *h, ABCTRACK *tp, uint32_t tracktime, ABCEVENT_JUMPTYPE j);
247
- static uint32_t abc_pattracktime(ABCHANDLE *h, uint32_t tracktime);
248
- static int abc_patno(ABCHANDLE *h, uint32_t tracktime);
249
-
250
- static SDL_INLINE int IsAlpha(const char c) {
251
- return ( ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) );
252
- }
253
-
254
- static SDL_INLINE int IsUpper(const char c) {
255
- return ( (c >= 'A') && (c <= 'Z') );
256
- }
257
-
258
- static SDL_INLINE int IsLower(const char c) {
259
- return ( (c >= 'a') && (c <= 'z') );
260
- }
261
-
262
- static int abc_isvalidchar(char c) {
263
- return(IsAlpha(c) || SDL_isdigit(c) || SDL_isspace(c) || c == '%' || c == ':');
264
- }
265
-
266
- static const char *abc_skipspace(const char *p)
267
- {
268
- while (*p && SDL_isspace(*p))
269
- p++;
270
- return p;
271
- }
272
-
273
- static void abc_extractkeyvalue(char *key, size_t key_max,
274
- char *value, size_t value_max, const char *src)
275
- {
276
- while (*src && SDL_isspace(*src))
277
- src++;
278
-
279
- size_t key_size;
280
- for (key_size = 0; key_size < key_max - 1 && *src;) {
281
- if (*src == '=') {
282
- src++;
283
- break;
284
- }
285
- key[key_size++] = *src++;
286
- }
287
- while (key_size > 0 && SDL_isspace(key[key_size - 1]))
288
- key_size--;
289
- key[key_size] = '\0';
290
-
291
- while (*src && SDL_isspace(*src))
292
- src++;
293
-
294
- size_t value_size;
295
- for (value_size = 0; value_size < value_max - 1 && *src;)
296
- value[value_size++] = *src++;
297
- while (value_size > 0 && SDL_isspace(value[value_size - 1]))
298
- value_size--;
299
- value[value_size] = '\0';
300
- }
301
-
302
- static void abc_message(const char *s1, const char *s2)
303
- {
304
- char txt[256];
305
- if( SDL_strlen(s1) + SDL_strlen(s2) > 255 ) return;
306
- SDL_snprintf(txt, sizeof (txt), s1, s2);
307
- SDL_LogInfo(SDL_LOG_CATEGORY_AUDIO, "load_abc > %s\n", txt);
308
- }
309
-
310
- static uint32_t modticks(uint32_t abcticks)
311
- {
312
- return abcticks / RESOLUTION;
313
- }
314
-
315
- static uint32_t abcticks(uint32_t modticks)
316
- {
317
- return modticks * RESOLUTION;
318
- }
319
-
320
- static uint32_t notelen_notediv_to_ticks(int speed, int len, int div)
321
- {
322
- uint32_t u;
323
- if (div == 0) return 0;
324
- u = (ROWSPERNOTE * RESOLUTION * speed * len * global_tempo_factor) / (div * global_tempo_divider);
325
- return u;
326
- }
327
-
328
- static void abc_dumptracks(ABCHANDLE *h, const char *p)
329
- {
330
- #if 0
331
- ABCTRACK *t;
332
- ABCEVENT *e;
333
- int n,pat,row,tck;
334
- char nn[3];
335
- if( !h ) return;
336
- for( t=h->track; t; t=t->next ) {
337
- printf("track %d.%d chan=%d %s\n", (int)(t->vno), (int)(t->vpos),
338
- (int)(t->chan), (char *)(t->v));
339
- if( SDL_strcmp(p,"nonotes") )
340
- n = 1;
341
- else
342
- n = 0;
343
- for( e=t->head; e; e=e->next ) {
344
- tck = modticks(e->tracktick);
345
- row = tck / h->speed;
346
- pat = row / 64;
347
- tck = tck % h->speed;
348
- row = row % 64;
349
- nn[0] = ( e->tracktick % abcticks(h->speed * 64) ) ? ' ': '-';
350
- if( e->flg == 1 ) {
351
- printf(" %6d.%02d.%d%c%c %d.%d %s ",
352
- pat, row, tck, nn[0], (int)(e->part), (int)(t->vno),
353
- (int)(t->vpos), (char *)(t->v));
354
- if( e->cmd == cmdchord ) {
355
- nn[0] = "CCCDDEFFGGAABccddeffggaabb"[e->par[chordnote]];
356
- nn[1] = "b # # # # # # # # # # #"[e->par[chordnote]];
357
- nn[2] = '\0';
358
- if( SDL_isspace(nn[1]) ) nn[1] = '\0';
359
- printf("CMD %c: gchord %s%s",
360
- (char)(e->cmd), nn, chordname[e->par[chordnum]]);
361
- if( e->par[chordbase] != e->par[chordnote] ) {
362
- nn[0] = "CCCDDEFFGGAABccddeffggaabb"[e->par[chordbase]];
363
- nn[1] = "b # # # # # # # # # # #"[e->par[chordbase]];
364
- nn[2] = '\0';
365
- printf("/%s", nn);
366
- }
367
- printf("\n");
368
- }
369
- else
370
- printf("CMD %c @%p 0x%08lX\n",
371
- (char)(e->cmd), e,
372
- (unsigned long)(e->lpar));
373
- if( SDL_strcmp(p,"nonotes") )
374
- n = 1;
375
- else
376
- n = 0;
377
- }
378
- else if( n ) {
379
- printf(" %6d.%02d.%d%c%c %d.%d %s ", pat, row, tck, nn[0], e->part, t->vno, t->vpos, t->v);
380
- if( e->par[note] ) {
381
- nn[0] = "CCCDDEFFGGAABccddeffggaabb"[e->par[note]-23];
382
- nn[1] = "b # # # # # # # # # # #"[e->par[note]-23];
383
- nn[2] = '\0';
384
- }
385
- else SDL_strlcpy(nn,"--",sizeof (nn));
386
- printf("NOTE %s octave %d inst %s vol %03d\n",
387
- nn, e->par[octave], pat_gm_name(pat_smptogm(e->par[smpno])),e->par[volume]);
388
- if( SDL_strcmp(p,"all") )
389
- n = 0;
390
- }
391
- }
392
- }
393
- #endif
394
- }
395
-
396
-
397
- // =====================================================================================
398
- static ABCEVENT *abc_new_event(ABCHANDLE *h, uint32_t abctick, const char data[])
399
- // =====================================================================================
400
- {
401
- ABCEVENT *retval;
402
- int i;
403
-
404
- retval = (ABCEVENT *)_mm_calloc(h->trackhandle, 1,sizeof(ABCEVENT));
405
- retval->next = NULL;
406
- retval->tracktick = abctick;
407
- for( i=0; i<6; i++ )
408
- retval->par[i] = data[i];
409
- retval->part = global_part;
410
- retval->tiednote = 0;
411
- return retval;
412
- }
413
-
414
- // =============================================================================
415
- static ABCEVENT *abc_copy_event(ABCHANDLE *h, ABCEVENT *se)
416
- // =============================================================================
417
- {
418
- ABCEVENT *e;
419
- e = (ABCEVENT *)_mm_calloc(h->trackhandle, 1,sizeof(ABCEVENT));
420
- e->next = NULL;
421
- e->tracktick = se->tracktick;
422
- e->flg = se->flg;
423
- e->cmd = se->cmd;
424
- e->lpar = se->lpar;
425
- e->part = se->part;
426
- return e;
427
- }
428
-
429
- // =============================================================================
430
- static void abc_new_macro(ABCHANDLE *h, const char *m)
431
- // =============================================================================
432
- {
433
- ABCMACRO *retval;
434
- char key[256], value[256];
435
- abc_extractkeyvalue(key, sizeof(key), value, sizeof(value), m);
436
-
437
- retval = (ABCMACRO *)_mm_calloc(h->macrohandle, 1,sizeof(ABCMACRO));
438
- retval->name = DupStr(h->macrohandle, key, SDL_strlen(key));
439
- retval->n = SDL_strrchr(retval->name, 'n'); // for transposing macro's
440
- retval->subst = DupStr(h->macrohandle, value, SDL_strlen(value));
441
- retval->next = h->macro;
442
- h->macro = retval;
443
- }
444
-
445
- // =============================================================================
446
- static void abc_new_umacro(ABCHANDLE *h, const char *m)
447
- // =============================================================================
448
- {
449
- ABCMACRO *retval, *mp;
450
- char *q;
451
-
452
- char key[256], value[256];
453
- abc_extractkeyvalue(key, sizeof(key), value, sizeof(value), m);
454
- if( SDL_strlen(key) > 1 || SDL_strchr("~HIJKLMNOPQRSTUVWXY",SDL_toupper(key[0])) == 0 ) return;
455
- while( (q = SDL_strchr(key, '!')) != NULL )
456
- *q = '+'; // translate oldstyle to newstyle
457
- if( !SDL_strcmp(key,"+nil+") ) { // delete a macro
458
- mp = NULL;
459
- for( retval=h->umacro; retval; retval = retval->next ) {
460
- if( retval->name[0] == key[0] ) { // delete this one
461
- if( mp ) mp->next = retval->next;
462
- else h->umacro = retval->next;
463
- _mm_free(h->macrohandle, retval);
464
- return;
465
- }
466
- mp = retval;
467
- }
468
- return;
469
- }
470
- retval = (ABCMACRO *)_mm_calloc(h->macrohandle, 1,sizeof(ABCMACRO));
471
- retval->name = DupStr(h->macrohandle, key, 1);
472
- retval->subst = DupStr(h->macrohandle, value, SDL_strlen(value));
473
- retval->n = 0;
474
- retval->next = h->umacro; // by placing it up front we mask out the old macro until we +nil+ it
475
- h->umacro = retval;
476
- }
477
-
478
- // =============================================================================
479
- static ABCTRACK *abc_new_track(ABCHANDLE *h, const char *voice, int pos)
480
- // =============================================================================
481
- {
482
- ABCTRACK *retval;
483
- if( !pos ) global_voiceno++;
484
- retval = (ABCTRACK *)_mm_calloc(h->trackhandle, 1,sizeof(ABCTRACK));
485
- retval->next = NULL;
486
- retval->vno = global_voiceno;
487
- retval->vpos = pos;
488
- retval->tiedvpos = pos;
489
- retval->instr = 1;
490
- SDL_strlcpy(retval->v, voice, 20);
491
- retval->v[20] = '\0';
492
- retval->head = NULL;
493
- retval->tail = NULL;
494
- retval->capostart = NULL;
495
- retval->tienote = NULL;
496
- retval->mute = 0;
497
- retval->chan = 0;
498
- retval->transpose = 0;
499
- retval->volume = h->track? h->track->volume: 120;
500
- retval->slidevoltime = 0;
501
- retval->slidevol = 0;
502
- retval->legato = 0;
503
- return retval;
504
- }
505
-
506
- static int abc_numtracks(ABCHANDLE *h)
507
- {
508
- int n;
509
- ABCTRACK *t;
510
- n=0;
511
- for( t = h->track; t; t=t->next )
512
- n++;
513
- return n;
514
- }
515
-
516
- static int abc_interval(const char *s, const char *d)
517
- {
518
- const char *p;
519
- int i,j,k;
520
- int n,oct,m[2];
521
- for( j=0; j<2; j++ ) {
522
- if( j ) p = d;
523
- else p = s;
524
- switch(p[0]) {
525
- case '^':
526
- n = p[1];
527
- i = 2;
528
- break;
529
- case '_':
530
- n = p[1];
531
- i = 2;
532
- break;
533
- case '=':
534
- n = p[1];
535
- i = 2;
536
- break;
537
- default:
538
- n = p[0];
539
- i = 1;
540
- break;
541
- }
542
- for( k=0; k<25; k++ )
543
- if( n == sig[7][k] )
544
- break;
545
- oct = 4; // ABC note pitch C is C4 and pitch c is C5
546
- if( k > 12 ) {
547
- oct++;
548
- k -= 12;
549
- }
550
- while( p[i] == ',' || p[i] == '\'' ) {
551
- if( p[i] == ',' )
552
- oct--;
553
- else
554
- oct++;
555
- i++;
556
- }
557
- m[j] = k + 12 * oct;
558
- }
559
- return m[0] - m[1];
560
- }
561
-
562
- static int abc_transpose(const char *v)
563
- {
564
- int i,j,t;
565
- const char *m = "B", *mv = "";
566
- t = 0;
567
- global_octave_shift = 99;
568
- for( ; *v && *v != ']'; v++ ) {
569
- if( !SDL_strncasecmp(v,"t=",2) ) {
570
- v+=2;
571
- if( *v=='-' ) {
572
- j = -1;
573
- v++;
574
- }
575
- else j = 1;
576
- v+=abc_getnumber(v,&i);
577
- t += i * j;
578
- global_octave_shift = 0;
579
- }
580
- if( !SDL_strncasecmp(v,"octave=",7) ) {
581
- v+=7;
582
- if( *v=='-' ) {
583
- j = -1;
584
- v++;
585
- }
586
- else j = 1;
587
- v+=abc_getnumber(v,&i);
588
- t += i * j * 12;
589
- global_octave_shift = 0;
590
- }
591
- if( !SDL_strncasecmp(v,"transpose=",10) ) {
592
- v+=10;
593
- if( *v=='-' ) {
594
- j = -1;
595
- v++;
596
- }
597
- else j = 1;
598
- v+=abc_getnumber(v,&i);
599
- t += i * j;
600
- global_octave_shift = 0;
601
- }
602
- if( !SDL_strncasecmp(v,"octave=",7) ) { // used in kv304*.abc
603
- v+=7;
604
- if( *v=='-' ) {
605
- j = -1;
606
- v++;
607
- }
608
- else j = 1;
609
- v+=abc_getnumber(v,&i);
610
- t += i * j * 12;
611
- global_octave_shift = 0;
612
- }
613
- if( !SDL_strncasecmp(v,"m=",2) ) {
614
- v += 2;
615
- mv = v; // get the pitch for the middle staff line
616
- while( *v && *v != ' ' && *v != ']' ) v++;
617
- global_octave_shift = 0;
618
- }
619
- if( !SDL_strncasecmp(v,"middle=",7) ) {
620
- v += 7;
621
- mv = v; // get the pitch for the middle staff line
622
- while( *v && *v != ' ' && *v != ']' ) v++;
623
- global_octave_shift = 0;
624
- }
625
- if( !SDL_strncasecmp(v,"clef=",5) )
626
- v += 5;
627
- j = 1;
628
- if( !SDL_strncasecmp(v,"treble",6) ) {
629
- j = 0;
630
- v += 6;
631
- switch( *v ) {
632
- case '1': v++; m = "d"; break;
633
- case '2': v++;
634
- default: m = "B"; break;
635
- case '3': v++; m = "G"; break;
636
- case '4': v++; m = "E"; break;
637
- case '5': v++; m = "C"; break;
638
- }
639
- global_octave_shift = 0;
640
- }
641
- if( j && !SDL_strncasecmp(v,"bass",4) ) {
642
- j = 0;
643
- v += 4;
644
- switch( *v ) {
645
- case '1': v++; m = "C"; break;
646
- case '2': v++; m = "A,"; break;
647
- case '3': v++; m = "F,"; break;
648
- case '4': v++;
649
- default: m = "D,"; break;
650
- case '5': v++; m = "B,,"; break;
651
- }
652
- if( global_octave_shift == 99 )
653
- global_octave_shift = -2;
654
- }
655
- if( j && !SDL_strncasecmp(v,"tenor",5) ) {
656
- j = 0;
657
- v += 5;
658
- switch( *v ) {
659
- case '1': v++; m = "G"; break;
660
- case '2': v++; m = "E"; break;
661
- case '3': v++; m = "C"; break;
662
- case '4': v++;
663
- default: m = "A,"; break;
664
- case '5': v++; m = "F,"; break;
665
- }
666
- if( global_octave_shift == 99 )
667
- global_octave_shift = 1;
668
- }
669
- if( j && !SDL_strncasecmp(v,"alto",4) ) {
670
- j = 0;
671
- v += 4;
672
- switch( *v ) {
673
- case '1': v++; m = "G"; break;
674
- case '2': v++; m = "E"; break;
675
- case '3': v++;
676
- default: m = "C"; break;
677
- case '4': v++; m = "A,"; break;
678
- case '5': v++; m = "F,"; break;
679
- }
680
- if( global_octave_shift == 99 )
681
- global_octave_shift = 1;
682
- }
683
- if( j && SDL_strchr("+-",*v) && *v && v[1]=='8' ) {
684
- switch(*v) {
685
- case '+':
686
- t += 12;
687
- break;
688
- case '-':
689
- t -= 12;
690
- break;
691
- }
692
- v += 2;
693
- if( !SDL_strncasecmp(v,"va",2) ) v += 2;
694
- global_octave_shift = 0;
695
- j = 0;
696
- }
697
- if( j ) {
698
- while( *v && *v != ' ' && *v != ']' ) v++;
699
- }
700
- }
701
- if( SDL_strlen(mv) > 0 ) // someone set the middle note
702
- t += abc_interval(mv, m);
703
- if( global_octave_shift == 99 )
704
- global_octave_shift = 0;
705
- return t;
706
- }
707
-
708
- // =============================================================================
709
- static ABCTRACK *abc_locate_track(ABCHANDLE *h, const char *voice, int pos)
710
- // =============================================================================
711
- {
712
- ABCTRACK *tr, *prev, *trunused;
713
- char vc[21];
714
- int i, trans=0, voiceno=0, instrno = 1, channo = 0;
715
- for( ; *voice == ' '; voice++ ) ; // skip leading spaces
716
- for( i=0; i+1 < sizeof(vc) && *voice && *voice != ']' && *voice != '%' && !SDL_isspace(*voice); voice++ ) // can work with inline voice instructions
717
- vc[i++] = *voice;
718
- vc[i] = '\0';
719
- prev = NULL;
720
- trunused = NULL;
721
- if( !pos ) trans = abc_transpose(voice);
722
- for( tr=h->track; tr; tr=tr->next ) {
723
- if( tr->vno == 0 ) {
724
- if( !trunused ) trunused = tr; // must reuse mastertrack (h->track) as first
725
- }
726
- else {
727
- if( !SDL_strncasecmp(tr->v, vc, 20) ) {
728
- if( tr->vpos == pos )
729
- return tr;
730
- trans = tr->transpose;
731
- global_octave_shift = tr->octave_shift;
732
- voiceno = tr->vno;
733
- instrno = tr->instr;
734
- channo = tr->chan;
735
- }
736
- }
737
- prev = tr;
738
- }
739
- if( trunused ) {
740
- tr = trunused;
741
- if( pos ) {
742
- tr->vno = voiceno;
743
- tr->instr = instrno;
744
- tr->chan = channo;
745
- }
746
- else {
747
- global_voiceno++;
748
- tr->vno = global_voiceno;
749
- tr->instr = 1;
750
- tr->chan = 0;
751
- }
752
- tr->vpos = pos;
753
- tr->tiedvpos = pos;
754
- SDL_strlcpy(tr->v, vc, 20);
755
- tr->v[20] = '\0';
756
- tr->mute = 0;
757
- tr->transpose = trans;
758
- tr->octave_shift = global_octave_shift;
759
- tr->volume = h->track->volume;
760
- tr->tienote = NULL;
761
- tr->legato = 0;
762
- return tr;
763
- }
764
- tr = abc_new_track(h, vc, pos);
765
- if( pos ) {
766
- tr->vno = voiceno;
767
- tr->instr = instrno;
768
- tr->chan = channo;
769
- }
770
- tr->transpose = trans;
771
- tr->octave_shift = global_octave_shift;
772
- if( prev ) prev->next = tr;
773
- else h->track = tr;
774
- return tr;
775
- }
776
-
777
- // =============================================================================
778
- static ABCTRACK *abc_check_track(ABCHANDLE *h, ABCTRACK *tp)
779
- // =============================================================================
780
- {
781
- if( !tp ) {
782
- tp = abc_locate_track(h, "", 0); // must work for voiceless abc too...
783
- tp->transpose = h->ktrans;
784
- }
785
- return tp;
786
- }
787
-
788
- static void abc_add_capo(ABCHANDLE *h, ABCTRACK *tp, uint32_t tracktime)
789
- {
790
- ABCEVENT *e;
791
- char d[6];
792
- d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = 0;
793
- d[cmdflag] = 1;
794
- d[command] = cmdcapo;
795
- e = abc_new_event(h, tracktime, d);
796
- tp->capostart = e;
797
- abc_add_event(h, tp, e); // do this last (recursion danger)
798
- }
799
-
800
- static void abc_add_segno(ABCHANDLE *h, ABCTRACK *tp, uint32_t tracktime)
801
- {
802
- ABCEVENT *e;
803
- char d[6];
804
- d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = 0;
805
- d[cmdflag] = 1;
806
- d[command] = cmdsegno;
807
- e = abc_new_event(h, tracktime, d);
808
- abc_add_event(h, tp, e);
809
- }
810
-
811
- static void abc_add_coda(ABCHANDLE *h, ABCTRACK *tp, uint32_t tracktime)
812
- {
813
- ABCEVENT *e;
814
- char d[6];
815
- d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = 0;
816
- d[cmdflag] = 1;
817
- d[command] = cmdcoda;
818
- e = abc_new_event(h, tracktime, d);
819
- abc_add_event(h, tp, e);
820
- }
821
-
822
- static void abc_add_fine(ABCHANDLE *h, ABCTRACK *tp, uint32_t tracktime)
823
- {
824
- ABCEVENT *e;
825
- char d[6];
826
- d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = 0;
827
- d[cmdflag] = 1;
828
- d[command] = cmdfine;
829
- e = abc_new_event(h, tracktime, d);
830
- abc_add_event(h, tp, e);
831
- }
832
-
833
- static void abc_add_tocoda(ABCHANDLE *h, ABCTRACK *tp, uint32_t tracktime)
834
- {
835
- ABCEVENT *e;
836
- char d[6];
837
- d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = 0;
838
- d[cmdflag] = 1;
839
- d[command] = cmdtocoda;
840
- e = abc_new_event(h, tracktime, d);
841
- abc_add_event(h, tp, e);
842
- }
843
-
844
- // first track is dirigent, remove all control events from other tracks
845
- // to keep the information where the events should be relative to note events
846
- // in the same tick the ticks are octated and four added for note events
847
- // the control events that come before the note events get a decremented tick,
848
- // those that come after get an incremented tick, for example:
849
- // ctrl ctrl note ctrl ctrl note
850
- // original: t t t t t+1 t+1
851
- // recoded: 8t+1 8t+2 8t+4 8t+5 8t+11 8t+12
852
- static void abc_remove_unnecessary_events(ABCHANDLE *h)
853
- {
854
- ABCTRACK *tp,*ptp;
855
- ABCEVENT *ep, *el;
856
- uint32_t ct, et;
857
- int d;
858
- ptp = NULL;
859
- for( tp=h->track; tp; tp=tp->next ) {
860
- el = NULL;
861
- ep = tp->head;
862
- ct = 0;
863
- d = -3;
864
- while( ep ) {
865
- et = ep->tracktick;
866
- ep->tracktick <<= 3;
867
- ep->tracktick += 4;
868
- if( ep->flg == 1 ) {
869
- ep->tracktick += d;
870
- d++;
871
- if( d == 0 ) d = -1;
872
- if( d == 4 ) d = 3;
873
- if( tp!=h->track ) ep->cmd = cmdhide;
874
- switch( ep->cmd ) {
875
- case cmdhide:
876
- case cmdsync:
877
- if( el ) {
878
- el->next = ep->next;
879
- if( !el->next )
880
- tp->tail = el;
881
- _mm_free(h->trackhandle,ep);
882
- ep = el->next;
883
- }
884
- else {
885
- tp->head = ep->next;
886
- if( !tp->head )
887
- tp->tail = NULL;
888
- _mm_free(h->trackhandle,ep);
889
- ep = tp->head;
890
- }
891
- break;
892
- default:
893
- el = ep;
894
- ep = ep->next;
895
- break;
896
- }
897
- }
898
- else {
899
- el = ep;
900
- ep = ep->next;
901
- d = 1;
902
- }
903
- if( et > ct )
904
- d = -3;
905
- ct = et;
906
- }
907
- if( !tp->head ) { // no need to keep empty tracks...
908
- if( ptp ) {
909
- ptp->next = tp->next;
910
- _mm_free(h->trackhandle,tp);
911
- tp = ptp;
912
- }
913
- else if (tp->next) {
914
- h->track = tp->next;
915
- _mm_free(h->trackhandle,tp);
916
- tp = h->track;
917
- } else {
918
- break;
919
- }
920
- }
921
- ptp = tp; // remember previous track
922
- }
923
- }
924
-
925
- // set ticks back, and handle partbreaks
926
- static void abc_retick_events(ABCHANDLE *h)
927
- {
928
- ABCTRACK *tp;
929
- ABCEVENT *ep;
930
- uint32_t et, tt=0, at = abcticks(64 * h->speed);
931
- for( tp=h->track; tp; tp=tp->next ) {
932
- // make ticks relative
933
- tt = 0;
934
- for( ep=tp->head; ep; ep=ep->next ) {
935
- et = ep->tracktick >> 3;
936
- ep->tracktick = et - tt;
937
- tt = et;
938
- }
939
- // make ticks absolute again, skipping no-op partbreaks
940
- tt = 0;
941
- for( ep=tp->head; ep; ep=ep->next ) {
942
- ep->tracktick += tt;
943
- tt = ep->tracktick;
944
- if( ep->flg == 1 && ep->cmd == cmdpartbrk ) {
945
- if( tt % at ) {
946
- tt += at;
947
- tt /= at;
948
- tt *= at;
949
- ep->tracktick -= abcticks(h->speed); // break plays current row
950
- }
951
- else ep->cmd = cmdhide;
952
- }
953
- }
954
- }
955
- }
956
-
957
- // make sure every track has the control events it needs, this way it is not
958
- // necessary to have redundant +segno+ +D.C.+ etc in the voices, the first voice
959
- // is the master, it is pointed to by the member 'track' in the ABCHANDLE
960
- static void abc_synchronise_tracks(ABCHANDLE *h)
961
- {
962
- ABCTRACK *tp;
963
- uint32_t tm; // tracktime in master
964
- ABCEVENT *em, *es, *et, *ec; // events in master, slave, slave temporary and copied event
965
- if( !h || !h->track ) return;
966
- abc_remove_unnecessary_events(h);
967
- for( tp = h->track->next; tp; tp = tp->next ) {
968
- for( em=h->track->head; em; em=em->next ) {
969
- if( em->flg == 1 ) { // some kind of control event
970
- switch( em->cmd ) {
971
- case cmdchord:
972
- case cmdhide:
973
- case cmdtempo:
974
- case cmdsync:
975
- break;
976
- default: // check to see if copy is necessary
977
- ec = abc_copy_event(h, em);
978
- tm = em->tracktick;
979
- es = tp->head; // allways search from the begin...
980
- for( et=es; et && et->tracktick <= tm; et=et->next )
981
- es = et;
982
- if( es == NULL || es->tracktick > tm ) { // special case: head of track
983
- ec->next = es;
984
- tp->head = ec;
985
- }
986
- else {
987
- ec->next = es->next;
988
- es->next = ec;
989
- }
990
- break;
991
- }
992
- }
993
- }
994
- }
995
- abc_retick_events(h);
996
- }
997
-
998
- static void abc_add_event(ABCHANDLE *h, ABCTRACK *tp, ABCEVENT *e)
999
- {
1000
- if( !tp->capostart ) abc_add_capo(h, tp, global_songstart);
1001
- if( tp->tail ) {
1002
- tp->tail->next = e;
1003
- tp->tail = e;
1004
- }
1005
- else {
1006
- tp->head = e;
1007
- tp->tail = e;
1008
- }
1009
- }
1010
-
1011
- static void abc_add_partbreak(ABCHANDLE *h, ABCTRACK *tp, uint32_t tracktime)
1012
- {
1013
- ABCEVENT *e;
1014
- char d[6];
1015
- d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = 0;
1016
- d[cmdflag] = 1;
1017
- d[command] = cmdpartbrk;
1018
- e = abc_new_event(h, tracktime, d);
1019
- abc_add_event(h, tp, e);
1020
- }
1021
-
1022
- static void abc_add_tempo_event(ABCHANDLE *h, ABCTRACK *tp, uint32_t tracktime, int tempo)
1023
- {
1024
- ABCEVENT *e;
1025
- char d[6];
1026
- d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = 0;
1027
- d[cmdflag] = 1;
1028
- d[command] = cmdtempo;
1029
- e = abc_new_event(h, tracktime, d);
1030
- e->lpar = tempo;
1031
- abc_add_event(h, tp, e);
1032
- }
1033
-
1034
- static void abc_add_noteoff(ABCHANDLE *h, ABCTRACK *tp, uint32_t tracktime)
1035
- {
1036
- ABCEVENT *e;
1037
- char d[6];
1038
- d[note] = 0;
1039
- d[octave] = 0;
1040
- d[smpno] = pat_gmtosmp(tp->instr);
1041
- d[volume] = 0;
1042
- d[effect] = 0;
1043
- d[effoper] = 0;
1044
- e = abc_new_event(h, tracktime, d);
1045
- abc_add_event(h, tp, e);
1046
- }
1047
-
1048
- static int abc_dynamic_volume(ABCTRACK *tp, uint32_t tracktime, int vol)
1049
- {
1050
- uint32_t slidetime;
1051
- int voldelta;
1052
- if( tp->mute ) return 0;
1053
- if( tp->slidevol == 0 ) return vol;
1054
- if( tracktime < tp->slidevoltime ) return vol;
1055
- slidetime = modticks(tracktime - tp->slidevoltime);
1056
- voldelta = (slidetime * 15) / 64 / 6; // slide from say mf up to f in one pattern's time
1057
- if( tp->slidevol > -2 && voldelta > 15 ) voldelta = 15; // never to much dynamics
1058
- if( tp->slidevol > 0 ) vol += voldelta;
1059
- else vol -= voldelta;
1060
- if( vol < 2 ) vol = 2; // xmms divides this by 2....
1061
- if( vol > 127 ) vol = 127;
1062
- return vol;
1063
- }
1064
-
1065
- static void abc_track_untie_short_chordnotes(ABCHANDLE *h)
1066
- {
1067
- ABCTRACK *tp;
1068
- int vn;
1069
- tp = h->tp;
1070
- vn = tp->vno;
1071
- for( tp = h->track; tp; tp = tp->next )
1072
- if( tp != h->tp && tp->vno == vn && tp->tienote ) {
1073
- abc_message("short notes in chord can not be tied:\n%s", h->line);
1074
- tp->tienote = 0;
1075
- }
1076
- }
1077
-
1078
- static void abc_track_clear_tiednote(ABCHANDLE *h)
1079
- {
1080
- ABCTRACK *tp;
1081
- int vn;
1082
- tp = h->tp;
1083
- vn = tp->vno;
1084
- for( tp = h->track; tp; tp = tp->next )
1085
- if( tp->vno == vn ) tp->tienote = 0;
1086
- }
1087
-
1088
- static void abc_track_clear_tiedvpos(ABCHANDLE *h)
1089
- {
1090
- ABCTRACK *tp;
1091
- int vn;
1092
- tp = h->tp;
1093
- vn = tp->vno;
1094
- for( tp = h->track; tp; tp = tp->next )
1095
- if( tp->vno == vn ) tp->tiedvpos = tp->vpos;
1096
- }
1097
-
1098
- static ABCTRACK *abc_track_with_note_tied(ABCHANDLE *h, uint32_t tracktime, int n, int oct)
1099
- {
1100
- int vn, vp;
1101
- ABCTRACK *tp;
1102
- ABCEVENT *e;
1103
- tp = h->tp;
1104
- vn = tp->vno;
1105
- vp = tp->vpos;
1106
- for( tp = h->track; tp; tp = tp->next ) {
1107
- if( tp->vno == vn ) {
1108
- e = tp->tienote;
1109
- if( e && e->tracktick < tracktime
1110
- && e->par[octave] == oct && SDL_abs(e->par[note] - n) < 3 ) {
1111
- if( tp->vpos != vp ) tp->tiedvpos = vp;
1112
- h->tp = tp;
1113
- return tp;
1114
- }
1115
- }
1116
- }
1117
- tp = h->tp;
1118
- vp = tp->tiedvpos;
1119
- if( tp->vpos != vp ) {
1120
- // chord note track already returned in previous call
1121
- for( tp = h->track; tp; tp = tp->next ) {
1122
- if( tp->vno == vn && tp->vpos == vp ) {
1123
- tp->tiedvpos = h->tp->vpos;
1124
- h->tp = tp;
1125
- return tp;
1126
- }
1127
- }
1128
- }
1129
- return h->tp;
1130
- }
1131
-
1132
- static int abc_add_noteon(ABCHANDLE *h, int ch, const char *p, uint32_t tracktime, char *barkey, int vol, ABCEVENT_X_EFFECT fx, int fxop)
1133
- {
1134
- ABCEVENT *e;
1135
- ABCTRACK *tp;
1136
- int i,j,k;
1137
- int n,oct;
1138
- char d[6];
1139
- tp = h->tp;
1140
- switch(ch) {
1141
- case '^':
1142
- if( p[0] == '^' ) {
1143
- n = p[1];
1144
- i = 2;
1145
- ch = 'x';
1146
- }
1147
- else {
1148
- n = p[0];
1149
- i = 1;
1150
- }
1151
- break;
1152
- case '_':
1153
- if( p[0] == '_' ) {
1154
- n = p[1];
1155
- i = 2;
1156
- ch = 'b';
1157
- }
1158
- else {
1159
- n = p[0];
1160
- i = 1;
1161
- }
1162
- break;
1163
- case '=':
1164
- n = p[0];
1165
- i = 1;
1166
- break;
1167
- default:
1168
- n = ch;
1169
- i = 0;
1170
- break;
1171
- }
1172
- for( k=0; k<51; k++ ) {
1173
- if( n == barkey[k] )
1174
- break;
1175
- }
1176
- j = k;
1177
- if( k > 24 )
1178
- k -= 25; // had something like A# over Bb key F signature....
1179
- if( i ) {
1180
- // propagate accidentals if necessary
1181
- // DON'T do redundant accidentals they're always relative to C-scale
1182
- for( k=0; k<25; k++ ) {
1183
- if( n == sig[7][k] )
1184
- break;
1185
- }
1186
- if( k < 25 ) { // only do real notes...
1187
- switch(ch) {
1188
- case 'x':
1189
- k++;
1190
- case '^':
1191
- k++;
1192
- break;
1193
- case 'b':
1194
- k--;
1195
- case '_':
1196
- k--;
1197
- break;
1198
- case '=':
1199
- break;
1200
- }
1201
- if( j < 25 ) // was it not A# over Bb?
1202
- barkey[j] = ' ';
1203
- barkey[k] = n;
1204
- }
1205
- }
1206
- oct = 3; // ABC note pitch C is C4 and pitch c is C5
1207
- if( k < 25 ) {
1208
- k += tp->transpose;
1209
- while( k > 12 ) {
1210
- oct++;
1211
- k -= 12;
1212
- }
1213
- while( k < 0 ) {
1214
- oct--;
1215
- k += 12;
1216
- }
1217
- d[note] = 23 + k; // C0 is midi notenumber 24
1218
- }
1219
- else
1220
- d[note] = 0; // someone has doen ^X3 or something like it...
1221
- while( p[i] && SDL_strchr(",'",p[i]) ) {
1222
- if( p[i]==',' ) oct--;
1223
- else oct++;
1224
- i++;
1225
- tp->octave_shift = 0; // forget we ever had to look at it
1226
- }
1227
- if( tp->octave_shift )
1228
- tp->transpose += 12 * tp->octave_shift;
1229
- oct += tp->octave_shift;
1230
- tp->octave_shift = 0; // after the first note we never have to look at it again
1231
- if( oct < 0 ) oct = 0;
1232
- if( oct > 9 ) oct = 9;
1233
- d[octave] = oct;
1234
- d[smpno] = pat_gmtosmp(tp->instr);
1235
- d[volume] = abc_dynamic_volume(tp, tracktime, vol);
1236
- d[effect] = fx; // effect
1237
- d[effoper] = fxop;
1238
- tp = abc_track_with_note_tied(h, tracktime, d[note], oct);
1239
- if( tp->tienote ) {
1240
- if( tp->tienote->par[note] != d[note] ) {
1241
- if( SDL_abs(tp->tienote->par[note] - d[note]) < 3 ) {
1242
- // may be tied over bar symbol, recover local accidental to barkey
1243
- k = tp->tienote->par[note] - 23 - tp->transpose;
1244
- while( k < 0 ) k += 12;
1245
- while( k > 12 ) k -= 12;
1246
- if( (IsUpper(n) && barkey[k+12] == ' ') || (IsLower(n) && barkey[k] == ' ') ) {
1247
- barkey[j] = ' ';
1248
- if( IsUpper(n) )
1249
- barkey[k] = n;
1250
- else
1251
- barkey[k+12] = n;
1252
- d[note] = tp->tienote->par[note];
1253
- d[octave] = tp->tienote->par[octave];
1254
- }
1255
- }
1256
- }
1257
- }
1258
- if( tp->tienote
1259
- && tp->tienote->par[note] == d[note]
1260
- && tp->tienote->par[octave] == d[octave] ) {
1261
- for( e = tp->tienote; e; e = e->next ) {
1262
- if( e->par[note] == 0 && e->par[octave] == 0 ) { // undo noteoff
1263
- e->flg = 1;
1264
- e->cmd = cmdhide;
1265
- e->lpar = 0;
1266
- break;
1267
- }
1268
- }
1269
- tp->tienote->tiednote = 1; // mark him for the pattern writers
1270
- for( j=i; SDL_isdigit(p[j]) || p[j]=='/'; j++ ) ; // look ahead to see if this one is tied too
1271
- if( p[j] != '-' ) // is this note tied too?
1272
- tp->tienote = NULL; // if not the tie ends here...
1273
- return i;
1274
- }
1275
- tp->tienote = NULL;
1276
- if( tp->tail
1277
- && tp->tail->tracktick == tracktime
1278
- && tp->tail->par[note] == 0
1279
- && tp->tail->par[octave] == 0 ) {
1280
- for( j=0; j<6; j++ )
1281
- tp->tail->par[j] = d[j];
1282
- }
1283
- else {
1284
- e = abc_new_event(h, tracktime, d);
1285
- abc_add_event(h, tp, e);
1286
- }
1287
- if( i > 0 && p[i-1] == '"' ) {
1288
- i--; // someone coded a weird note like ^"E"
1289
- abc_message("strange note encountered scanning %s", h->line);
1290
- }
1291
- return i;
1292
- }
1293
-
1294
- static void abc_add_dronenote(ABCHANDLE *h, ABCTRACK *tp, uint32_t tracktime, int nnum, int vol)
1295
- {
1296
- ABCEVENT *e;
1297
- int j,k;
1298
- int oct;
1299
- char d[6];
1300
- oct = -1; // ABC note pitch C is C4 and pitch c is C5
1301
- k = nnum + 1;
1302
- while( k > 12 ) {
1303
- oct++;
1304
- k -= 12;
1305
- }
1306
- while( k < 0 ) {
1307
- oct--;
1308
- k += 12;
1309
- }
1310
- if( oct < 0 ) oct = 0;
1311
- d[note] = 23 + k; // C0 is midi notenumber 24
1312
- d[octave] = oct;
1313
- d[smpno] = pat_gmtosmp(tp->instr);
1314
- d[volume] = abc_dynamic_volume(tp, tracktime, vol);
1315
- d[effect] = 0; // effect
1316
- d[effoper] = 0;
1317
- if( tp->tail
1318
- && tp->tail->tracktick == tracktime
1319
- && tp->tail->par[note] == 0
1320
- && tp->tail->par[octave] == 0 ) {
1321
- for( j=0; j<6; j++ )
1322
- tp->tail->par[j] = d[j];
1323
- }
1324
- else {
1325
- e = abc_new_event(h, tracktime, d);
1326
- abc_add_event(h, tp, e);
1327
- }
1328
- }
1329
-
1330
- static void abc_add_chordnote(ABCHANDLE *h, ABCTRACK *tp, uint32_t tracktime, int nnum, int vol)
1331
- {
1332
- abc_add_dronenote(h, tp, tracktime, nnum + 23, tp->mute? 0: vol);
1333
- }
1334
-
1335
- static void abc_add_drumnote(ABCHANDLE *h, ABCTRACK *tp, uint32_t tracktime, int nnum, int vol)
1336
- {
1337
- abc_add_dronenote(h, tp, tracktime, nnum, tp->mute? 0: vol);
1338
- }
1339
-
1340
- static void abc_add_variant_start(ABCHANDLE *h, ABCTRACK *tp, uint32_t tracktime, int n)
1341
- {
1342
- ABCEVENT *e;
1343
- char d[6];
1344
- d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = 0;
1345
- d[cmdflag] = 1;
1346
- d[command] = cmdvariant;
1347
- e = abc_new_event(h, tracktime, d);
1348
- e->lpar = 1<<n;
1349
- abc_add_event(h, tp, e);
1350
- }
1351
-
1352
- static void abc_add_variant_choise(ABCTRACK *tp, int n)
1353
- {
1354
- tp->tail->lpar |= 1<<n;
1355
- }
1356
-
1357
- static void abc_add_chord(const char *p, ABCHANDLE *h, ABCTRACK *tp, uint32_t tracktime)
1358
- {
1359
- ABCEVENT *e;
1360
- char d[6];
1361
- char s[8];
1362
- int i;
1363
- const char *n = " C D EF G A Bc d ef g a b";
1364
- d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = 0;
1365
- d[cmdflag] = 1;
1366
- d[command] = cmdchord;
1367
- if( p[0] == '(' ) p++; // chord between parens like: (C)
1368
- for( i=0; n[i]; i++ )
1369
- if( *p == n[i] ) {
1370
- d[chordnote] = i;
1371
- break;
1372
- }
1373
- p++;
1374
- switch(*p) {
1375
- case 'b':
1376
- d[chordnote]--;
1377
- p++;
1378
- break;
1379
- case '#':
1380
- d[chordnote]++;
1381
- p++;
1382
- break;
1383
- }
1384
- d[chordbase] = d[chordnote];
1385
- for( i=0; i < sizeof(s) - 1 && p[i] && p[i] != '"' && p[i] != '/' && p[i] != '(' && p[i] != ')' && p[i] != ' '; i++ ) s[i] = p[i];
1386
- s[i] = '\0';
1387
- p = &p[i];
1388
- if( *p=='/' ) {
1389
- p++;
1390
- for( i=0; n[i]; i++ )
1391
- if( *p == n[i] ) {
1392
- d[chordbase] = i;
1393
- break;
1394
- }
1395
- p++;
1396
- switch(*p) {
1397
- case 'b':
1398
- d[chordbase]--;
1399
- p++;
1400
- break;
1401
- case '#':
1402
- d[chordbase]++;
1403
- p++;
1404
- break;
1405
- }
1406
- }
1407
- for( i=0; i<chordsnamed; i++ )
1408
- if( !SDL_strcmp(s, chordname[i]) ) {
1409
- d[chordnum] = i;
1410
- break;
1411
- }
1412
- if( i==chordsnamed ) {
1413
- abc_message("Failure: unrecognized chordname %s",s);
1414
- return;
1415
- }
1416
- e = abc_new_event(h, tracktime, d);
1417
- abc_add_event(h, tp, e);
1418
- }
1419
-
1420
- static void abc_add_setloop(ABCHANDLE *h, ABCTRACK *tp, uint32_t tracktime)
1421
- {
1422
- ABCEVENT *e;
1423
- char d[6];
1424
- d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = 0;
1425
- d[cmdflag] = 1;
1426
- d[command] = cmdloop;
1427
- e = abc_new_event(h, tracktime, d);
1428
- abc_add_event(h, tp, e);
1429
- }
1430
-
1431
- static void abc_fade_track(ABCTRACK *tp, ABCEVENT *e)
1432
- {
1433
- while(e) {
1434
- if( e->flg != 1 && e->par[note] != 0 )
1435
- e->par[volume] = abc_dynamic_volume(tp, e->tracktick, e->par[volume]);
1436
- e = e->next;
1437
- }
1438
- }
1439
-
1440
- static void abc_add_setjumploop(ABCHANDLE *h, ABCTRACK *tp, uint32_t tracktime, ABCEVENT_JUMPTYPE j)
1441
- {
1442
- ABCEVENT *e;
1443
- char d[8];
1444
- d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = 0;
1445
- d[cmdflag] = 1;
1446
- d[command] = cmdjump;
1447
- d[jumptype] = j;
1448
- e = abc_new_event(h, tracktime, d);
1449
- abc_add_event(h, tp, e);
1450
- }
1451
-
1452
- static void abc_add_sync(ABCHANDLE *h, ABCTRACK *tp, uint32_t tracktime)
1453
- {
1454
- ABCEVENT *e;
1455
- char d[6];
1456
- e = tp->tail;
1457
- if( e && e->tracktick == tracktime ) return;
1458
- if( e && e->flg == 1 && e->cmd == cmdsync ) {
1459
- e->tracktick = tracktime;
1460
- return;
1461
- }
1462
- d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = 0;
1463
- d[cmdflag] = 1;
1464
- d[command] = cmdsync;
1465
- e = abc_new_event(h, tracktime, d);
1466
- abc_add_event(h, tp, e);
1467
- }
1468
-
1469
- static void abc_add_gchord_syncs(ABCHANDLE *h, ABCTRACK *tpc, uint32_t tracktime)
1470
- {
1471
- ABCTRACK *tp;
1472
- int i;
1473
- for( i = GCHORDBPOS; i < DRUMPOS; i++ ) {
1474
- tp = abc_locate_track(h, tpc->v, i);
1475
- abc_add_sync(h,tp,tracktime);
1476
- }
1477
- }
1478
-
1479
- static void abc_add_drum_sync(ABCHANDLE *h, ABCTRACK *tpr, uint32_t tracktime)
1480
- {
1481
- ABCTRACK *tp;
1482
- tp = abc_locate_track(h, tpr->v, DRUMPOS);
1483
- abc_add_sync(h,tp,tracktime);
1484
- }
1485
-
1486
- static int abc_getnumber(const char *p, int *number)
1487
- {
1488
- int i,h;
1489
- i = 0;
1490
- h = 0;
1491
- while( SDL_isdigit(p[i]) ) {
1492
- h = 10 * h + p[i] - '0';
1493
- i++;
1494
- }
1495
- if( i==0 )
1496
- *number = 1;
1497
- else
1498
- *number = h;
1499
- return i;
1500
- }
1501
-
1502
- static int abc_getexpr(const char *p, int *number)
1503
- {
1504
- int i, term, total;
1505
- i = 0;
1506
- while( SDL_isspace(p[i]) )
1507
- i++;
1508
- if( p[i] == '(' ) {
1509
- i += abc_getexpr(p+i+1, number);
1510
- while( p[i] && (p[i] != ')') )
1511
- i++;
1512
- return i;
1513
- }
1514
- i += abc_getnumber(p+i, &total);
1515
- while( SDL_isspace(p[i]) )
1516
- i++;
1517
- while( p[i] == '+' ) {
1518
- i += 1 + abc_getexpr(p+i+1, &term);
1519
- total += term;
1520
- while( SDL_isspace(p[i]) )
1521
- i++;
1522
- }
1523
- *number = total;
1524
- return i;
1525
- }
1526
-
1527
- static int abc_notelen(const char *p, int *len, int *div)
1528
- {
1529
- int i,h,k;
1530
- i = abc_getnumber(p,len);
1531
- h = 1;
1532
- while( p[i] == '/' ) {
1533
- h *= 2;
1534
- i++;
1535
- }
1536
- if( SDL_isdigit(p[i]) ) {
1537
- h /= 2;
1538
- i += abc_getnumber(p+i,&k);
1539
- }
1540
- else k = 1;
1541
- *div = h * k;
1542
- return i;
1543
- }
1544
-
1545
- static int abc_brokenrithm(const char *p, int *nl, int *nd, int *b, int hornpipe)
1546
- {
1547
- switch( *b ) {
1548
- case '<':
1549
- *nl *= 3;
1550
- *nd *= 2;
1551
- hornpipe = 0;
1552
- break;
1553
- case '>':
1554
- *nd *= 2;
1555
- hornpipe = 0;
1556
- break;
1557
- }
1558
- *b = *p;
1559
- switch( *b ) {
1560
- case '>':
1561
- *nl *= 3;
1562
- *nd *= 2;
1563
- return 1;
1564
- case '<':
1565
- *nd *= 2;
1566
- return 1;
1567
- default:
1568
- *b = 0;
1569
- break;
1570
- }
1571
- if( hornpipe ) { // still true then make 1/8 notes broken rithme
1572
- if( *nl == 1 && *nd == 1 ) {
1573
- *b = '>';
1574
- *nl = 3;
1575
- *nd = 2;
1576
- }
1577
- }
1578
- return 0;
1579
- }
1580
-
1581
- // put p notes in the time q for the next r notes
1582
- static int abc_tuplet(int *nl, int *nd, int p, int q, int r)
1583
- {
1584
- if( !r ) return 0;
1585
- *nl *= q;
1586
- *nd *= p;
1587
- return r - 1;
1588
- }
1589
-
1590
- // evaluate [Q:"string" n1/m1 n2/m2 n3/m3 n4/m4=bpm "string"]
1591
- // minimal form [Q:"string"]
1592
- // most used form [Q: 1/4=120]
1593
- static int abc_extract_tempo(const char *p, int invoice)
1594
- {
1595
- int nl, nd, ns, in, tempo;
1596
- int nl1=0, nd1, notes, state;
1597
- const char *q;
1598
- in = 0;
1599
- nl = 0;
1600
- nd = 1;
1601
- ns = 120;
1602
- notes = 0;
1603
- state = 0;
1604
- for( q=p; *q; q++ ) {
1605
- if( in ) {
1606
- if( *q=='"' )
1607
- in = 0;
1608
- }
1609
- else {
1610
- if( *q == ']' ) break;
1611
- switch( *q ) {
1612
- case '"':
1613
- in = 1;
1614
- break;
1615
- case '/':
1616
- notes++;
1617
- state = 1;
1618
- nl1 = ns;
1619
- break;
1620
- case '=':
1621
- break;
1622
- default:
1623
- if( SDL_isdigit(*q) ) {
1624
- if( state ) {
1625
- q+=abc_getnumber(q,&nd1)-1;
1626
- state = 0;
1627
- nl = nl * nd1 + nl1 * nd;
1628
- nd = nd * nd1;
1629
- }
1630
- else
1631
- q+=abc_getnumber(q,&ns)-1;
1632
- }
1633
- break;
1634
- }
1635
- }
1636
- }
1637
- if( !notes ) {
1638
- nl = 1;
1639
- nd = 4;
1640
- }
1641
- if( !nd ) tempo = 120;
1642
- else tempo = ns * nl * 4 / nd; // mod tempo is really BPM where one B is equal to a quartnote
1643
- if( tempo <= 0 )
1644
- tempo = 120;
1645
- if( invoice ) {
1646
- nl = global_tempo_factor;
1647
- nd = global_tempo_divider;
1648
- }
1649
- global_tempo_factor = 1;
1650
- global_tempo_divider = 1;
1651
- while( tempo/global_tempo_divider > 255 )
1652
- global_tempo_divider++;
1653
- tempo /= global_tempo_divider;
1654
- while( tempo * global_tempo_factor < 256 )
1655
- global_tempo_factor++;
1656
- global_tempo_factor--;
1657
- tempo *= global_tempo_factor;
1658
- if( tempo * 3 < 512 ) {
1659
- global_tempo_factor *= 3;
1660
- global_tempo_divider *= 2;
1661
- tempo = (tempo * 3) / 2;
1662
- }
1663
- if( invoice ) {
1664
- if( nl != global_tempo_factor || nd != global_tempo_divider ) {
1665
- ns = (tempo * nl * global_tempo_divider) / (nd * global_tempo_factor);
1666
- if( ns > 31 && ns < 256 ) {
1667
- tempo = ns;
1668
- global_tempo_factor = nl;
1669
- global_tempo_divider = nd;
1670
- }
1671
- else
1672
- abc_message("Failure: inconvenient tempo change in middle of voice (%s)", p);
1673
- }
1674
- }
1675
- return tempo;
1676
- }
1677
-
1678
- static void abc_set_parts(char **d, char *p)
1679
- {
1680
- int i,k,m,n;
1681
- size_t j, size;
1682
- char *q;
1683
- if( *d ) SDL_free(*d);
1684
- *d = 0;
1685
- if( !p ) return;
1686
- for( i=0; p[i] && p[i] != '%'; i++ ) {
1687
- if( !SDL_strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ().0123456789 ",p[i]) ) {
1688
- abc_message("invalid characters in part string scanning P:%s", p);
1689
- return;
1690
- }
1691
- }
1692
- // decode constructs like "((AB)2.(CD)2)3.(AB)E2" to "ABABCDCDABABCDCDABABCDCDABEE"
1693
- // first compute needed storage...
1694
- j=0;
1695
- k=0;
1696
- for( i=0; p[i] && p[i] != '%'; i++ ) {
1697
- if( IsUpper(p[i]) ) {
1698
- j++;
1699
- }
1700
- if( SDL_isdigit(p[i]) ) {
1701
- n=abc_getnumber(p+i,&k);
1702
- if( k == 0 )
1703
- k = 1;
1704
- if( p[i-1] == ')' )
1705
- j *= k; // never mind multiple parens, just take the worst case
1706
- else
1707
- j += k-1;
1708
- i += n-1;
1709
- }
1710
- }
1711
- // even if j overflows above, it will only wrap around and still be okay
1712
- size = ( j >= INT_MAX )? INT_MAX - 1 : j;
1713
- q = (char *)_mm_calloc(h, size + 1, sizeof(char)); // enough storage for the worst case
1714
- // now copy bytes from p to *d, taking parens and digits in account
1715
- j = 0;
1716
- for( i=0; p[i] && p[i] != '%' && j < size && i < size; i++ ) {
1717
- if( SDL_isdigit(p[i]) || IsUpper(p[i]) || p[i] == '(' || p[i] == ')' ) {
1718
- if( p[i] == ')' ) {
1719
- for( n=j; n > 0 && q[n-1] != '('; n-- ) ; // find open paren in q
1720
- // q[n+1] to q[j] contains the substring that must be repeated
1721
- if( n > 0 ) {
1722
- for( k = n; k<j; k++ ) q[k-1] = q[k]; // shift to the left...
1723
- j--;
1724
- }
1725
- else {
1726
- abc_message("Warning: Unbalanced right parens in P: definition %s",p);
1727
- break;
1728
- }
1729
- n = j - n + 1; // number of repeatable characters
1730
- i += abc_getnumber(p+i+1,&k);
1731
- while( k-- > 1 ) {
1732
- for( m=0; m<n; m++ ) {
1733
- q[j] = q[j-n];
1734
- j++;
1735
- }
1736
- }
1737
- continue;
1738
- }
1739
- if( SDL_isdigit(p[i]) ) {
1740
- n = abc_getnumber(p+i,&k);
1741
- i += n - 1;
1742
- while( k-- > 1 ) {
1743
- q[j] = q[j-1];
1744
- j++;
1745
- }
1746
- continue;
1747
- }
1748
- q[j] = p[i];
1749
- j++;
1750
- }
1751
- }
1752
- q[j] = '\0';
1753
- // remove any left over parens
1754
- for( i=0; i<j; i++ ) {
1755
- if( q[i] == '(' ) {
1756
- abc_message("Warning: Unbalanced left parens in P: definition %s",p);
1757
- for( k=i; k<j; k++ ) q[k] = q[k+1];
1758
- j--;
1759
- }
1760
- }
1761
- *d = q;
1762
- }
1763
-
1764
- static void abc_appendpart(ABCHANDLE *h, ABCTRACK *tp, uint32_t pt1, uint32_t pt2)
1765
- {
1766
- ABCEVENT *e, *ec;
1767
- uint32_t dt;
1768
- dt = tp->tail->tracktick - pt1;
1769
- for( e=tp->head; e && e->tracktick <= pt2; e=e->next ) {
1770
- if( e->tracktick >= pt1 ) {
1771
- if( e->flg != 1 || e->cmd == cmdsync || e->cmd == cmdchord ) {
1772
- if( e != tp->tail ) {
1773
- // copy this event at tail
1774
- ec = abc_copy_event(h,e);
1775
- ec->tracktick += dt;
1776
- ec->part = '*';
1777
- tp->tail->next = ec;
1778
- tp->tail = ec;
1779
- }
1780
- }
1781
- }
1782
- }
1783
- abc_add_sync(h, tp, pt2 + dt); // make sure there is progression...
1784
- }
1785
-
1786
- static uint32_t abc_pattracktime(ABCHANDLE *h, uint32_t tracktime)
1787
- {
1788
- ABCEVENT *e;
1789
- uint32_t dt,et,pt=abcticks(64 * h->speed);
1790
- if(!h || !h->track || !h->track->head ) return 0;
1791
- dt = 0;
1792
- for( e=h->track->head; e && e->tracktick <= tracktime; e=e->next ) {
1793
- if( e->flg == 1 && e->cmd == cmdpartbrk ) {
1794
- et = e->tracktick + dt;
1795
- if( et % pt ) {
1796
- et += pt;
1797
- et /= pt;
1798
- et *= pt;
1799
- dt = et - e->tracktick;
1800
- }
1801
- }
1802
- }
1803
- return (tracktime + dt);
1804
- }
1805
-
1806
- static int abc_patno(ABCHANDLE *h, uint32_t tracktime)
1807
- {
1808
- return modticks(abc_pattracktime(h, tracktime)) / 64 / h->speed;
1809
- }
1810
-
1811
- static void abc_stripoff(ABCHANDLE *h, ABCTRACK *tp, uint32_t tt)
1812
- {
1813
- ABCEVENT *e1, *e2;
1814
- e2 = NULL;
1815
- for( e1 = tp->head; e1 && e1->tracktick <= tt; e1=e1->next )
1816
- e2 = e1;
1817
- if( e2 ) {
1818
- e1 = e2->next;
1819
- tp->tail = e2;
1820
- e2->next = NULL;
1821
- }
1822
- else {
1823
- e1 = tp->tail;
1824
- tp->head = NULL;
1825
- tp->tail = NULL;
1826
- }
1827
- while( e1 ) {
1828
- e2 = e1->next;
1829
- _mm_free(h->trackhandle,e1);
1830
- e1 = e2;
1831
- }
1832
- }
1833
-
1834
- static void abc_keeptiednotes(ABCHANDLE *h, uint32_t fromtime, uint32_t totime) {
1835
- ABCTRACK *tp;
1836
- ABCEVENT *e,*n,*f;
1837
- if( totime <= fromtime ) return;
1838
- for( tp=h->track; tp; tp=tp->next ) {
1839
- if( tp->vno ) { // if track is in use...
1840
- n = NULL;
1841
- for( e=tp->head; e && e->tracktick < fromtime; e = e->next )
1842
- if( e->flg != 1 ) n = e; // remember it when it is a note event
1843
- if( n && n->tiednote ) { // we've a candidate to tie over the break
1844
- while( e && e->tracktick < totime ) e=e->next; // skip to other part
1845
- if( e && e->tracktick == totime ) { // if this is on begin row of this part
1846
- f = NULL;
1847
- while( !f && e && e->tracktick == totime ) {
1848
- if( e->flg != 1 ) f = e;
1849
- e = e->next;
1850
- }
1851
- if( f && f->par[note] ) { // pfoeie, we've found a candidate
1852
- if( SDL_abs(n->par[note] - f->par[note]) < 3 ) { // undo the note on
1853
- f->flg = 1;
1854
- f->cmd = cmdhide;
1855
- f->lpar = 0;
1856
- }
1857
- }
1858
- }
1859
- }
1860
- }
1861
- }
1862
- }
1863
-
1864
- static uint32_t abc_fade_tracks(ABCHANDLE *h, char *abcparts, uint32_t ptt[27])
1865
- {
1866
- ABCTRACK *tp;
1867
- ABCEVENT *e0;
1868
- char *p;
1869
- int vol;
1870
- uint32_t pt1, pt2;
1871
- uint32_t tt;
1872
- tt = h->track->tail->tracktick;
1873
- for( tp=h->track->next; tp; tp=tp->next ) {
1874
- if( !tp->tail ) abc_add_sync(h, tp, tt); // no empty tracks please...
1875
- if( tp->tail->tracktick > tt ) abc_stripoff(h, tp, tt); // should not happen....
1876
- if( tp->tail->tracktick < tt ) abc_add_sync(h, tp, tt);
1877
- }
1878
- for( tp=h->track; tp; tp=tp->next ) {
1879
- vol = 127;
1880
- e0 = tp->tail;
1881
- if( tp->slidevol != -2 ) {
1882
- tp->slidevol = -2;
1883
- tp->slidevoltime = e0->tracktick;
1884
- }
1885
- tp->mute = 0; // unmute track for safety, notes in a muted track already have zero volume...
1886
- while( vol > 5 ) {
1887
- for( p=abcparts; *p && vol > 5; p++ ) {
1888
- pt1 = ptt[*p-'A'];
1889
- pt2 = ptt[*p-'A'+1];
1890
- abc_appendpart(h, tp, pt1, pt2);
1891
- vol = abc_dynamic_volume(tp, tp->tail->tracktick, 127);
1892
- }
1893
- }
1894
- abc_fade_track(tp,e0);
1895
- }
1896
- return h->track->tail->tracktick;
1897
- }
1898
-
1899
- static void abc_song_to_parts(ABCHANDLE *h, char **abcparts, BYTE partp[27][2])
1900
- {
1901
- uint32_t starttick;
1902
- ABCEVENT *e;
1903
- int i, fading, loop, normal, partno, partsegno, partloop, partcoda, parttocoda, partfine, skip, x, y;
1904
- int vmask[27],nextp[27];
1905
- uint32_t ptt[27];
1906
- char buf[256]; // must be enough, mod's cannot handle more than 240 patterns
1907
- char *pfade;
1908
- if( !h || !h->track || !h->track->capostart ) return;
1909
- SDL_strlcpy(buf,"A",sizeof (buf)); // initialize our temporary array
1910
- i = 1;
1911
- loop = 1;
1912
- partno = 0;
1913
- partsegno = 0;
1914
- partloop = 0;
1915
- partcoda = -1;
1916
- parttocoda = -1;
1917
- partfine = -1;
1918
- starttick = h->track->capostart->tracktick;
1919
- ptt[0] = starttick;
1920
- vmask[0] = -1;
1921
- nextp[0] = 1;
1922
- for( e=h->track->capostart; e; e=e->next ) {
1923
- if( e->flg == 1 ) {
1924
- switch( e->cmd ) {
1925
- case cmdpartbrk:
1926
- if( e->tracktick > starttick) {
1927
- starttick = e->tracktick; // do not make empty parts
1928
- if( partno < 26 ) {
1929
- partno++;
1930
- ptt[partno] = starttick;
1931
- }
1932
- if( i < 255 ) buf[i++] = partno+'A';
1933
- vmask[partno] = -1;
1934
- nextp[partno] = partno+1;
1935
- }
1936
- break;
1937
- case cmdloop:
1938
- partloop = partno;
1939
- loop = 1; // start counting anew...
1940
- break;
1941
- case cmdvariant:
1942
- vmask[partno] = e->lpar;
1943
- break;
1944
- case cmdjump:
1945
- x = 0;
1946
- fading = 0;
1947
- normal = 0;
1948
- skip = 0;
1949
- pfade = &buf[i];
1950
- switch( e->par[jumptype] ) {
1951
- case jumpfade:
1952
- fading = 1;
1953
- case jumpnormal:
1954
- normal = 1;
1955
- x = partloop;
1956
- loop++;
1957
- break;
1958
- case jumpdsfade:
1959
- fading = 1;
1960
- case jumpdasegno:
1961
- x = partsegno;
1962
- break;
1963
- case jumpdcfade:
1964
- fading = 1;
1965
- case jumpdacapo:
1966
- x = 0;
1967
- break;
1968
- default:
1969
- // defaults set above.
1970
- break;
1971
- }
1972
- if( vmask[partno] != -1 ) nextp[partno] = x;
1973
- if( partno < 26 ) ptt[partno+1] = e->tracktick; // for handling ties over breaks
1974
- while( x <= partno ) {
1975
- if( skip == 1 && x == partcoda ) skip = 0;
1976
- y = !skip;
1977
- if( y ) {
1978
- if( !normal ) {
1979
- if( x == partfine ) skip = 2;
1980
- if( x == parttocoda ) skip = 1;
1981
- y = !skip;
1982
- }
1983
- if( !(vmask[x] & (1<<loop)) ) y = 0;
1984
- }
1985
- if( y ) {
1986
- if( i < 255 ) buf[i++] = x+'A';
1987
- if( nextp[x] != x + 1 ) loop++;
1988
- x = nextp[x];
1989
- }
1990
- else
1991
- x++;
1992
- }
1993
- if( fading && partno < 25 && i < 254 ) { // add single part with fading tracks
1994
- partno++;
1995
- ptt[partno] = e->tracktick;
1996
- buf[i] = '\0'; // close up pfade with zero byte
1997
- starttick = abc_fade_tracks(h, pfade, ptt);
1998
- buf[i++] = partno+'A';
1999
- partno++;
2000
- ptt[partno] = starttick;
2001
- buf[i++] = partno+'A'; // one extra to throw away...
2002
- e = h->track->tail; // this is the edge of the world captain...
2003
- }
2004
- break;
2005
- case cmdtocoda:
2006
- parttocoda = partno;
2007
- break;
2008
- case cmdcoda:
2009
- partcoda = partno;
2010
- break;
2011
- case cmdfine:
2012
- partfine = partno;
2013
- break;
2014
- case cmdsegno:
2015
- partsegno = partno;
2016
- break;
2017
- }
2018
- }
2019
- e->part = partno+'a'; // small caps for generated parts...
2020
- }
2021
- i--; // strip off last partno
2022
- if( partno > 0 ) partno--;
2023
- buf[i] = '\0';
2024
- if( i > 1 ) {
2025
- for( i=1; buf[i]; i++ ) {
2026
- if( buf[i] != buf[i-1] + 1 ) {
2027
- x = buf[i-1] - 'A';
2028
- y = buf[i] - 'A';
2029
- abc_keeptiednotes(h, ptt[x+1], ptt[y]);
2030
- }
2031
- }
2032
- }
2033
- starttick = h->track->tail->tracktick;
2034
- ptt[partno+1] = starttick;
2035
- for( i=0; i<=partno; i++ ) {
2036
- partp[i][0] = abc_patno(h, ptt[i]);
2037
- partp[i][1] = abc_patno(h, ptt[i+1]);
2038
- }
2039
- // calculate end point of last part
2040
- starttick = abc_pattracktime(h, starttick);
2041
- if( starttick % abcticks(64 * h->speed) )
2042
- partp[partno][1]++;
2043
- abc_set_parts(abcparts, buf);
2044
- }
2045
-
2046
- // =====================================================================================
2047
- static char *abc_fgets(MMFILE *mmfile, char buf[], unsigned int bufsz)
2048
- // =====================================================================================
2049
- {
2050
- if( mmfeof(mmfile) ) return NULL;
2051
- mmfgets(buf,bufsz,mmfile);
2052
- return buf;
2053
- }
2054
-
2055
- // =====================================================================================
2056
- static char *abc_fgetbytes(MMFILE *mmfile, char buf[], unsigned int bufsz)
2057
- // =====================================================================================
2058
- {
2059
- unsigned int i;
2060
- long pos;
2061
- if( mmfeof(mmfile) ) return NULL;
2062
- for( i=0; i<bufsz-2; i++ ) {
2063
- buf[i] = (char)mmfgetc(mmfile);
2064
- if( buf[i] == '\n' ) break;
2065
- if( buf[i] == '\r' ) {
2066
- pos = mmftell(mmfile);
2067
- if( mmfgetc(mmfile) != '\n' ) mmfseek(mmfile, pos, SEEK_SET);
2068
- buf[i] = '\n';
2069
- break;
2070
- }
2071
- }
2072
- if( i != bufsz-2 && buf[i] == '\n' ) i++;
2073
- buf[i] = '\0';
2074
- return buf;
2075
- }
2076
-
2077
- static void abc_substitute(ABCHANDLE *h, char *target, char *s)
2078
- {
2079
- char *p, *q;
2080
- int i;
2081
- int l = SDL_strlen(target);
2082
- int n = SDL_strlen(s);
2083
- if (l <= 0 ||n <= 0 || SDL_strstr(s, target))
2084
- return;
2085
- while( (p=SDL_strstr(h->line, target)) ) {
2086
- if( (i=SDL_strlen(h->line)) + n - l >= (int)h->len ) {
2087
- h->line = (char *)_mm_recalloc(h->allochandle, h->line, h->len<<1, sizeof(char));
2088
- h->len <<= 1;
2089
- p=SDL_strstr(h->line, target);
2090
- }
2091
- if( n > l ) {
2092
- for( q=&h->line[i]; q>p; q-- ) q[n-l] = q[0];
2093
- for( q=s; *q; q++ ) *p++ = *q;
2094
- }
2095
- else {
2096
- const size_t buflen = h->len - ((size_t) (p - h->line));
2097
- SDL_strlcpy(p,s,buflen);
2098
- SDL_strlcat(p,p+l,buflen);
2099
- }
2100
- }
2101
- }
2102
-
2103
- static void abc_preprocess(ABCHANDLE *h, ABCMACRO *m)
2104
- {
2105
- int i, j, k, l, a, b;
2106
- if( m->n ) {
2107
- k = m->n - m->name;
2108
- for( i=0; i<14; i++ ) {
2109
- const size_t tlen = SDL_strlen(m->name) + 1;
2110
- char *t = alloca(tlen);
2111
- SDL_strlcpy(t, m->name, tlen);
2112
- t[k] = "CDEFGABcdefgab"[i];
2113
- l = SDL_strlen(m->subst);
2114
- char *s = alloca(2 * l + 1);
2115
- char *p = s;
2116
- for( j=0; j<l; j++ ) {
2117
- a = m->subst[j];
2118
- if( a > 'g' && IsLower(a) ) {
2119
- b = a - 'n';
2120
- a = "CDEFGABCDEFGABcdefgabcdefgab"[i+b+7];
2121
- *p++ = a;
2122
- if( i+b < 0 )
2123
- *p++ = ',';
2124
- else if( i+b > 13 )
2125
- *p++ = '\'';
2126
- }
2127
- else *p++ = a;
2128
- }
2129
- *p = '\0';
2130
- abc_substitute(h, t, s);
2131
- }
2132
- }
2133
- else
2134
- abc_substitute(h, m->name, m->subst);
2135
- }
2136
-
2137
- static char *abc_gets(ABCHANDLE *h, MMFILE *mmfile)
2138
- {
2139
- int i;
2140
- ABCMACRO *mp;
2141
- if( !h->len ) {
2142
- h->len = 64; // initial line size, adequate for most abc's
2143
- h->line = (char *)_mm_calloc(h->allochandle, h->len, sizeof(char));
2144
- }
2145
- if( abc_fgetbytes(mmfile, h->line, h->len) ) {
2146
- while( (i=SDL_strlen(h->line)) > (int)(h->len - 3) ) {
2147
- // line too short, double it
2148
- h->line = (char *)_mm_recalloc(h->allochandle, h->line, h->len<<1, sizeof(char));
2149
- if( h->line[i-1] != '\n' )
2150
- abc_fgetbytes(mmfile, &h->line[i], h->len);
2151
- h->len <<= 1;
2152
- }
2153
- h->line[i-1] = '\0'; // strip off newline
2154
- for( mp=h->macro; mp; mp=mp->next )
2155
- abc_preprocess(h,mp);
2156
- return h->line;
2157
- }
2158
- return NULL;
2159
- }
2160
-
2161
- static int abc_parse_decorations(ABCHANDLE *h, ABCTRACK *tp, const char *p)
2162
- {
2163
- int vol=0;
2164
- if( !SDL_strncmp(p,"mp",2) ) vol = 75;
2165
- if( !SDL_strncmp(p,"mf",2) ) vol = 90;
2166
- if( !SDL_strncmp(p,"sfz",3) ) vol = 100;
2167
- if( *p == 'p' ) {
2168
- vol = 60;
2169
- while( *p++ == 'p' ) vol -= 15;
2170
- if( vol < 1 ) vol = 1;
2171
- }
2172
- if( *p == 'f' ) {
2173
- vol = 105;
2174
- while( *p++ == 'f' ) vol += 15;
2175
- if( vol > 135 ) vol = 127; // ffff
2176
- if( vol > 127 ) vol = 125; // fff
2177
- }
2178
- if( vol ) {
2179
- tp->volume = vol;
2180
- if( tp == h->track ) { // copy volume over to all voice tracks
2181
- for( ; tp; tp=tp->next ) {
2182
- if( tp->vpos == 0 || tp->vpos > DRONEPOS2 ) tp->volume = vol;
2183
- }
2184
- tp = h->track;
2185
- }
2186
- }
2187
- return tp->volume;
2188
- }
2189
-
2190
- // =====================================================================================
2191
- BOOL CSoundFile_TestABC(const BYTE *lpStream, DWORD dwMemLength)
2192
- // =====================================================================================
2193
- {
2194
- char id[128];
2195
- int hasText = 0;
2196
- // scan file for first K: line (last in header)
2197
- MMFILE mmfile;
2198
- mmfile.mm = (char *)lpStream;
2199
- mmfile.sz = dwMemLength;
2200
- mmfseek(&mmfile,0,SEEK_SET);
2201
- int ppos = mmfile.pos;
2202
-
2203
- while(abc_fgets(&mmfile,id,128)) {
2204
-
2205
- if (id[0] == 0 && hasText == 0 && mmfile.pos < ppos + 120) return(0); //probably binary
2206
- if (id[0] == 0) continue; // blank line.
2207
-
2208
- if (!abc_isvalidchar(id[0]) || !abc_isvalidchar(id[1])) {
2209
- return(0); // probably not an ABC.
2210
- }
2211
- if(id[0]=='K'
2212
- && id[1]==':'
2213
- && (IsAlpha(id[2]) || SDL_isspace(id[2])) ) return 1;
2214
- // disable binary error if have any "tag"
2215
- if((id[0]>='A' && id[0]<='Z')
2216
- && id[1]==':'
2217
- && (IsAlpha(id[2]) || SDL_isspace(id[2])) ) hasText = 1;
2218
- }
2219
- return 0;
2220
- }
2221
-
2222
- // =====================================================================================
2223
- static ABCHANDLE *ABC_Init(void)
2224
- {
2225
- ABCHANDLE *retval;
2226
- char *p;
2227
- char buf[10];
2228
- retval = (ABCHANDLE *)SDL_calloc(1,sizeof(ABCHANDLE));
2229
- if( !retval ) return NULL;
2230
-
2231
- retval->track = NULL;
2232
- retval->macro = NULL;
2233
- retval->umacro = NULL;
2234
- retval->beatstring = NULL;
2235
- retval->pickrandom = 0;
2236
- retval->len = 0;
2237
- retval->line = NULL;
2238
- retval->gchord[0] = 0;
2239
- retval->barticks = 0;
2240
- p = SDL_getenv(ABC_ENV_NORANDOMPICK);
2241
- if( p ) {
2242
- if( SDL_isdigit(*p) )
2243
- retval->pickrandom = SDL_atoi(p);
2244
- if( *p == '-' ) {
2245
- retval->pickrandom = SDL_atoi(p+1)-1; // xmms preloads the file
2246
- SDL_snprintf(buf,sizeof(buf),"-%ld",retval->pickrandom+2);
2247
- SDL_setenv(ABC_ENV_NORANDOMPICK, buf, 1);
2248
- }
2249
- }
2250
- else {
2251
- srandom((uint32_t)time(0)); // initialize random generator with seed
2252
- retval->pickrandom = 1+(int)(10000.0*random()/(RAND_MAX+1.0));
2253
- // can handle pickin' from songbooks with 10.000 songs
2254
- SDL_snprintf(buf,sizeof(buf),"-%ld",retval->pickrandom); // xmms preloads the file
2255
- SDL_setenv(ABC_ENV_NORANDOMPICK, buf, 1);
2256
- }
2257
- return retval;
2258
- }
2259
-
2260
- static void ABC_CleanupTrack(ABCTRACK *tp)
2261
- {
2262
- ABCEVENT *ep, *en;
2263
- if( tp ) {
2264
- for( ep=tp->head; ep; ep = en ) {
2265
- en=ep->next;
2266
- SDL_free(ep);
2267
- }
2268
- tp->head = NULL;
2269
- }
2270
- }
2271
-
2272
- static void ABC_CleanupMacro(ABCMACRO *m)
2273
- {
2274
- if( m->name )
2275
- SDL_free(m->name);
2276
- if( m->subst )
2277
- SDL_free(m->subst);
2278
- SDL_free(m);
2279
- }
2280
-
2281
- // =====================================================================================
2282
- static void ABC_CleanupTracks(ABCHANDLE *handle)
2283
- // =====================================================================================
2284
- {
2285
- ABCTRACK *tp, *tn;
2286
- if(handle) {
2287
- for( tp=handle->track; tp; tp = tn ) {
2288
- tn=tp->next;
2289
- ABC_CleanupTrack(tp);
2290
- }
2291
- handle->track = NULL;
2292
- }
2293
- }
2294
-
2295
- // =====================================================================================
2296
- static void ABC_CleanupMacros(ABCHANDLE *handle)
2297
- // =====================================================================================
2298
- {
2299
- ABCMACRO *mp, *mn;
2300
- if(handle) {
2301
- for( mp=handle->macro; mp; mp = mn ) {
2302
- mn=mp->next;
2303
- ABC_CleanupMacro(mp);
2304
- }
2305
- for( mp=handle->umacro; mp; mp = mn ) {
2306
- mn=mp->next;
2307
- ABC_CleanupMacro(mp);
2308
- }
2309
- handle->macro = NULL;
2310
- handle->umacro = NULL;
2311
- }
2312
- }
2313
-
2314
- // =====================================================================================
2315
- static void ABC_Cleanup(ABCHANDLE *handle)
2316
- // =====================================================================================
2317
- {
2318
- if(handle) {
2319
- ABC_CleanupMacros(handle);
2320
- ABC_CleanupTracks(handle);
2321
- if( handle->line )
2322
- SDL_free(handle->line);
2323
- if( handle->beatstring )
2324
- SDL_free(handle->beatstring);
2325
- SDL_free(handle);
2326
- }
2327
- }
2328
-
2329
- static int abc_is_global_event(ABCEVENT *e)
2330
- {
2331
- return e->flg == 1 && (e->cmd == cmdtempo || e->cmd == cmdpartbrk);
2332
- }
2333
-
2334
- static ABCEVENT *abc_next_global(ABCEVENT *e)
2335
- {
2336
- for( ; e && !abc_is_global_event(e); e=e->next ) ;
2337
- return e;
2338
- }
2339
-
2340
- static ABCEVENT *abc_next_note(ABCEVENT *e)
2341
- {
2342
- for( ; e && e->flg == 1; e=e->next ) ;
2343
- return e;
2344
- }
2345
-
2346
- static int ABC_ReadPatterns(MODCOMMAND *pattern[], WORD psize[], ABCHANDLE *h, int numpat, int channels)
2347
- // =====================================================================================
2348
- {
2349
- int pat,row,i,ch,trillbits;
2350
- BYTE n,ins,vol;
2351
- ABCTRACK *t;
2352
- ABCEVENT *e, *en, *ef, *el;
2353
- uint32_t tt1, tt2;
2354
- MODCOMMAND *m;
2355
- int patbrk, tempo;
2356
- if( numpat > MAX_PATTERNS ) numpat = MAX_PATTERNS;
2357
-
2358
- // initialize start points of event list in tracks
2359
- for( t = h->track; t; t = t->next ) t->capostart = t->head;
2360
- trillbits = 0; // trill effect admininstration: one bit per channel, max 32 channnels
2361
- for( pat = 0; pat < numpat; pat++ ) {
2362
- pattern[pat] = CSoundFile_AllocatePattern(64, channels);
2363
- if( !pattern[pat] ) return 0;
2364
- psize[pat] = 64;
2365
- for( row = 0; row < 64; row++ ) {
2366
- tt1 = abcticks((pat * 64 + row ) * h->speed);
2367
- tt2 = tt1 + abcticks(h->speed);
2368
- ch = 0;
2369
- tempo = 0;
2370
- patbrk = 0;
2371
- if ( h->track )
2372
- for( e=abc_next_global(h->track->capostart); e && e->tracktick < tt2; e=abc_next_global(e->next) ) {
2373
- if( e && e->tracktick >= tt1 ) { // we have a tempo event in this row
2374
- switch( e->cmd ) {
2375
- case cmdtempo:
2376
- tempo = e->lpar;
2377
- break;
2378
- case cmdpartbrk:
2379
- patbrk = 1;
2380
- break;
2381
- }
2382
- }
2383
- }
2384
- for( t = h->track; t; t = t->next ) {
2385
- for( e=abc_next_note(t->capostart); e && e->tracktick < tt1; e=abc_next_note(e->next) ) ;
2386
- i = 0;
2387
- ef = NULL;
2388
- en = e;
2389
- el = e;
2390
- for( ; e && e->tracktick < tt2; e=abc_next_note(e->next) ) { // we have a note event in this row
2391
- t->capostart = e;
2392
- i++;
2393
- if( e->par[volume] ) {
2394
- if( !ef ) ef = e;
2395
- el = e;
2396
- }
2397
- }
2398
- m = &pattern[pat][row * channels + ch];
2399
- m->param = 0;
2400
- m->command = CMD_NONE;
2401
- if( i ) {
2402
- trillbits &= ~(1<<ch);
2403
- if( i == 1 || ef == el || !ef ) { // only one event in this row
2404
- if( ef ) e = ef;
2405
- else e = en;
2406
- el = t->capostart;
2407
- i = e->par[note] + ((e->par[octave])*12);
2408
- if( t->chan == 10 ) {
2409
- n = pat_gm_drumnote(i) + 23;
2410
- ins = pat_gmtosmp(pat_gm_drumnr(i));
2411
- }
2412
- else {
2413
- n = pat_modnote(i);
2414
- ins = e->par[smpno];
2415
- }
2416
- vol = e->par[volume]/2;
2417
- if( e->par[volume] > 0 ) {
2418
- if( e->par[effect] == accent ) vol += vol / 20;
2419
- if( vol > 64 ) vol = 64;
2420
- if( el->par[volume] == 0 ) { // note cut
2421
- m->param = el->tracktick - tt1;
2422
- m->command = CMD_S3MCMDEX;
2423
- m->param |= 0xC0;
2424
- }
2425
- else {
2426
- switch( e->par[effect] ) {
2427
- case trill:
2428
- m->command = CMD_VIBRATO;
2429
- m->param = 0xC2; // speed 12 depth 2
2430
- trillbits |= (1<<ch);
2431
- break;
2432
- case bow:
2433
- m->command = CMD_XFINEPORTAUPDOWN;
2434
- m->param |= (e->par[effoper])? 0x12: 0x22;
2435
- break;
2436
- default:
2437
- m->param = modticks(e->tracktick - tt1);
2438
- if( m->param ) { // note delay
2439
- m->command = CMD_S3MCMDEX;
2440
- m->param |= 0xD0;
2441
- }
2442
- break;
2443
- }
2444
- }
2445
- }
2446
- m->instr = ins;
2447
- m->note = n; // <- normal note
2448
- m->volcmd = VOLCMD_VOLUME;
2449
- m->vol = vol;
2450
- }
2451
- else {
2452
- // two notes in one row, use FINEPITCHSLIDE runonce effect
2453
- // start first note on first tick and framedly runonce on seconds note tick
2454
- // use volume and instrument of last note
2455
- if( t->chan == 10 ) {
2456
- i = el->par[note] + ((el->par[octave])*12);
2457
- n = pat_gm_drumnote(i) + 23;
2458
- ins = pat_gmtosmp(pat_gm_drumnr(i));
2459
- i = n; // cannot change instrument here..
2460
- }
2461
- else {
2462
- i = ef->par[note] + ((ef->par[octave])*12);
2463
- n = pat_modnote(i);
2464
- ins = el->par[smpno];
2465
- i = pat_modnote(el->par[note] + ((el->par[octave])*12));
2466
- }
2467
- vol = el->par[volume]/2;
2468
- if( vol > 64 ) vol = 64;
2469
- m->instr = ins;
2470
- m->note = n; // <- normal note
2471
- m->volcmd = VOLCMD_VOLUME;
2472
- m->vol = vol;
2473
- m->param = ((i > n)?i-n:n-i);
2474
- if( m->param < 16 ) {
2475
- if( m->param ) {
2476
- m->command = CMD_XFINEPORTAUPDOWN;
2477
- m->param |= (i > n)? 0x10: 0x20;
2478
- }
2479
- else { // retrigger same note...
2480
- m->command = CMD_RETRIG;
2481
- m->param = modticks(el->tracktick - tt1);
2482
- }
2483
- }
2484
- else
2485
- m->command = (i > n)? CMD_PORTAMENTOUP: CMD_PORTAMENTODOWN;
2486
- }
2487
- }
2488
- else { // no new notes, keep on trilling...
2489
- if( trillbits & (1<<ch) ) {
2490
- m = &pattern[pat][row * channels + ch];
2491
- m->command = CMD_VIBRATO;
2492
- m->param = 0; // inherited from first effect
2493
- m->instr = 0;
2494
- m->note = 0;
2495
- m->volcmd = 0;
2496
- m->vol = 0;
2497
- }
2498
- }
2499
- if( m->param == 0 && m->command == CMD_NONE ) {
2500
- if( tempo ) {
2501
- m->command = CMD_TEMPO;
2502
- m->param = tempo;
2503
- tempo = 0;
2504
- }
2505
- else {
2506
- if( patbrk ) {
2507
- m->command = CMD_PATTERNBREAK;
2508
- patbrk = 0;
2509
- }
2510
- }
2511
- }
2512
- ch++;
2513
- }
2514
- if( tempo || patbrk ) return 1;
2515
- }
2516
- }
2517
- return 0;
2518
- }
2519
-
2520
- static int ABC_Key(const char *p)
2521
- {
2522
- int i,j;
2523
- char c[8];
2524
- SDL_memset(c, 0, sizeof (c));
2525
- const char *q;
2526
- while( SDL_isspace(*p) ) p++;
2527
- q = p;
2528
- for( i=0; i<8 && *p && *p != ']'; p++ ) {
2529
- if( SDL_isspace(*p) ) {
2530
- while( SDL_isspace(*p) ) p++;
2531
- if( SDL_strncasecmp(p, "min", 3) && SDL_strncasecmp(p, "maj", 3) )
2532
- break;
2533
- }
2534
- c[i] = *p;
2535
- i++;
2536
- }
2537
- if( !SDL_strcmp(c,"Hp") || !SDL_strcmp(c,"HP") ) // highland pipes
2538
- SDL_strlcpy(c,"Bm",sizeof (c)); // two sharps at c and f
2539
- if( !SDL_strcasecmp(c+1, "minor") ) i=2;
2540
- if( !SDL_strcasecmp(c+2, "minor") ) i=3;
2541
- if( !SDL_strcasecmp(c+1, "major") ) i=1;
2542
- if( !SDL_strcasecmp(c+2, "major") ) i=2;
2543
- if( !SDL_strcasecmp(c+1, "min") ) i=2;
2544
- if( !SDL_strcasecmp(c+2, "min") ) i=3;
2545
- if( !SDL_strcasecmp(c+1, "maj") ) i=1;
2546
- if( !SDL_strcasecmp(c+2, "maj") ) i=2;
2547
- for( ; i<6; i++ )
2548
- c[i] = ' ';
2549
- for( i=0; keySigs[i]; i++ ) {
2550
- for( j=10; j<46; j+=6 )
2551
- if( !SDL_strncasecmp(keySigs[i]+j, c, 6) )
2552
- return i;
2553
- }
2554
- abc_message("Failure: Unrecognised K: field %s", q);
2555
- return 7;
2556
- }
2557
-
2558
- static char *abc_skip_word(char *p)
2559
- {
2560
- while( SDL_isspace(*p) ) p++;
2561
- while( *p && !SDL_isspace(*p) && *p != ']') p++;
2562
- while( SDL_isspace(*p) ) p++;
2563
- return p;
2564
- }
2565
-
2566
- static uint32_t abc_tracktime(ABCTRACK *tp)
2567
- {
2568
- uint32_t tracktime;
2569
- if( tp->tail ) tracktime = tp->tail->tracktick;
2570
- else tracktime = 0;
2571
- if( tracktime < global_songstart )
2572
- tracktime = global_songstart;
2573
- return tracktime;
2574
- }
2575
-
2576
- static void abc_addchordname(const char *s, int len, const int *notes)
2577
- // adds chord name and note set to list of known chords
2578
- {
2579
- int i, j;
2580
- if(SDL_strlen(s) > 7) {
2581
- abc_message("Failure: Chord name cannot exceed 7 characters, %s", s);
2582
- return;
2583
- }
2584
- if(len > 6) {
2585
- abc_message("Failure: Named chord cannot have more than 6 notes, %s", s);
2586
- return;
2587
- }
2588
- for( i=0; i < chordsnamed; i++ ) {
2589
- if(SDL_strcmp(s, chordname[i]) == 0) {
2590
- /* change chord */
2591
- chordlen[i] = len;
2592
- for(j = 0; j < len; j++) chordnotes[i][j] = notes[j];
2593
- return;
2594
- }
2595
- }
2596
- if(chordsnamed > MAXCHORDNAMES - 1)
2597
- abc_message("Failure: Too many Guitar Chord Names used, %s", s);
2598
- else {
2599
- SDL_strlcpy(chordname[chordsnamed], s, 8);
2600
- chordlen[chordsnamed] = len;
2601
- for(j = 0; j < len; j++) chordnotes[chordsnamed][j] = notes[j];
2602
- chordsnamed++;
2603
- }
2604
- }
2605
-
2606
- static void abc_setup_chordnames()
2607
- // set up named guitar chords
2608
- {
2609
- static const int list_Maj[3] = { 0, 4, 7 };
2610
- static const int list_m[3] = { 0, 3, 7 };
2611
- static const int list_7[4] = { 0, 4, 7, 10 };
2612
- static const int list_m7[4] = { 0, 3, 7, 10 };
2613
- static const int list_maj7[4] = { 0, 4, 7, 11 };
2614
- static const int list_M7[4] = { 0, 4, 7, 11 };
2615
- static const int list_6[4] = { 0, 4, 7, 9 };
2616
- static const int list_m6[4] = { 0, 3, 7, 9 };
2617
- static const int list_aug[3] = { 0, 4, 8 };
2618
- static const int list_plus[3] = { 0, 4, 8 };
2619
- static const int list_aug7[4] = { 0, 4, 8, 10 };
2620
- static const int list_dim[3] = { 0, 3, 6 };
2621
- static const int list_dim7[4] = { 0, 3, 6, 9 };
2622
- static const int list_9[5] = { 0, 4, 7, 10, 2 };
2623
- static const int list_m9[5] = { 0, 3, 7, 10, 2 };
2624
- static const int list_maj9[5] = { 0, 4, 7, 11, 2 };
2625
- static const int list_M9[5] = { 0, 4, 7, 11, 2 };
2626
- static const int list_11[6] = { 0, 4, 7, 10, 2, 5 };
2627
- static const int list_dim9[5] = { 0, 4, 7, 10, 13 };
2628
- static const int list_sus[3] = { 0, 5, 7 };
2629
- static const int list_sus9[3] = { 0, 2, 7 };
2630
- static const int list_7sus[4] = { 0, 5, 7, 10 };
2631
- static const int list_7sus4[4] = { 0, 5, 7, 10 };
2632
- static const int list_7sus9[4] = { 0, 2, 7, 10 };
2633
- static const int list_9sus4[5] = { 0, 5, 10, 14, 19 };
2634
- static const int list_5[2] = { 0, 7 };
2635
- static const int list_13[6] = { 0, 4, 7, 10, 16, 21 };
2636
-
2637
- chordsnamed = 0;
2638
- abc_addchordname("", 3, list_Maj);
2639
- abc_addchordname("m", 3, list_m);
2640
- abc_addchordname("7", 4, list_7);
2641
- abc_addchordname("m7", 4, list_m7);
2642
- abc_addchordname("maj7", 4, list_maj7);
2643
- abc_addchordname("M7", 4, list_M7);
2644
- abc_addchordname("6", 4, list_6);
2645
- abc_addchordname("m6", 4, list_m6);
2646
- abc_addchordname("aug", 3, list_aug);
2647
- abc_addchordname("+", 3, list_plus);
2648
- abc_addchordname("aug7", 4, list_aug7);
2649
- abc_addchordname("7+", 4, list_aug7);
2650
- abc_addchordname("dim", 3, list_dim);
2651
- abc_addchordname("dim7", 4, list_dim7);
2652
- abc_addchordname("9", 5, list_9);
2653
- abc_addchordname("m9", 5, list_m9);
2654
- abc_addchordname("maj9", 5, list_maj9);
2655
- abc_addchordname("M9", 5, list_M9);
2656
- abc_addchordname("11", 6, list_11);
2657
- abc_addchordname("dim9", 5, list_dim9);
2658
- abc_addchordname("sus", 3, list_sus);
2659
- abc_addchordname("sus9", 3, list_sus9);
2660
- abc_addchordname("7sus", 4, list_7sus);
2661
- abc_addchordname("7sus4", 4, list_7sus4);
2662
- abc_addchordname("7sus9", 4, list_7sus9);
2663
- abc_addchordname("9sus4", 5, list_9sus4);
2664
- abc_addchordname("5", 2, list_5);
2665
- abc_addchordname("13", 6, list_13);
2666
- }
2667
-
2668
- static int abc_MIDI_getnumber(const char *p)
2669
- {
2670
- int n;
2671
- while( SDL_isspace(*p) ) p++;
2672
- abc_getnumber(p, &n);
2673
- if( n < 0 ) n = 0;
2674
- if( n > 127 ) n = 127;
2675
- return n;
2676
- }
2677
-
2678
- static int abc_MIDI_getprog(const char *p)
2679
- {
2680
- int n;
2681
- while( SDL_isspace(*p) ) p++;
2682
- abc_getnumber(p, &n);
2683
- if( n < 1 ) n = 1;
2684
- if( n > 128 ) n = 128;
2685
- return n;
2686
- }
2687
-
2688
- // MIDI drone <instr0> <pitch1> <pitch2> <vel1> <vel2>
2689
- static void abc_MIDI_drone(const char *p, int *gm, int *ptch, int *vol)
2690
- {
2691
- int i;
2692
- while( SDL_isspace(*p) ) p++;
2693
- p += abc_getnumber(p, &i);
2694
- i++; // adjust for 1..128
2695
- if( i>0 && i < 129 )
2696
- *gm = i;
2697
- else
2698
- *gm = 71; // bassoon
2699
- while( SDL_isspace(*p) ) p++;
2700
- p += abc_getnumber(p, &i);
2701
- if( i>0 && i < 127 )
2702
- ptch[0] = i;
2703
- else
2704
- ptch[0] = 45;
2705
- while( SDL_isspace(*p) ) p++;
2706
- p += abc_getnumber(p, &i);
2707
- if( i>0 && i < 127 )
2708
- ptch[1] = i;
2709
- else
2710
- ptch[1] = 33;
2711
- while( SDL_isspace(*p) ) p++;
2712
- p += abc_getnumber(p, &i);
2713
- if( i>0 && i < 127 )
2714
- vol[0] = i;
2715
- else
2716
- vol[0] = 80;
2717
- while( SDL_isspace(*p) ) p++;
2718
- p += abc_getnumber(p, &i);
2719
- if( i>0 && i < 127 )
2720
- vol[1] = i;
2721
- else
2722
- vol[1] = 80;
2723
- }
2724
-
2725
- static void abc_chan_to_tracks(ABCHANDLE *h, int tno, int ch)
2726
- {
2727
- ABCTRACK *tp;
2728
- if( tno>0 && tno<33 ) {
2729
- for( tp=h->track; tp; tp=tp->next ) {
2730
- if( tp->vno == tno && (tp->vpos < GCHORDBPOS || tp->vpos > DRONEPOS2) )
2731
- tp->chan = ch;
2732
- }
2733
- }
2734
- }
2735
-
2736
- // %%MIDI channel int1
2737
- // channel numbers are 1-16
2738
- static void abc_MIDI_channel(const char *p, ABCTRACK *tp, ABCHANDLE *h)
2739
- {
2740
- int i1, i2;
2741
- i1 = tp? tp->vno: 1;
2742
- for( ; *p && SDL_isspace(*p); p++ ) ;
2743
- if( SDL_isdigit(*p) ) {
2744
- p += abc_getnumber(p, &i2);
2745
- if( i2 >= 1 && i2 <= 16 )
2746
- abc_chan_to_tracks(h, i1, i2); // we start at 1
2747
- }
2748
- }
2749
-
2750
- static void abc_instr_to_tracks(ABCHANDLE *h, int tno, int gm)
2751
- {
2752
- ABCTRACK *tp;
2753
- if( tno>0 && tno<33 && gm>0 && gm<129 ) {
2754
- for( tp=h->track; tp; tp=tp->next ) {
2755
- if( tp->vno == tno && (tp->vpos < GCHORDBPOS || tp->vpos > DRONEPOS2) )
2756
- tp->instr = gm;
2757
- }
2758
- }
2759
- }
2760
-
2761
- // %%MIDI program [int1] <int2>
2762
- // instrument numbers are 0-127
2763
- static void abc_MIDI_program(const char *p, ABCTRACK *tp, ABCHANDLE *h)
2764
- {
2765
- int i1, i2;
2766
- i1 = tp? tp->vno: 1;
2767
- for( ; *p && SDL_isspace(*p); p++ ) ;
2768
- if( SDL_isdigit(*p) ) {
2769
- p += abc_getnumber(p, &i2);
2770
- for( ; *p && SDL_isspace(*p); p++ ) ;
2771
- if( SDL_isdigit(*p) ) {
2772
- i1 = i2;
2773
- p += abc_getnumber(p, &i2);
2774
- }
2775
- abc_instr_to_tracks(h, i1, i2 + 1); // we start at 1
2776
- }
2777
- }
2778
-
2779
- static void abc_mute_voice(ABCHANDLE *h, ABCTRACK *tp, int m)
2780
- {
2781
- ABCTRACK *t;
2782
- for( t=h->track; t; t=t->next ) {
2783
- if( t->vno == tp->vno ) t->mute = m;
2784
- }
2785
- }
2786
-
2787
- // %%MIDI voice [<ID>] [instrument=<integer> [bank=<integer>]] [mute]
2788
- // instrument numbers are 1-128
2789
- static void abc_MIDI_voice(const char *p, ABCTRACK *tp, ABCHANDLE *h)
2790
- {
2791
- int i1, i2;
2792
- for( ; *p && SDL_isspace(*p); p++ ) ;
2793
- if( SDL_strncmp(p,"instrument=",11) && SDL_strncmp(p,"mute",4) ) {
2794
- tp = abc_locate_track(h, p, 0);
2795
- for( ; *p && !SDL_isspace(*p); p++ ) ;
2796
- for( ; *p && SDL_isspace(*p); p++ ) ;
2797
- }
2798
- i1 = tp? tp->vno: 1;
2799
- i2 = 0;
2800
- if( !SDL_strncmp(p,"instrument=",11) && SDL_isdigit(p[11]) ) {
2801
- p += 11;
2802
- p += abc_getnumber(p, &i2);
2803
- for( ; *p && SDL_isspace(*p); p++ ) ;
2804
- if( !SDL_strncmp(p,"bank=",5) && SDL_isdigit(p[5]) ) {
2805
- for( ; *p && !SDL_isspace(*p); p++ ) ;
2806
- for( ; *p && SDL_isspace(*p); p++ ) ;
2807
- }
2808
- }
2809
- if( tp ) abc_mute_voice(h,tp,0);
2810
- if( !SDL_strncmp(p,"mute",4) && (p[4]=='\0' || p[4]=='%' || SDL_isspace(p[4])) ) {
2811
- if( tp ) abc_mute_voice(h,tp,1);
2812
- }
2813
- abc_instr_to_tracks(h, i1, i2); // starts already at 1 (draft 4.0)
2814
- }
2815
-
2816
- // %%MIDI chordname <string> <int1> <int2> ... <int6>
2817
- static void abc_MIDI_chordname(const char *p)
2818
- {
2819
- char name[20];
2820
- int i, notes[6];
2821
- SDL_memset(notes, 0, sizeof (notes));
2822
-
2823
- for( ; *p && SDL_isspace(*p); p++ ) ;
2824
- i = 0;
2825
- while ((i < 19) && (*p != ' ') && (*p != '\0')) {
2826
- name[i] = *p;
2827
- p = p + 1;
2828
- i = i + 1;
2829
- }
2830
- name[i] = '\0';
2831
- if(*p != ' ') {
2832
- abc_message("Failure: Bad format for chordname command, %s", p);
2833
- }
2834
- else {
2835
- i = 0;
2836
- while ((i < 6) && SDL_isspace(*p)) {
2837
- for( ; *p && SDL_isspace(*p); p++ ) ;
2838
- p += abc_getnumber(p, &notes[i]);
2839
- i = i + 1;
2840
- }
2841
- abc_addchordname(name, i, notes);
2842
- }
2843
- }
2844
-
2845
- // %%MIDI drum <string> <inst 1> ... <inst n> <vol 1> ... <vol n>
2846
- // instrument numbers are 0-127
2847
- static int abc_MIDI_drum(const char *p, ABCHANDLE *h)
2848
- {
2849
- char *q;
2850
- int i, n, m;
2851
- uint32_t len;
2852
- while( SDL_isspace(*p) ) p++;
2853
- if( !SDL_strncmp(p,"on",2) && (SDL_isspace(p[2]) || p[2] == '\0') ) return 2;
2854
- if( !SDL_strncmp(p,"off",3) && (SDL_isspace(p[3]) || p[3] == '\0') ) return 1;
2855
- n = 0; len = 0;
2856
- for( q = h->drum; *p && !SDL_isspace(*p); p++ ) {
2857
- if( !SDL_strchr("dz0123456789",*p) ) break;
2858
- *q++ = *p; len++;
2859
- if( !SDL_isdigit(*p) && len < sizeof(h->drum)-1 ) {
2860
- if( !SDL_isdigit(p[1]) ) { *q++ = '1'; len ++; }
2861
- n++; // count the silences too....
2862
- }
2863
- if (len >= sizeof(h->drum)-1) {
2864
- // consume the rest of the input
2865
- // definitely enough "drum last state" stored.
2866
- while ( *p && !SDL_isspace(*p) ) p++;
2867
- break;
2868
- }
2869
- }
2870
- *q = '\0';
2871
- q = h->drumins;
2872
- for( i = 0; i<n; i++ ) {
2873
- if( h->drum[i*2] == 'd' ) {
2874
- while( *p && SDL_isspace(*p) ) p++;
2875
- if( !SDL_isdigit(*p) ) {
2876
- m = 0;
2877
- while( *p && !SDL_isspace(*p) ) p++;
2878
- }
2879
- else
2880
- p += abc_getnumber(p,&m);
2881
- q[i] = m + 1; // we start at 1
2882
- }
2883
- else q[i] = 0;
2884
- }
2885
- q = h->drumvol;
2886
- for( i = 0; i<n; i++ ) {
2887
- if( h->drum[i*2] == 'd' ) {
2888
- while( *p && SDL_isspace(*p) ) p++;
2889
- if( !SDL_isdigit(*p) ) {
2890
- m = 0;
2891
- while( *p && !SDL_isspace(*p) ) p++;
2892
- }
2893
- else
2894
- p += abc_getnumber(p,&m);
2895
- q[i] = m;
2896
- }
2897
- else q[i] = 0;
2898
- }
2899
- return 0;
2900
- }
2901
-
2902
- // %%MIDI gchord <string>
2903
- static int abc_MIDI_gchord(const char *p, ABCHANDLE *h)
2904
- {
2905
- char *q;
2906
- uint32_t len = 0;
2907
- while( SDL_isspace(*p) ) p++;
2908
- if( !SDL_strncmp(p,"on",2) && (SDL_isspace(p[2]) || p[2] == '\0') ) return 2;
2909
- if( !SDL_strncmp(p,"off",3) && (SDL_isspace(p[3]) || p[3] == '\0') ) return 1;
2910
- for( q = h->gchord; *p && !SDL_isspace(*p); p++ ) {
2911
- if( !SDL_strchr("fbcz0123456789ghijGHIJ",*p) ) break;
2912
- *q++ = *p; len++;
2913
- if( !SDL_isdigit(*p) && len < sizeof(h->gchord)-1 && !SDL_isdigit(p[1]) ) { *q++ = '1'; len ++; }
2914
- if (len >= sizeof(h->gchord)-1) {
2915
- // consume the rest of the input
2916
- // definitely enough "drum last state" stored.
2917
- while ( *p && !SDL_isspace(*p) ) p++;
2918
- break;
2919
- }
2920
- }
2921
- *q = '\0';
2922
- return 0;
2923
- }
2924
-
2925
- static void abc_metric_gchord(ABCHANDLE *h, int mlen, int mdiv)
2926
- {
2927
- switch( 16 * mlen + mdiv ) {
2928
- case 0x24:
2929
- case 0x44:
2930
- case 0x22:
2931
- abc_MIDI_gchord("fzczfzcz", h);
2932
- break;
2933
- case 0x64:
2934
- case 0x32:
2935
- abc_MIDI_gchord("fzczczfzczcz", h);
2936
- break;
2937
- case 0x34:
2938
- case 0x38:
2939
- abc_MIDI_gchord("fzczcz", h);
2940
- break;
2941
- case 0x68:
2942
- abc_MIDI_gchord("fzcfzc", h);
2943
- break;
2944
- case 0x98:
2945
- abc_MIDI_gchord("fzcfzcfzc", h);
2946
- break;
2947
- case 0xc8:
2948
- abc_MIDI_gchord("fzcfzcfzcfzc", h);
2949
- break;
2950
- default:
2951
- if( mlen % 3 == 0 )
2952
- abc_MIDI_gchord("fzcfzcfzcfzcfzcfzcfzcfzcfzc", h);
2953
- else
2954
- abc_MIDI_gchord("fzczfzczfzczfzczfzczfzczfzcz", h);
2955
- if( mdiv == 8 ) h->gchord[mlen*2] = '\0';
2956
- else h->gchord[mlen*4] = '\0';
2957
- break;
2958
- }
2959
- }
2960
-
2961
- static void abc_MIDI_legato(const char *p, ABCTRACK *tp)
2962
- {
2963
- for( ; *p && SDL_isspace(*p); p++ ) ;
2964
- if( !SDL_strncmp(p,"off",3) ) tp->legato = 0;
2965
- else tp->legato = 1;
2966
- }
2967
-
2968
- static void abc_M_field(const char *p, int *mlen, int *mdiv)
2969
- {
2970
- if( !SDL_strncmp(p,"none",4) ) {
2971
- *mlen = 1;
2972
- *mdiv = 1;
2973
- return;
2974
- }
2975
- if( !SDL_strncmp(p,"C|",2) ) {
2976
- *mlen = 2;
2977
- *mdiv = 2;
2978
- return;
2979
- }
2980
- if( *p == 'C' ) {
2981
- *mlen = 4;
2982
- *mdiv = 4;
2983
- return;
2984
- }
2985
- p += abc_getexpr(p,mlen);
2986
- SDL_sscanf(p," / %d", mdiv);
2987
- }
2988
-
2989
- static int abc_drum_steps(const char *dch)
2990
- {
2991
- const char *p;
2992
- int i=0;
2993
- for( p=dch; *p; p++ ) {
2994
- if( SDL_isdigit(*p) ) i += *p - '0';;
2995
- }
2996
- return i;
2997
- }
2998
-
2999
- static void abc_add_drum(ABCHANDLE *h, uint32_t tracktime, uint32_t bartime)
3000
- {
3001
- ABCEVENT *e;
3002
- ABCTRACK *tp;
3003
- uint32_t etime, ctime , rtime, stime;
3004
- int i, g, steps, gnote, gsteps, nnum;
3005
- steps = abc_drum_steps(h->drum);
3006
- ctime = h->barticks;
3007
- // look up the last event in tpr drumtrack
3008
- tp = abc_locate_track(h, h->tpr->v, DRUMPOS);
3009
- e = tp->tail;
3010
- etime = e? e->tracktick: bartime;
3011
- if( etime > tracktime ) return;
3012
- if( etime < bartime ) rtime = h->barticks - ((bartime - etime) % h->barticks);
3013
- else rtime = (etime - bartime) % h->barticks;
3014
- stime = ctime*steps;
3015
- rtime *= steps;
3016
- rtime += stime;
3017
- gsteps = SDL_strlen(h->drum)/2;
3018
- g = 0;
3019
- while( rtime > stime ) {
3020
- rtime -= ctime*(h->drum[g*2+1] - '0');
3021
- if( ++g == gsteps ) g = 0;
3022
- }
3023
- stime = (tracktime - etime) * steps;
3024
- rtime = 0;
3025
-
3026
- // if no drumsteps, there is nothing we can do anyway.
3027
- if( steps == 0 )
3028
- return;
3029
-
3030
- while( rtime < stime ) {
3031
- gnote = h->drum[g*2];
3032
- i = h->drum[g*2+1] - '0';
3033
- if( gnote=='d') {
3034
- tp->instr = pat_gm_drumnr(h->drumins[g]-1);
3035
- nnum = pat_gm_drumnote(h->drumins[g]);
3036
- abc_add_drumnote(h, tp, etime + rtime/steps, nnum, h->drumvol[g]);
3037
- abc_add_noteoff(h,tp,etime + ( rtime + ctime * i )/steps);
3038
- }
3039
- if( ++g == gsteps ) g = 0;
3040
- rtime += ctime * i;
3041
- }
3042
- }
3043
-
3044
- static int abc_gchord_steps(const char *gch)
3045
- {
3046
- const char *p;
3047
- int i=0;
3048
- for( p=gch; *p; p++ )
3049
- if( SDL_isdigit(*p) ) i += *p - '0';
3050
- return i;
3051
- }
3052
-
3053
- static void abc_add_gchord(ABCHANDLE *h, uint32_t tracktime, uint32_t bartime)
3054
- {
3055
- ABCEVENT *e, *c;
3056
- ABCTRACK *tp;
3057
- uint32_t etime, ctime , rtime, stime;
3058
- int i, g, steps, gnote, gcnum, gsteps, nnum, glen;
3059
- // look up the last chord event in tpc
3060
- c = 0;
3061
- for( e = h->tpc->head; e; e = e->next )
3062
- if( e->flg == 1 && e->cmd == cmdchord )
3063
- c = e;
3064
- if( !c ) return;
3065
- gcnum = c->par[chordnum];
3066
- steps = abc_gchord_steps(h->gchord);
3067
- ctime = h->barticks;
3068
- etime = 0;
3069
- for( i = GCHORDBPOS; i < DRUMPOS; i++ ) {
3070
- tp = abc_locate_track(h, h->tpc->v, i);
3071
- e = tp->tail;
3072
- if( !e ) e = c;
3073
- stime = e->tracktick;
3074
- if( stime > etime ) etime = stime;
3075
- }
3076
- if( etime > tracktime ) return;
3077
- if( etime < bartime ) rtime = h->barticks - ((bartime - etime) % h->barticks);
3078
- else rtime = (etime - bartime) % h->barticks;
3079
- stime = ctime * steps;
3080
- rtime *= steps;
3081
- rtime += stime;
3082
- gsteps = SDL_strlen(h->gchord);
3083
- g = 0;
3084
- while( rtime > stime ) {
3085
- glen = h->gchord[2*g+1] - '0';
3086
- rtime -= ctime * glen;
3087
- if( ++g == gsteps ) g = 0;
3088
- }
3089
- stime = (tracktime - etime) * steps;
3090
- rtime = 0;
3091
- while( rtime < stime ) {
3092
- gnote = h->gchord[2*g];
3093
- glen = h->gchord[2*g+1] - '0';
3094
- if( ++g == gsteps ) g = 0;
3095
- switch(gnote) {
3096
- case 'b':
3097
- tp = abc_locate_track(h, h->tpc->v, GCHORDFPOS);
3098
- tp->instr = h->abcbassprog;
3099
- nnum = c->par[chordnote]+chordnotes[gcnum][0]+24;
3100
- abc_add_chordnote(h, tp, etime + rtime/steps, nnum, h->abcbassvol);
3101
- abc_add_noteoff(h,tp,etime + ( rtime + ctime * glen )/steps);
3102
- case 'c':
3103
- for( i = 1; i < chordlen[gcnum]; i++ ) {
3104
- tp = abc_locate_track(h, h->tpc->v, i+GCHORDFPOS);
3105
- tp->instr = h->abcchordprog;
3106
- nnum = c->par[chordnote]+chordnotes[gcnum][i]+24;
3107
- abc_add_chordnote(h, tp, etime + rtime/steps, nnum, h->abcchordvol);
3108
- abc_add_noteoff(h,tp,etime + ( rtime + ctime * glen )/steps);
3109
- }
3110
- rtime += ctime * glen;
3111
- break;
3112
- case 'f':
3113
- tp = abc_locate_track(h, h->tpc->v, GCHORDFPOS);
3114
- tp->instr = h->abcbassprog;
3115
- nnum = c->par[chordbase]+12;
3116
- abc_add_chordnote(h, tp, etime + rtime/steps, nnum, h->abcbassvol);
3117
- rtime += ctime * glen;
3118
- abc_add_noteoff(h,tp,etime + rtime/steps);
3119
- break;
3120
- case 'g':
3121
- case 'h':
3122
- case 'i':
3123
- case 'j':
3124
- case 'G':
3125
- case 'H':
3126
- case 'I':
3127
- case 'J':
3128
- i = SDL_toupper(gnote) - 'G';
3129
- nnum = 0;
3130
- if( i < chordlen[gcnum] ) {
3131
- tp = abc_locate_track(h, h->tpc->v, GCHORDFPOS+i+1);
3132
- tp->instr = h->abcchordprog;
3133
- nnum = c->par[chordnote]+chordnotes[gcnum][i]+24;
3134
- if( IsUpper(gnote) ) nnum -= 12;
3135
- abc_add_chordnote(h, tp, etime + rtime/steps, nnum, h->abcchordvol);
3136
- }
3137
- rtime += ctime * glen;
3138
- if( nnum ) abc_add_noteoff(h,tp,etime + rtime/steps);
3139
- break;
3140
- case 'z':
3141
- rtime += ctime * glen;
3142
- break;
3143
- }
3144
- }
3145
- }
3146
-
3147
- // %%MIDI beat a b c n
3148
- //
3149
- // controls the way note velocities are selected. The first note in a bar has
3150
- // velocity a. Other "strong" notes have velocity b and all the rest have velocity
3151
- // c. a, b and c must be in the range 0-128. The parameter n determines which
3152
- // notes are "strong". If the time signature is x/y, then each note is given
3153
- // a position number k = 0, 1, 2 .. x-1 within each bar. Note that the units for
3154
- // n are not the unit note length. If k is a multiple of n, then the note is
3155
- // "strong". The volume specifiers !ppp! to !fff! are equivalent to the
3156
- // following :
3157
- //
3158
- // !ppp! = %%MIDI beat 30 20 10 1
3159
- // !pp! = %%MIDI beat 45 35 20 1
3160
- // !p! = %%MIDI beat 60 50 35 1
3161
- // !mp! = %%MIDI beat 75 65 50 1
3162
- // !mf! = %%MIDI beat 90 80 65 1
3163
- // !f! = %%MIDI beat 105 95 80 1
3164
- // !ff! = %%MIDI beat 120 110 95 1
3165
- // !fff! = %%MIDI beat 127 125 110 1
3166
- static void abc_MIDI_beat(ABCHANDLE *h, const char *p)
3167
- {
3168
- int i,j;
3169
- h->beat[0] = 127;
3170
- h->beat[1] = 125;
3171
- h->beat[2] = 110;
3172
- h->beat[3] = 1;
3173
- for( j=0; j<4; j++ ) {
3174
- while( SDL_isspace(*p) ) p++;
3175
- if( *p ) {
3176
- p += abc_getnumber(p, &i);
3177
- if( i < 0 ) i = 0;
3178
- if( i > 127 ) i = 127;
3179
- h->beat[j] = i;
3180
- }
3181
- }
3182
- if( h->beat[3] == 0 ) h->beat[3] = 1; // BB Ruud says: do not let you make mad
3183
- }
3184
-
3185
- //
3186
- // %%MIDI beatstring <string of f, m and p>
3187
- //
3188
- // This provides an alternative way of specifying where the strong and weak
3189
- // stresses fall within a bar. 'f' means velocity a (normally strong), 'm'
3190
- // means velocity b (medium velocity) and 'p' means velocity c (soft velocity).
3191
- // For example, if the time signature is 7/8 with stresses on the first, fourth
3192
- // and sixth notes in the bar, we could use the following
3193
- //
3194
- // %%MIDI beatstring fppmpmp
3195
- static void abc_MIDI_beatstring(ABCHANDLE *h, const char *p)
3196
- {
3197
- while( SDL_isspace(*p) ) p++;
3198
- if( h->beatstring ) _mm_free(h->allochandle, h->beatstring);
3199
- if( SDL_strlen(p) )
3200
- h->beatstring = DupStr(h->allochandle,p,SDL_strlen(p)+1);
3201
- else
3202
- h->beatstring = NULL;
3203
- }
3204
-
3205
- static int abc_beat_vol(ABCHANDLE *h, int abcvol, int barpos)
3206
- {
3207
- int vol;
3208
- if( h->beatstring ) {
3209
- vol = (h->beat[2] * 9) / 10;
3210
- if( barpos < (int)SDL_strlen(h->beatstring) ) {
3211
- switch(h->beatstring[barpos]) {
3212
- case 'f':
3213
- vol = h->beat[0];
3214
- break;
3215
- case 'm':
3216
- vol = h->beat[1];
3217
- break;
3218
- case 'p':
3219
- vol = h->beat[2];
3220
- break;
3221
- default:
3222
- break;
3223
- }
3224
- }
3225
- }
3226
- else {
3227
- if( (barpos % h->beat[3]) == 0 ) {
3228
- if( barpos )
3229
- vol = h->beat[1];
3230
- else
3231
- vol = h->beat[0];
3232
- }
3233
- else
3234
- vol = h->beat[2];
3235
- }
3236
- vol *= abcvol;
3237
- vol /= 128;
3238
- return vol;
3239
- }
3240
-
3241
- static void abc_init_partpat(BYTE partp[27][2])
3242
- {
3243
- int i;
3244
- for( i=0; i<27; i++ ) {
3245
- partp[i][0] = 0xff;
3246
- partp[i][1] = 0;
3247
- }
3248
- }
3249
-
3250
- static int abc_partpat_to_orderlist(BYTE partp[27][2], const char *abcparts, ABCHANDLE *h, BYTE **list, int orderlen)
3251
- {
3252
- int t, partsused;
3253
- const char *p;
3254
- BYTE *orderlist = *list;
3255
- static int ordersize = 0;
3256
- if( *list == NULL ) {
3257
- ordersize = 128;
3258
- orderlist = (BYTE *)_mm_calloc(h->ho, ordersize, sizeof(BYTE));
3259
- *list = orderlist;
3260
- }
3261
- if( abcparts ) {
3262
- partsused = 0;
3263
- for( p = abcparts; *p; p++ ) {
3264
- for( t = partp[*p - 'A'][0]; t < partp[*p - 'A'][1]; t++ ) {
3265
- if( orderlen == ordersize ) {
3266
- ordersize <<= 1;
3267
- if (ordersize == 0) ordersize = 2;
3268
- orderlist = (BYTE *)_mm_recalloc(h->ho, orderlist, ordersize, sizeof(BYTE));
3269
- *list = orderlist;
3270
- }
3271
- orderlist[orderlen] = t;
3272
- orderlen++;
3273
- partsused++;
3274
- }
3275
- }
3276
- if( partsused ) return orderlen;
3277
- }
3278
- // some fool wrote a P: string in the header but didn't use P: in the body
3279
- for( t = partp[26][0]; t < partp[26][1]; t++ ) {
3280
- if( orderlen == ordersize ) {
3281
- ordersize <<= 1;
3282
- if (ordersize == 0) ordersize = 2;
3283
- orderlist = (BYTE *)_mm_recalloc(h->ho, orderlist, ordersize, sizeof(BYTE));
3284
- *list = orderlist;
3285
- }
3286
- orderlist[orderlen] = t;
3287
- orderlen++;
3288
- }
3289
- return orderlen;
3290
- }
3291
-
3292
- static void abc_globalslide(ABCHANDLE *h, uint32_t tracktime, int slide)
3293
- {
3294
- ABCTRACK *tp;
3295
- ABCEVENT *e;
3296
- int hslide;
3297
- hslide = h->track? h->track->slidevol: slide;
3298
- for( tp=h->track; tp; tp = tp->next ) {
3299
- if( slide ) {
3300
- tp->slidevoltime = tracktime;
3301
- if( slide == 2 )
3302
- tp->slidevol = 0;
3303
- }
3304
- if( tp->slidevol > -2 && slide < 2 )
3305
- tp->slidevol = slide;
3306
- }
3307
- if( h->track && h->track->tail
3308
- && hslide != slide && slide == -2
3309
- && h->track->tail->tracktick >= tracktime ) {
3310
- // need to update jumptypes in mastertrack from tracktime on...
3311
- for( e=h->track->head; e; e=e->next ) {
3312
- if( e->flg == 1 && e->cmd == cmdjump && e->tracktick >= tracktime ) {
3313
- switch( e->par[jumptype] ) {
3314
- case jumpnormal:
3315
- case jumpfade:
3316
- e->par[jumptype] = jumpfade;
3317
- break;
3318
- case jumpdacapo:
3319
- case jumpdcfade:
3320
- e->par[jumptype] = jumpdcfade;
3321
- break;
3322
- case jumpdasegno:
3323
- case jumpdsfade:
3324
- e->par[jumptype] = jumpdsfade;
3325
- break;
3326
- }
3327
- }
3328
- }
3329
- }
3330
- }
3331
-
3332
- static void abc_recalculate_tracktime(ABCHANDLE *h) {
3333
- ABCTRACK *ttp;
3334
- h->tracktime = 0;
3335
- for( ttp=h->track; ttp; ttp=ttp->next )
3336
- if( ttp->tail && ttp->tail->tracktick > h->tracktime )
3337
- h->tracktime = ttp->tail->tracktick;
3338
- }
3339
-
3340
- static void abc_MIDI_command(ABCHANDLE *h, char *p, char delim) {
3341
- int t;
3342
- // interpret some of the possibilitys
3343
- if( !SDL_strncmp(p,"bassprog",8) && SDL_isspace(p[8]) ) h->abcbassprog = abc_MIDI_getprog(p+8)+1;
3344
- if( !SDL_strncmp(p,"bassvol",7) && SDL_isspace(p[7]) ) h->abcbassvol = abc_MIDI_getnumber(p+7);
3345
- if( !SDL_strncmp(p,"beat",4) && SDL_isspace(p[4]) ) abc_MIDI_beat(h, p+4);
3346
- if( !SDL_strncmp(p,"beatstring",10) && SDL_isspace(p[10]) ) abc_MIDI_beatstring(h, p+4);
3347
- if( !SDL_strncmp(p,"chordname",9) && SDL_isspace(p[9]) ) abc_MIDI_chordname(p+9);
3348
- if( !SDL_strncmp(p,"chordprog",9) && SDL_isspace(p[9]) ) h->abcchordprog = abc_MIDI_getprog(p+9)+1;
3349
- if( !SDL_strncmp(p,"chordvol",8) && SDL_isspace(p[8]) ) h->abcchordvol = abc_MIDI_getnumber(p+8);
3350
- if( !SDL_strncmp(p,"drone",5) && SDL_isspace(p[5]) ) abc_MIDI_drone(p+5, &h->dronegm, h->dronepitch, h->dronevol);
3351
- if( !SDL_strncmp(p,"droneoff",8) && (p[8]=='\0' || p[8]==delim || SDL_isspace(p[8])) ) h->droneon = 0;
3352
- if( !SDL_strncmp(p,"droneon",7) && (p[7]=='\0' || p[7]==delim || SDL_isspace(p[7])) ) h->droneon = 1;
3353
- t = h->drumon;
3354
- if( !SDL_strncmp(p,"drum",4) && SDL_isspace(p[4]) ) {
3355
- h->drumon = abc_MIDI_drum(p+4, h);
3356
- if( h->drumon ) --h->drumon;
3357
- else h->drumon = t;
3358
- }
3359
- if( !SDL_strncmp(p,"drumoff",7) && (p[7]=='\0' || p[7]==delim || SDL_isspace(p[7])) ) h->drumon = 0;
3360
- if( !SDL_strncmp(p,"drumon",6) && (p[6]=='\0' || p[6]==delim || SDL_isspace(p[6])) ) h->drumon = 1;
3361
- if( t != h->drumon ) {
3362
- if( h->drumon && !h->tpr ) h->tpr = h->track;
3363
- if( h->tpr ) abc_add_drum_sync(h, h->tpr, h->tracktime); // don't start drumming from the beginning of time!
3364
- if( h->tpr && !h->drumon ) h->tpr = NULL;
3365
- }
3366
- t = h->gchordon;
3367
- if( !SDL_strncmp(p,"gchord",6) && (p[6]=='\0' || p[6]==delim || SDL_isspace(p[6])) ) {
3368
- h->gchordon = abc_MIDI_gchord(p+6, h);
3369
- if( h->gchordon ) --h->gchordon;
3370
- else h->gchordon = t;
3371
- }
3372
- if( !SDL_strncmp(p,"gchordoff",9) && (p[9]=='\0' || p[9]==delim || SDL_isspace(p[9])) ) h->gchordon = 0;
3373
- if( !SDL_strncmp(p,"gchordon",8) && (p[8]=='\0' || p[8]==delim || SDL_isspace(p[8])) ) h->gchordon = 1;
3374
- if( t != h->gchordon ) {
3375
- if( h->tpc ) abc_add_gchord_syncs(h, h->tpc, h->tracktime);
3376
- }
3377
- if( !SDL_strncmp(p,"channel",7) && SDL_isspace(p[7]) )
3378
- abc_MIDI_channel(p+8, h->tp = abc_check_track(h, h->tp), h);
3379
- if( !SDL_strncmp(p,"program",7) && SDL_isspace(p[7]) )
3380
- abc_MIDI_program(p+8, h->tp = abc_check_track(h, h->tp), h);
3381
- if( !SDL_strncmp(p,"voice",5) && SDL_isspace(p[5]) )
3382
- abc_MIDI_voice(p+6, h->tp = abc_check_track(h, h->tp), h);
3383
- if( !SDL_strncmp(p,"legato",6) && (p[6]=='\0' || p[6]==delim || SDL_isspace(p[6])) )
3384
- abc_MIDI_legato(p+6, h->tp = abc_check_track(h, h->tp));
3385
- }
3386
-
3387
- // continuate line that ends with a backslash, can't do this in abc_gets because voice lines
3388
- // can have comment lines in between that must be parsed properly, for example:
3389
- // [V:1] cdef gabc' |\ << continuation backslash
3390
- // %%MIDI program 25
3391
- // c'bag fedc |
3392
- // informational lines can have this too, so it is rather convoluted code...
3393
- static char *abc_continuated(ABCHANDLE *h, MMFILE *mmf, char *p) {
3394
- char *pm, *p1, *p2 = 0;
3395
- int continued;
3396
- pm = p;
3397
- while( pm[SDL_strlen(pm)-1]=='\\' ) {
3398
- p1 = SDL_strdup(pm);
3399
- if( p2 ) SDL_free(p2);
3400
- continued = 1;
3401
- while( continued ) {
3402
- continued = 0;
3403
- pm = abc_gets(h, mmf);
3404
- if( !pm ) {
3405
- abc_message("line not properly continued\n%s", p1);
3406
- return p1;
3407
- }
3408
- while( *pm && SDL_isspace(*pm) ) ++pm;
3409
- if( !SDL_strncmp(pm,"%%",2) ) {
3410
- for( p2 = pm+2; *p2 && SDL_isspace(*p2); p2++ ) ;
3411
- if( !SDL_strncmp(p2,"MIDI",4) && (p2[4]=='=' || SDL_isspace(p2[4])) ) {
3412
- for( p2+=5; *p2 && SDL_isspace(*p2); p2++ ) ;
3413
- if( *p2 == '=' )
3414
- for( p2+=1; *p2 && SDL_isspace(*p2); p2++ ) ;
3415
- abc_MIDI_command(h,p2,'%');
3416
- }
3417
- continued = 1;
3418
- }
3419
- }
3420
- const size_t macrolinelen = SDL_strlen(p1)+SDL_strlen(pm)+1;
3421
- p2 = (char *)SDL_malloc(macrolinelen);
3422
- if( !p2 ) {
3423
- abc_message("macro line too long\n%s", p1);
3424
- return p1;
3425
- }
3426
- p1[SDL_strlen(p1)-1] = '\0'; // strip off the backslash
3427
- SDL_strlcpy(p2,p1,macrolinelen);
3428
- SDL_strlcat(p2,pm,macrolinelen);
3429
- pm = p2;
3430
- SDL_free(p1);
3431
- }
3432
- return pm;
3433
- }
3434
-
3435
- // =====================================================================================
3436
- BOOL CSoundFile_ReadABC(CSoundFile *_this, const uint8_t *lpStream, DWORD dwMemLength)
3437
- {
3438
- static int avoid_reentry = 0;
3439
- ABCHANDLE *h;
3440
- uint32_t numpat;
3441
- MMFILE mm, *mmfile;
3442
- uint32_t t;
3443
- char *line, *p, *pp, ch, ch0=0;
3444
- char barsig[52]; // for propagated accidental key signature within bar
3445
- char *abcparts;
3446
- uint8_t partpat[27][2], *orderlist;
3447
- int orderlen;
3448
- enum { NOWHERE, INBETWEEN, INHEAD, INBODY, INSKIPFORX, INSKIPFORQUOTE } abcstate;
3449
- ABCEVENT_JUMPTYPE j;
3450
- ABCEVENT_X_EFFECT abceffect;
3451
- int abceffoper;
3452
- int abcxcount=0, abcxwanted=0, abcxnumber=1;
3453
- int abckey, abcrate, abcchord, abcvol, abcbeatvol, abcnoslurs, abcnolegato, abcfermata, abcarpeggio, abcto;
3454
- int abctempo;
3455
- int cnotelen=0, cnotediv=0, snotelen, snotediv, mnotelen, mnotediv, notelen, notediv;
3456
- // c for chords, s for standard L: setting, m for M: barlength
3457
- int abchornpipe, brokenrithm, tupletp, tupletq, tupletr;
3458
- int ktempo;
3459
- uint32_t abcgrace=0, bartime, thistime=0;
3460
- ABCTRACK *tpd, *ttp;
3461
- ABCMACRO *mp;
3462
- int mmsp;
3463
- MMFILE *mmstack[MAXABCINCLUDES];
3464
- if( !CSoundFile_TestABC(lpStream, dwMemLength) ) return FALSE;
3465
- h = ABC_Init();
3466
- if( !h ) return FALSE;
3467
- mmfile = &mm;
3468
- mm.mm = (char *)lpStream;
3469
- mm.sz = dwMemLength;
3470
- mm.pos = 0;
3471
- while( avoid_reentry ) SDL_Delay(1);
3472
- avoid_reentry = 1;
3473
- pat_resetsmp();
3474
- pat_init_patnames();
3475
- _this->m_nDefaultTempo = 0;
3476
- global_voiceno = 0;
3477
- abckey = 0;
3478
- h->tracktime = 0;
3479
- global_songstart = 0;
3480
- h->speed = 6;
3481
- abcrate = 240;
3482
- global_tempo_factor = 2;
3483
- global_tempo_divider = 1;
3484
- abctempo = 0;
3485
- ktempo = 0;
3486
- abceffect = none;
3487
- abceffoper = 0;
3488
- abcvol = 120;
3489
- h->abcchordvol = abcvol;
3490
- h->abcbassvol = abcvol;
3491
- h->abcchordprog = 25; // acoustic guitar
3492
- h->abcbassprog = 33; // acoustic bass
3493
- abcparts = 0;
3494
- abcnoslurs = 1;
3495
- abcnolegato = 1;
3496
- abcfermata = 0;
3497
- abcarpeggio = 0;
3498
- abcto = 0;
3499
- snotelen = 0;
3500
- snotediv = 0;
3501
- mnotelen = 1;
3502
- mnotediv = 1;
3503
- abchornpipe = 0;
3504
- brokenrithm = 0;
3505
- tupletp = 0;
3506
- tupletq = 0;
3507
- tupletr = 0;
3508
- h->ktrans = 0;
3509
- h->drumon = 0;
3510
- h->gchordon = 1;
3511
- h->droneon = 0;
3512
- h->tracktime = 0;
3513
- bartime = 0;
3514
- h->tp = NULL;
3515
- h->tpc = NULL;
3516
- h->tpr = NULL;
3517
- tpd = NULL;
3518
- h->dronegm = 71;
3519
- h->dronepitch[0] = 45;
3520
- h->dronepitch[1] = 33;
3521
- h->dronevol[0] = 80;
3522
- h->dronevol[1] = 80;
3523
- abc_new_umacro(h, "v = +downbow+");
3524
- abc_new_umacro(h, "u = +upbow+");
3525
- abc_new_umacro(h, "O = +coda+");
3526
- abc_new_umacro(h, "S = +segno+");
3527
- abc_new_umacro(h, "P = +uppermordent+");
3528
- abc_new_umacro(h, "M = +lowermordent+");
3529
- abc_new_umacro(h, "L = +emphasis+");
3530
- abc_new_umacro(h, "H = +fermata+");
3531
- abc_new_umacro(h, "T = +trill+");
3532
- abc_new_umacro(h, "~ = +roll+");
3533
- abc_setup_chordnames();
3534
- abc_init_partpat(partpat);
3535
- abc_MIDI_beat(h, ""); // reset beat array
3536
- abc_MIDI_beatstring(h, ""); // reset beatstring
3537
- orderlist = NULL;
3538
- orderlen = 0;
3539
- mmsp = 1;
3540
- mmstack[0] = mmfile;
3541
- mmfseek(mmfile,0,SEEK_SET);
3542
- abcstate = NOWHERE;
3543
- if( h->pickrandom ) {
3544
- abcstate = INSKIPFORX;
3545
- abcxcount = 0;
3546
- mmfseek(mmfile,0,SEEK_SET);
3547
- while( (line=abc_gets(h, mmfile)) ) {
3548
- for( p=line; SDL_isspace(*p); p++ ) ;
3549
- if( !SDL_strncmp(p,"X:",2) ) abcxcount++;
3550
- }
3551
- if( abcxcount == 0 )
3552
- abcstate = NOWHERE;
3553
- else
3554
- abcxwanted = (h->pickrandom - 1) % abcxcount;
3555
- abcxcount = 0;
3556
- mmfseek(mmfile,0,SEEK_SET);
3557
- }
3558
- while( mmsp > 0 ) {
3559
- mmsp--;
3560
- while((line=abc_gets(h, mmstack[mmsp]))) {
3561
- for( p=line; SDL_isspace(*p); p++ ) ;
3562
- switch(abcstate) {
3563
- case INSKIPFORX:
3564
- if( !SDL_strncmp(p,"X:",2) ) {
3565
- if( abcxcount++ != abcxwanted )
3566
- break;
3567
- }
3568
- // fall through
3569
- case INBETWEEN:
3570
- if( !SDL_strncmp(p,"X:",2) ) {
3571
- abcstate = INHEAD;
3572
- for( p+=2; SDL_isspace(*p); p++ ) ;
3573
- abcxnumber = SDL_atoi(p);
3574
- abchornpipe = 0;
3575
- h->droneon = 0;
3576
- h->dronegm = 71;
3577
- h->dronepitch[0] = 45;
3578
- h->dronepitch[1] = 33;
3579
- h->dronevol[0] = 80;
3580
- h->dronevol[1] = 80;
3581
- for( ttp = h->track; ttp; ttp=ttp->next ) {
3582
- ttp->vno = 0; // mark track unused
3583
- ttp->capostart = NULL;
3584
- }
3585
- h->tp = NULL; // forget old voices
3586
- h->tpc = NULL;
3587
- h->tpr = NULL;
3588
- global_voiceno = 0;
3589
- abc_set_parts(&abcparts, 0);
3590
- abcgrace = 0;
3591
- h->ktrans = 0;
3592
- ktempo = 0;
3593
- h->gchordon = 1;
3594
- h->drumon = 0;
3595
- global_songstart = h->tracktime;
3596
- abc_MIDI_beat(h, ""); // reset beat array
3597
- abc_MIDI_beatstring(h, ""); // reset beatstring
3598
- h->gchord[0] = 0; // reset gchord string
3599
- abcnolegato = 1; // reset legato switch
3600
- }
3601
- break;
3602
- case NOWHERE:
3603
- if( p[0] != '\0' && p[1] == ':' ) {
3604
- abcstate = INHEAD;
3605
- abc_set_parts(&abcparts, 0);
3606
- h->gchord[0] = 0;
3607
- if( h->drumon && h->tpr ) abc_add_drum_sync(h, h->tpr, h->tracktime);
3608
- if( h->tpc && !h->gchordon ) abc_add_gchord_syncs(h, h->tpc, h->tracktime);
3609
- h->gchordon = 1;
3610
- h->drumon = 0;
3611
- }
3612
- else
3613
- break;
3614
- case INHEAD:
3615
- if( !SDL_strncmp(p,"L:",2) ) {
3616
- SDL_sscanf(p+2," %d / %d", &snotelen, &snotediv);
3617
- break;
3618
- }
3619
- if( !SDL_strncmp(p,"M:",2) ) {
3620
- abc_M_field(p+2, &mnotelen, &mnotediv);
3621
- break;
3622
- }
3623
- if( !SDL_strncmp(p,"P:",2) ) {
3624
- abc_set_parts(&abcparts, p+2);
3625
- break;
3626
- }
3627
- if( !SDL_strncmp(p,"Q:",2) ) {
3628
- abctempo = abc_extract_tempo(p+2,0);
3629
- ktempo = 1;
3630
- if( h->track ) {
3631
- // make h->tracktime start of a new age...
3632
- abc_add_partbreak(h, h->track, h->tracktime);
3633
- abc_add_tempo_event(h, h->track, h->tracktime, abctempo);
3634
- }
3635
- if( _this->m_nDefaultTempo == 0 ) _this->m_nDefaultTempo = abctempo;
3636
- break;
3637
- }
3638
- if( !SDL_strncmp(p,"T:",2) ) {
3639
- break;
3640
- }
3641
- if( !SDL_strncmp(p,"R:",2) ) {
3642
- for( p+=2; SDL_isspace(*p); p++ ) ;
3643
- if( !SDL_strncmp(p,"hornpipe",8) && (SDL_isspace(p[8]) || p[8]=='\0') ) abchornpipe = 1;
3644
- else abchornpipe = 0;
3645
- break;
3646
- }
3647
- if( !SDL_strncmp(p,"V:",2) ) {
3648
- for( t=2; p[t]==' '; t++ ) ;
3649
- h->tp = abc_locate_track(h, p+t, 0);
3650
- abcvol = h->tp->volume;
3651
- abcnolegato = !h->tp->legato;
3652
- if( !abcnolegato ) abcnoslurs = 0;
3653
- break;
3654
- }
3655
- if( !SDL_strncmp(p,"K:",2) ) {
3656
- abcstate = INBODY;
3657
- abckey = ABC_Key(p+2);
3658
- SDL_snprintf(barsig, sizeof (barsig), "%s%s", sig[abckey], sig[abckey]); // reset the key signature
3659
- p = abc_skip_word(p+2);
3660
- h->ktrans = abc_transpose(p);
3661
- *p = '%'; // force skip rest of line
3662
- if( snotelen == 0 ) { // calculate default notelen from meter M:
3663
- if( mnotediv == 0 ) mnotediv = mnotelen = 1; // do'nt get nuked
3664
- snotelen = 100 * mnotelen / mnotediv;
3665
- if( snotelen > 74 )
3666
- snotediv = 8;
3667
- else
3668
- snotediv = 16;
3669
- snotelen = 1;
3670
- }
3671
- abceffect = none;
3672
- abceffoper = 0;
3673
- if( !(snotelen == 1 && snotediv == 8) ) abchornpipe = 0; // no matter what they said at R:
3674
- brokenrithm = 0;
3675
- global_part = ' ';
3676
- abcgrace = 0;
3677
- abcnoslurs = abcnolegato;
3678
- abcto = 0;
3679
- h->tpc = NULL; // reset chord track
3680
- tpd = NULL; // reset drone track
3681
- h->tpr = NULL; // reset drum track
3682
- if( !SDL_strlen(h->gchord) ) abc_metric_gchord(h, mnotelen, mnotediv);
3683
- h->barticks = notelen_notediv_to_ticks(h->speed, mnotelen, mnotediv);
3684
- if( abctempo && !ktempo ) { // did not set tempo in this songpiece so reset to abcrate
3685
- abctempo = 0;
3686
- global_tempo_factor = 2;
3687
- global_tempo_divider = 1;
3688
- if( h->track ) {
3689
- // make h->tracktime start of a new age...
3690
- abc_add_partbreak(h, h->track, h->tracktime);
3691
- abc_add_tempo_event(h, h->track, h->tracktime, abcrate);
3692
- }
3693
- if( _this->m_nDefaultTempo == 0 ) _this->m_nDefaultTempo = abcrate;
3694
- }
3695
- abc_init_partpat(partpat);
3696
- partpat[26][0] = abc_patno(h, h->tracktime);
3697
- partpat[26][1] = 0;
3698
- abc_globalslide(h, h->tracktime, 2); // reset all volumeslides
3699
- break;
3700
- }
3701
- if( !SDL_strlen(p) )
3702
- abcstate = INBETWEEN;
3703
- break;
3704
- case INSKIPFORQUOTE:
3705
- while( *p && *p != '"' )
3706
- p++;
3707
- if( *p == '\0' )
3708
- break;
3709
- abcstate = INBODY;
3710
- // fall through
3711
- case INBODY:
3712
- if( !SDL_strlen(p) && h->track ) { // end of this song
3713
- abcstate = h->pickrandom? INSKIPFORX: INBETWEEN;
3714
- // last but not least shut off all pending events
3715
- abc_recalculate_tracktime(h);
3716
- for( ttp=h->track; ttp; ttp=ttp->next )
3717
- abc_add_noteoff(h,ttp,h->tracktime);
3718
- abc_add_partbreak(h, h->track, h->tracktime);
3719
- t = abc_patno(h, h->tracktime);
3720
- if( abc_pattracktime(h, h->tracktime) % abcticks(64 * h->speed) ) t++;
3721
- if( global_part == ' ' ) {
3722
- partpat[26][1] = t;
3723
- if( abcparts ) {
3724
- for( t=0; t<26; t++ )
3725
- if( partpat[t][0] < partpat[t][1] ) break;
3726
- if( t == 26 ) {
3727
- abc_message("parts (%s) set but not used", abcparts);
3728
- abc_set_parts(&abcparts, 0); // forget the parts array
3729
- }
3730
- }
3731
- }
3732
- else
3733
- partpat[global_part - 'A'][1] = t;
3734
- if( !abcparts ) abc_song_to_parts(h, &abcparts, partpat);
3735
- orderlen = abc_partpat_to_orderlist(partpat, abcparts, h, &orderlist, orderlen);
3736
- }
3737
- if( !SDL_strncmp(p,"V:",2) ) {
3738
- for( t=2; p[t]==' '; t++ ) ;
3739
- h->tp = abc_locate_track(h, p+t, 0);
3740
- SDL_snprintf(barsig, sizeof (barsig), "%s%s", sig[abckey], sig[abckey]); // reset the key signature
3741
- abcgrace = 0;
3742
- brokenrithm = 0;
3743
- h->tracktime = abc_tracktime(h->tp);
3744
- bartime = h->tracktime; // it is not friendly to break voices in the middle of a track...
3745
- abcnolegato = !h->tp->legato;
3746
- if( !abcnolegato ) abcnoslurs = 0;
3747
- *p = '%'; // make me skip the rest of the line....
3748
- }
3749
- if( !SDL_strncmp(p,"K:",2) ) {
3750
- abckey = ABC_Key(p+2);
3751
- SDL_snprintf(barsig, sizeof (barsig), "%s%s", sig[abckey], sig[abckey]); // reset the key signature
3752
- p = abc_skip_word(p+2);
3753
- h->ktrans = abc_transpose(p);
3754
- *p = '%'; // make me skip the rest of the line....
3755
- }
3756
- if( !SDL_strncmp(p,"L:",2) ) {
3757
- SDL_sscanf(p+2," %d / %d", &snotelen, &snotediv);
3758
- *p = '%'; // make me skip the rest of the line....
3759
- }
3760
- if( !SDL_strncmp(p,"M:",2) ) {
3761
- abc_M_field(p+2, &mnotelen, &mnotediv);
3762
- h->barticks = notelen_notediv_to_ticks(h->speed, mnotelen, mnotediv);
3763
- *p = '%'; // make me skip the rest of the line....
3764
- }
3765
- if( !SDL_strncmp(p,"Q:",2) ) {
3766
- abctempo = abc_extract_tempo(p+2,ch0=='\\');
3767
- if( !h->track ) {
3768
- h->tp = abc_check_track(h, h->track);
3769
- h->tp->vno = 0; // mark reuseable (temporarely, until first notes come up)
3770
- }
3771
- abc_add_tempo_event(h, h->track, h->tracktime, abctempo);
3772
- *p = '%'; // make me skip the rest of the line....
3773
- }
3774
- if( !SDL_strncmp(p,"T:",2) ) {
3775
- *p = '%'; // make me skip the rest of the line....
3776
- }
3777
- break;
3778
- }
3779
- if( !SDL_strncmp(p,"m:",2) ) {
3780
- if( abcstate != INSKIPFORX ) {
3781
- char *pm;
3782
- pm = abc_continuated(h, mmstack[mmsp], p);
3783
- abc_new_macro(h, pm+2);
3784
- if( pm != p ) {
3785
- SDL_free(pm);
3786
- if( h->tp ) abcnolegato = !h->tp->legato;
3787
- if( !abcnolegato ) abcnoslurs = 0;
3788
- }
3789
- }
3790
- *p = '%'; // skip rest of line
3791
- }
3792
- if( !SDL_strncmp(p,"U:",2) ) {
3793
- abc_new_umacro(h, p+2);
3794
- *p = '%'; // skip rest of line
3795
- }
3796
- if( !SDL_strncmp(p,"w:",2) ) { // inline lyrics
3797
- *p = '%'; // skip rest of line
3798
- }
3799
- if( !SDL_strncmp(p,"W:",2) ) { // lyrics at end of song body
3800
- *p = '%'; // skip rest of line
3801
- }
3802
- if( !SDL_strncmp(p,"d:",2) ) { // oldstyle decorations
3803
- abc_message("warning: old style decorations not handled\n%s", p);
3804
- *p = '%'; // skip rest of line
3805
- }
3806
- if( !SDL_strncmp(p,"s:",2) ) { // newstyle decorations (symbols)
3807
- abc_message("warning: new style decorations not handled\n%s", p);
3808
- *p = '%'; // skip rest of line
3809
- }
3810
- if( !SDL_strncmp(p,"I:",2) && abcstate != INSKIPFORX ) { // handle like oldstyle '%%command' lines
3811
- p[0]= '%';
3812
- p[1]= '%';
3813
- }
3814
- if( !SDL_strncmp(p,"%%",2) ) {
3815
- for( p+=2; *p && SDL_isspace(*p); p++ ) ;
3816
- if( !SDL_strncmp(p,"abc-include",11) && SDL_isspace(p[11]) ) {
3817
- for( t=12; SDL_isspace(p[t]); t++ ) ;
3818
- if( p[t] ) {
3819
- #if 1 // we don't want people opening arbitrary files.
3820
- abc_message("failure: abc-include unsupported, %s", &p[t]);
3821
- #else
3822
- mmsp++;
3823
- if( mmsp == MAXABCINCLUDES ) {
3824
- mmsp--;
3825
- abc_message("failure: too many abc-include's, %s", &p[t]);
3826
- } else {
3827
- mmstack[mmsp] = mmfopen(&p[t], "r");
3828
- if( !mmstack[mmsp] ) {
3829
- mmsp--;
3830
- abc_message("failure: abc-include file %s not found", &p[t]);
3831
- }
3832
- }
3833
- #endif
3834
- }
3835
- else abc_message("failure: abc-include missing file name, %s", p);
3836
- }
3837
- if( !SDL_strncmp(p,"MIDI",4) && (p[4]=='=' || SDL_isspace(p[4])) && abcstate != INSKIPFORX ) {
3838
- for( p+=5; *p && SDL_isspace(*p); p++ ) ;
3839
- if( *p == '=' )
3840
- for( p+=1; *p && SDL_isspace(*p); p++ ) ;
3841
- abc_MIDI_command(h,p,'%');
3842
- if( h->tp ) abcnolegato = !h->tp->legato;
3843
- if( !abcnolegato ) abcnoslurs = 0;
3844
- }
3845
- if(*p) *p = '%'; // skip rest of line
3846
- }
3847
- if( abcstate == INBODY ) {
3848
- if( *p == 'P' && p[1] == ':' ) { // a line with a part indication
3849
- if( abcparts != NULL ) {
3850
- // make h->tracktime start of a new age...
3851
- if( !h->track ) {
3852
- h->tp = abc_check_track(h, h->track);
3853
- h->tp->vno = 0; // mark reuseable (temporarely, until first notes come up)
3854
- }
3855
- h->tracktime = h->track? abc_tracktime(h->track): 0; // global parts are voice independent
3856
- abc_add_partbreak(h, h->track, h->tracktime);
3857
- t = abc_patno(h, h->tracktime);
3858
- if( global_part == ' ' ) {
3859
- partpat[26][1] = t;
3860
- if( abcparts ) {
3861
- for( t=0; t<26; t++ )
3862
- if( partpat[t][0] < partpat[t][1] ) break;
3863
- if( t == 26 ) {
3864
- abc_message("parts (%s) set but not used", abcparts);
3865
- abc_set_parts(&abcparts, 0); // forget the parts array
3866
- }
3867
- }
3868
- }
3869
- else
3870
- partpat[global_part - 'A'][1] = t;
3871
- // give every new coming abcevent the desired part indication
3872
- while( p[2]==' ' || p[2]=='.' ) p++; // skip blancs and dots
3873
- if( IsUpper(p[2]) )
3874
- global_part = p[2];
3875
- else
3876
- global_part = ' ';
3877
- if( global_part == ' ' )
3878
- partpat[26][0] = t;
3879
- else
3880
- partpat[global_part - 'A'][0] = t;
3881
- }
3882
- *p = '%'; // make me skip the rest of the line....
3883
- }
3884
- if( h->droneon && !tpd ) {
3885
- tpd = h->track;
3886
- if( tpd ) {
3887
- tpd = abc_locate_track(h, tpd->v, DRONEPOS1);
3888
- tpd->instr = h->dronegm;
3889
- abc_add_dronenote(h, tpd, h->tracktime, h->dronepitch[0], h->dronevol[0]);
3890
- tpd = abc_locate_track(h, tpd->v, DRONEPOS2);
3891
- tpd->instr = h->dronegm;
3892
- abc_add_dronenote(h, tpd, h->tracktime, h->dronepitch[1], h->dronevol[1]);
3893
- }
3894
- }
3895
- if( tpd && !h->droneon ) {
3896
- tpd = abc_locate_track(h, tpd->v, DRONEPOS1);
3897
- abc_add_noteoff(h, tpd, h->tracktime);
3898
- tpd = abc_locate_track(h, tpd->v, DRONEPOS2);
3899
- abc_add_noteoff(h, tpd, h->tracktime);
3900
- tpd = NULL;
3901
- }
3902
- if( h->drumon && !h->tpr ) {
3903
- h->tpr = h->track;
3904
- if( h->tpr ) abc_add_drum_sync(h, h->tpr, h->tracktime); // don't start drumming from the beginning of time!
3905
- }
3906
- if( h->tpr && !h->drumon ) h->tpr = NULL;
3907
- if( *p && *p != '%' ) { // skip uninteresting lines
3908
- // plough thru the songline gathering mos....
3909
- ch0 = ' ';
3910
- pp = 0;
3911
- while( (ch = *p++) ) {
3912
- if( !pp && IsAlpha(ch) && *p != ':' ) { // maybe a macro
3913
- for( mp=h->umacro; mp; mp=mp->next ) {
3914
- if( ch == mp->name[0] ) {
3915
- pp = p;
3916
- p = mp->subst;
3917
- ch = *p;
3918
- if( ch ) p++;
3919
- break;
3920
- }
3921
- }
3922
- }
3923
- switch(ch) {
3924
- case '%':
3925
- abcto = 0;
3926
- while( *p ) p++;
3927
- break;
3928
- case '[': // chord follows or some inline field
3929
- abcto = 0;
3930
- if( *p=='|' ) break; // [| a thick-thin bar line, loop around and let case '|' handle it
3931
- if( !SDL_strncmp(p,"V:",2) ) { // inline voice change
3932
- for( t=2; SDL_isspace(p[t]); t++ ) ;
3933
- h->tp = abc_locate_track(h, p+t, 0);
3934
- for( ; *p && *p != ']'; p++ ) ;
3935
- abcgrace = 0;
3936
- brokenrithm = 0;
3937
- SDL_snprintf(barsig, sizeof (barsig), "%s%s", sig[abckey], sig[abckey]); // reset the key signature
3938
- h->tracktime = abc_tracktime(h->tp);
3939
- bartime = h->tracktime; // it is not wise to break voices in the middle of a track...
3940
- abcvol = h->tp->volume;
3941
- abcnolegato = !h->tp->legato;
3942
- if( !abcnolegato ) abcnoslurs = 0;
3943
- break;
3944
- }
3945
- if( !SDL_strncmp(p,"K:",2) ) {
3946
- abckey = ABC_Key(p+2);
3947
- SDL_snprintf(barsig, sizeof (barsig), "%s%s", sig[abckey], sig[abckey]); // reset the key signature
3948
- p = abc_skip_word(p+2);
3949
- h->ktrans = abc_transpose(p);
3950
- for( ; *p && *p != ']'; p++ ) ;
3951
- break;
3952
- }
3953
- if( !SDL_strncmp(p,"M:",2) ) {
3954
- abc_M_field(p+2, &mnotelen, &mnotediv);
3955
- for( ; *p && *p != ']'; p++ ) ;
3956
- h->barticks = notelen_notediv_to_ticks(h->speed, mnotelen, mnotediv);
3957
- break;
3958
- }
3959
- if( !SDL_strncmp(p,"P:",2) ) { // a [P:X] field inline
3960
- if( abcparts != NULL ) {
3961
- // make h->tracktime start of a new age...
3962
- if( h->track )
3963
- abc_add_partbreak(h, h->track, h->tracktime);
3964
- t = abc_patno(h, h->tracktime);
3965
- if( global_part == ' ' )
3966
- partpat[26][1] = t;
3967
- else
3968
- partpat[global_part - 'A'][1] = t;
3969
- // give every new coming abcevent the desired part indication
3970
- while( SDL_isspace(p[2]) || p[2]=='.' ) p++; // skip blancs and dots
3971
- if( IsUpper(p[2]) )
3972
- global_part = p[2];
3973
- else
3974
- global_part = ' ';
3975
- if( global_part == ' ' )
3976
- partpat[26][0] = t;
3977
- else
3978
- partpat[global_part - 'A'][0] = t;
3979
- }
3980
- for( ; *p && *p != ']'; p++ ) ;
3981
- break;
3982
- }
3983
- if( !SDL_strncmp(p,"Q:",2) ) {
3984
- abctempo = abc_extract_tempo(p+2,1);
3985
- for( ; *p && *p != ']'; p++ ) ;
3986
- if( h->track )
3987
- abc_add_tempo_event(h, h->track, h->tracktime, abctempo);
3988
- break;
3989
- }
3990
- if( !SDL_strncmp(p,"I:",2) ) { // interpret some of the possibilitys
3991
- for( p += 2; SDL_isspace(*p); p++ ) ;
3992
- if( !SDL_strncmp(p,"MIDI",4) && (p[4]=='=' || SDL_isspace(p[4])) ) { // interpret some of the possibilitys
3993
- for( p += 4; SDL_isspace(*p); p++ ) ;
3994
- if( *p == '=' )
3995
- for( p += 1; SDL_isspace(*p); p++ ) ;
3996
- abc_MIDI_command(h, p, ']');
3997
- if( h->tp ) abcnolegato = !h->tp->legato;
3998
- if( !abcnolegato ) abcnoslurs = 0;
3999
- }
4000
- for( ; *p && *p != ']'; p++ ) ; // skip rest of inline field
4001
- }
4002
- if( *p && p[1] == ':' ) { // some other kind of inline field
4003
- for( ; *p && *p != ']'; p++ ) ;
4004
- break;
4005
- }
4006
- if( *p && SDL_strchr("abcdefgABCDEFG^_=",*p) ) {
4007
- int cnl[8],cnd[8],vnl,nl0=0,nd0=0; // for chords with notes of varying length
4008
- abcchord = 0;
4009
- vnl = 0;
4010
- h->tp = abc_check_track(h, h->tp);
4011
- abc_track_clear_tiedvpos(h);
4012
- abcbeatvol = abc_beat_vol(h, abcvol, (h->tracktime - bartime)/notelen_notediv_to_ticks(h->speed,1,mnotediv));
4013
- while( (ch=*p++) && (ch != ']') ) {
4014
- h->tp = abc_locate_track(h, h->tp->v, abcchord? abcchord+DRONEPOS2: 0);
4015
- p += abc_add_noteon(h, ch, p, h->tracktime, barsig, abcbeatvol, abceffect, abceffoper);
4016
- p += abc_notelen(p, &notelen, &notediv);
4017
- if( *p == '-' ) {
4018
- p++;
4019
- if( h->tp->tail && h->tp->tail->flg != 1 )
4020
- h->tp->tienote = h->tp->tail;
4021
- }
4022
- if( abcchord<8 ) {
4023
- cnl[abcchord] = notelen;
4024
- cnd[abcchord] = notediv;
4025
- }
4026
- if( abcchord==0 ) {
4027
- cnotelen = notelen;
4028
- cnotediv = notediv;
4029
- nl0 = notelen;
4030
- nd0 = notediv;
4031
- }
4032
- else {
4033
- if( cnotelen != notelen || cnotediv != notediv ) {
4034
- vnl = 1;
4035
- // update to longest duration
4036
- if( cnotelen * notediv < notelen * cnotediv ) {
4037
- cnotelen = notelen;
4038
- cnotediv = notediv;
4039
- abc_track_untie_short_chordnotes(h);
4040
- }
4041
- if( cnotelen * notediv > notelen * cnotediv ) {
4042
- if( h->tp->tienote ) {
4043
- abc_message("short notes in chord can not be tied:\n%s", h->line);
4044
- h->tp->tienote = 0; // short chord notes cannot be tied...
4045
- }
4046
- }
4047
- // update to shortest duration
4048
- if( nl0 * notediv > notelen * nd0 ) {
4049
- nl0 = notelen;
4050
- nd0 = notediv;
4051
- }
4052
- }
4053
- }
4054
- abcchord++;
4055
- }
4056
- p += abc_notelen(p, &notelen, &notediv);
4057
- if( (ch = *p) == '-' ) p++; // tied chord...
4058
- if( abcarpeggio ) { // update starttime in the noteon events...
4059
- thistime = notelen_notediv_to_ticks(h->speed, nl0*notelen*snotelen, nd0*notediv*snotediv)/abcchord;
4060
- if( thistime > abcticks(h->speed) ) thistime = abcticks(h->speed);
4061
- for( nl0=1; nl0<abcchord; nl0++ ) {
4062
- h->tp = abc_locate_track(h, h->tp->v, nl0+DRONEPOS2);
4063
- if( h->tp->tail )
4064
- h->tp->tail->tracktick = h->tracktime + thistime * nl0;
4065
- }
4066
- }
4067
- notelen *= cnotelen;
4068
- notediv *= cnotediv;
4069
- tupletr = abc_tuplet(&notelen, &notediv, tupletp, tupletq, tupletr);
4070
- while( SDL_isspace(*p) ) p++; // allow spacing in broken rithm notation
4071
- p += abc_brokenrithm(p, &notelen, &notediv, &brokenrithm, abchornpipe);
4072
- thistime = notelen_notediv_to_ticks(h->speed, notelen*snotelen, notediv*snotediv);
4073
- if( abcfermata ) {
4074
- thistime <<= 1;
4075
- abcfermata = 0;
4076
- }
4077
- if( thistime > abcgrace ) {
4078
- thistime -= abcgrace;
4079
- abcgrace = 0;
4080
- }
4081
- else {
4082
- abcgrace -= thistime;
4083
- thistime = abcticks(h->speed);
4084
- abcgrace += abcticks(h->speed);
4085
- }
4086
- h->tracktime += thistime;
4087
- while( abcchord>0 ) {
4088
- abcchord--;
4089
- h->tp = abc_locate_track(h, h->tp->v, abcchord? abcchord+DRONEPOS2: 0);
4090
- if( vnl && (abcchord < 8) && (cnl[abcchord] != cnotelen || cnd[abcchord] != cnotediv) ) {
4091
- abc_add_noteoff(h, h->tp,
4092
- h->tracktime - thistime
4093
- + (thistime * cnl[abcchord] * cnotediv)/(cnd[abcchord] * cnotelen) );
4094
- }
4095
- else {
4096
- if( ch=='-' && h->tp->tail && h->tp->tail->flg != 1 )
4097
- h->tp->tienote = h->tp->tail; // copy noteon event to tienote in track
4098
- if( thistime > abcticks(h->speed) )
4099
- abc_add_noteoff(h, h->tp, h->tracktime - abcnoslurs);
4100
- else
4101
- abc_add_noteoff(h, h->tp, h->tracktime);
4102
- }
4103
- }
4104
- if( h->gchordon && (h->tp == h->tpc) )
4105
- abc_add_gchord(h, h->tracktime, bartime);
4106
- if( h->drumon && (h->tp == h->tpr) )
4107
- abc_add_drum(h, h->tracktime, bartime);
4108
- abcarpeggio = 0;
4109
- if( abceffoper != 255 ) abceffect = none;
4110
- break;
4111
- }
4112
- if( SDL_isdigit(*p) ) { // different endings in repeats [i,j,n-r,s,...
4113
- h->tp = abc_check_track(h, h->tp);
4114
- abc_add_partbreak(h, h->tp, h->tracktime);
4115
- p += abc_getnumber(p, &notelen);
4116
- abc_add_variant_start(h, h->tp, h->tracktime, notelen);
4117
- while( *p==',' || *p=='-' ) {
4118
- if( *p==',' ) {
4119
- p++;
4120
- p += abc_getnumber(p, &notelen);
4121
- abc_add_variant_choise(h->tp, notelen);
4122
- }
4123
- else {
4124
- p++;
4125
- p += abc_getnumber(p, &notediv);
4126
- while( notelen < notediv ) {
4127
- notelen++;
4128
- abc_add_variant_choise(h->tp, notelen);
4129
- }
4130
- }
4131
- }
4132
- break;
4133
- }
4134
- // collect the notes in the chord
4135
- break;
4136
- case '(': // slurs follow or some tuplet (duplet, triplet etc.)
4137
- abcto = 0;
4138
- if( SDL_isdigit(*p) ) {
4139
- p += abc_getnumber(p,&tupletp);
4140
- tupletr = tupletp; // ABC draft 2.0 (4.13): if r is not given it defaults to p
4141
- switch( tupletp ) { // ABC draft 2.0 (4.13): q defaults depending on p and time signature
4142
- case 2: case 4: case 8:
4143
- tupletq = 3;
4144
- break;
4145
- case 3: case 6:
4146
- tupletq = 2;
4147
- break;
4148
- default:
4149
- if( snotediv == 8 )
4150
- tupletq = 3;
4151
- else
4152
- tupletq = 2;
4153
- break;
4154
- }
4155
- if( *p==':' ) {
4156
- p++;
4157
- if( SDL_isdigit(*p) ) p += abc_getnumber(p,&tupletq);
4158
- if( *p==':' ) {
4159
- p++;
4160
- if( SDL_isdigit(*p) ) p += abc_getnumber(p,&tupletr);
4161
- }
4162
- }
4163
- }
4164
- else
4165
- abcnoslurs=0;
4166
- break;
4167
- case ')': // end of slurs
4168
- abcto = 0;
4169
- abcnoslurs = abcnolegato;
4170
- break;
4171
- case '{': // grace notes follow
4172
- abcto = 0;
4173
- h->tp = abc_check_track(h, h->tp);
4174
- abc_track_clear_tiedvpos(h);
4175
- abcgrace = 0;
4176
- abcbeatvol = abc_beat_vol(h, abcvol, (h->tracktime - bartime)/notelen_notediv_to_ticks(h->speed,1,mnotediv));
4177
- while( (ch=*p++) && (ch != '}') ) {
4178
- p += abc_add_noteon(h, ch, p, h->tracktime+abcgrace, barsig, abcbeatvol, none, 0);
4179
- p += abc_notelen(p, &notelen, &notediv);
4180
- if( *p=='-' ) {
4181
- p++;
4182
- if( h->tp->tail->flg != 1 )
4183
- h->tp->tienote = h->tp->tail;
4184
- }
4185
- notediv *= 4; // grace notes factor 4 shorter (1/8 => 1/32)
4186
- abcgrace += notelen_notediv_to_ticks(h->speed, notelen*snotelen, notediv*snotediv);
4187
- abc_add_noteoff(h, h->tp, h->tracktime + abcgrace);
4188
- }
4189
- h->tracktime += abcgrace;
4190
- abc_add_sync(h, h->tp, h->tracktime);
4191
- if( h->gchordon && (h->tp == h->tpc) )
4192
- abc_add_gchord(h, h->tracktime, bartime);
4193
- if( h->drumon && (h->tp == h->tpr) )
4194
- abc_add_drum(h, h->tracktime, bartime);
4195
- break;
4196
- case '|': // bar symbols
4197
- abcto = 0;
4198
- if( h->gchordon && h->tp && (h->tp == h->tpc) )
4199
- abc_add_gchord(h, h->tracktime, bartime);
4200
- if( h->drumon && (h->tp == h->tpr) )
4201
- abc_add_drum(h, h->tracktime, bartime);
4202
- SDL_snprintf(barsig, sizeof (barsig), "%s%s", sig[abckey], sig[abckey]); // reset the key signature
4203
- bartime = h->tracktime;
4204
- if( h->tp && h->tp->vpos ) h->tp = abc_locate_track(h, h->tp->v, 0); // reset from voice overlay
4205
- if( SDL_isdigit(*p) ) { // different endings in repeats |i,j,n-r,s,...
4206
- h->tp = abc_check_track(h, h->tp);
4207
- abc_add_partbreak(h, h->tp, h->tracktime);
4208
- p += abc_getnumber(p, &notelen);
4209
- abc_add_variant_start(h, h->tp, h->tracktime, notelen);
4210
- while( *p==',' || *p=='-' ) {
4211
- if( *p==',' ) {
4212
- p++;
4213
- p += abc_getnumber(p, &notelen);
4214
- abc_add_variant_choise(h->tp, notelen);
4215
- }
4216
- else {
4217
- p++;
4218
- p += abc_getnumber(p, &notediv);
4219
- while( notelen < notediv ) {
4220
- notelen++;
4221
- abc_add_variant_choise(h->tp, notelen);
4222
- }
4223
- }
4224
- }
4225
- break;
4226
- }
4227
- if( *p==':' ) { // repeat start
4228
- p++;
4229
- h->tp = abc_check_track(h, h->tp);
4230
- abc_add_partbreak(h, h->tp, h->tracktime);
4231
- abc_add_setloop(h, h->tp, h->tracktime);
4232
- }
4233
- break;
4234
- case '&': // voice overlay
4235
- abcto = 0;
4236
- h->tracktime = bartime;
4237
- h->tp = abc_check_track(h, h->tp);
4238
- t = h->tp->vpos;
4239
- h->tp = abc_locate_track(h, h->tp->v, t? t+1: DRONEPOS2+1);
4240
- break;
4241
- case ']': // staff break, end of song
4242
- abcto = 0;
4243
- break;
4244
- case ':': // repeat jump
4245
- abcto = 0;
4246
- h->tp = abc_check_track(h, h->tp);
4247
- j = (h->tp->slidevol == -2)? jumpfade: jumpnormal;
4248
- abc_add_setjumploop(h, h->tp, h->tracktime, j);
4249
- abc_add_partbreak(h, h->tp, h->tracktime);
4250
- if( *p==':' ) { // repeat start without intermediate bar symbol
4251
- p++;
4252
- abc_add_setloop(h, h->tp, h->tracktime);
4253
- }
4254
- break;
4255
- case '"': // chord notation
4256
- if( !SDL_strchr("_^<>@", *p) && !SDL_isdigit(*p) ) { // if it's not a annotation string
4257
- h->tp = abc_check_track(h, h->tp);
4258
- if( !h->tpc ) h->tpc = abc_locate_track(h, h->tp->v, 0);
4259
- if( h->tp == h->tpc ) abc_add_chord(p, h, h->tpc, h->tracktime); // only do chords for one voice
4260
- }
4261
- abcto = 0;
4262
- while( (ch=*p++) && (ch != '"') ) {
4263
- if( !SDL_strncasecmp(p,"fade",4) && h->track && h->track->slidevol > -2 )
4264
- abc_globalslide(h, h->tracktime, -2); // set volumeslide to fade away...
4265
- if( !SDL_strncasecmp(p,"to coda",7) ) {
4266
- h->tp = abc_check_track(h, h->tp);
4267
- abc_add_partbreak(h, h->tp, h->tracktime);
4268
- abc_add_tocoda(h, h->tp, h->tracktime);
4269
- p+=7;
4270
- abcto = -1;
4271
- }
4272
- else
4273
- if( !SDL_isspace(*p) ) abcto = 0;
4274
- if( !SDL_strncasecmp(p,"to",2) && (SDL_isspace(p[2]) || p[2] == '"') ) abcto = 1;
4275
- }
4276
- if( !ch ) abcstate = INSKIPFORQUOTE;
4277
- break;
4278
- case '\\': // skip the rest of this line, should be the end of the line anyway
4279
- while( *p ) p++;
4280
- ch = '\\'; // remember for invoice tempo changes....
4281
- break;
4282
- case '!': // line break, or deprecated old style decoration
4283
- case '+': // decorations new style
4284
- if( !SDL_strncmp(p,"coda",4) && p[4] == ch ) {
4285
- h->tp = abc_check_track(h, h->tp);
4286
- if( abcto ) {
4287
- if( abcto > 0 ) {
4288
- abc_add_partbreak(h, h->tp, h->tracktime);
4289
- abc_add_tocoda(h, h->tp, h->tracktime);
4290
- }
4291
- }
4292
- else {
4293
- abc_add_partbreak(h, h->tp, h->tracktime);
4294
- abc_add_coda(h, h->tp, h->tracktime);
4295
- }
4296
- p += 5;
4297
- abcto = 0;
4298
- break;
4299
- }
4300
- abcto = 0;
4301
- if( !SDL_strncmp(p,"arpeggio",8) && p[8] == ch ) {
4302
- abcarpeggio = 1;
4303
- p += 9;
4304
- break;
4305
- }
4306
- if( !SDL_strncmp(p,"crescendo(",10) && p[10] == ch ) {
4307
- h->tp = abc_check_track(h, h->tp);
4308
- abc_globalslide(h, h->tracktime, 1);
4309
- p += 11;
4310
- break;
4311
- }
4312
- if( !SDL_strncmp(p,"crescendo)",10) && p[10] == ch ) {
4313
- h->tp = abc_check_track(h, h->tp);
4314
- abc_globalslide(h, h->tracktime, 0);
4315
- p += 11;
4316
- break;
4317
- }
4318
- if( !SDL_strncmp(p,"<(",2) && p[2] == ch ) {
4319
- h->tp = abc_check_track(h, h->tp);
4320
- abc_globalslide(h, h->tracktime, 1);
4321
- p += 3;
4322
- break;
4323
- }
4324
- if( !SDL_strncmp(p,"<)",2) && p[2] == ch ) {
4325
- h->tp = abc_check_track(h, h->tp);
4326
- abc_globalslide(h, h->tracktime, 0);
4327
- p += 3;
4328
- break;
4329
- }
4330
- if( !SDL_strncmp(p,"dimimuendo(",11) && p[11] == ch ) {
4331
- h->tp = abc_check_track(h, h->tp);
4332
- abc_globalslide(h, h->tracktime, -1);
4333
- p += 12;
4334
- break;
4335
- }
4336
- if( !SDL_strncmp(p,"diminuendo)",11) && p[11] == ch ) {
4337
- h->tp = abc_check_track(h, h->tp);
4338
- abc_globalslide(h, h->tracktime, 0);
4339
- p += 12;
4340
- break;
4341
- }
4342
- if( !SDL_strncmp(p,">(",2) && p[2] == ch ) {
4343
- h->tp = abc_check_track(h, h->tp);
4344
- abc_globalslide(h, h->tracktime, -1);
4345
- p += 3;
4346
- break;
4347
- }
4348
- if( !SDL_strncmp(p,">)",2) && p[2] == ch ) {
4349
- h->tp = abc_check_track(h, h->tp);
4350
- abc_globalslide(h, h->tracktime, 0);
4351
- p += 3;
4352
- break;
4353
- }
4354
- if( !SDL_strncmp(p,"upbow",5) && p[5] == ch ) {
4355
- abceffect = bow;
4356
- abceffoper = 1;
4357
- p += 6;
4358
- break;
4359
- }
4360
- if( !SDL_strncmp(p,"downbow",7) && p[7] == ch ) {
4361
- abceffect = bow;
4362
- abceffoper = 0;
4363
- p += 8;
4364
- break;
4365
- }
4366
- if( !SDL_strncmp(p,"trill",5) && p[5] == ch ) {
4367
- abceffect = trill;
4368
- abceffoper = 0;
4369
- p += 6;
4370
- break;
4371
- }
4372
- if( !SDL_strncmp(p,"trill(",6) && p[6] == ch ) {
4373
- abceffect = trill;
4374
- abceffoper = 255;
4375
- p += 7;
4376
- break;
4377
- }
4378
- if( !SDL_strncmp(p,"trill)",6) && p[6] == ch ) {
4379
- abceffect = none;
4380
- abceffoper = 0;
4381
- p += 7;
4382
- break;
4383
- }
4384
- if( !SDL_strncmp(p,"accent",6) && p[6] == ch ) {
4385
- abceffect = accent;
4386
- abceffoper = 0;
4387
- p += 7;
4388
- break;
4389
- }
4390
- if( !SDL_strncmp(p,"emphasis",8) && p[8] == ch ) {
4391
- abceffect = accent;
4392
- abceffoper = 0;
4393
- p += 9;
4394
- break;
4395
- }
4396
- if( !SDL_strncmp(p,">",1) && p[1] == ch ) {
4397
- abceffect = accent;
4398
- abceffoper = 0;
4399
- p += 2;
4400
- break;
4401
- }
4402
- if( !SDL_strncmp(p,"fermata",7) && p[7] == ch ) {
4403
- abcfermata = 1;
4404
- p += 8;
4405
- break;
4406
- }
4407
- if( !SDL_strncmp(p,"fine",4) && p[4] == ch ) {
4408
- h->tp = abc_check_track(h, h->tp);
4409
- abc_add_partbreak(h, h->tp, h->tracktime);
4410
- abc_add_fine(h, h->tp, h->tracktime);
4411
- p += 5;
4412
- break;
4413
- }
4414
- if( !SDL_strncmp(p,"segno",5) && p[5] == ch ) {
4415
- h->tp = abc_check_track(h, h->tp);
4416
- abc_add_partbreak(h, h->tp, h->tracktime);
4417
- abc_add_segno(h, h->tp, h->tracktime);
4418
- p += 6;
4419
- break;
4420
- }
4421
- if( !SDL_strncmp(p,"tocoda",6) && p[6] == ch ) {
4422
- h->tp = abc_check_track(h, h->tp);
4423
- abc_add_partbreak(h, h->tp, h->tracktime);
4424
- abc_add_tocoda(h, h->tp, h->tracktime);
4425
- p += 7;
4426
- break;
4427
- }
4428
- if( !SDL_strncmp(p,"D.C.",4) && p[4] == ch ) {
4429
- h->tp = abc_check_track(h, h->tp);
4430
- j = (h->tp->slidevol == -2)? jumpdcfade: jumpdacapo;
4431
- abc_add_setjumploop(h, h->tp, h->tracktime, j);
4432
- abc_add_partbreak(h, h->tp, h->tracktime);
4433
- p += 5;
4434
- break;
4435
- }
4436
- if( !SDL_strncmp(p,"D.S.",4) && p[4] == ch ) {
4437
- h->tp = abc_check_track(h, h->tp);
4438
- j = (h->tp->slidevol == -2)? jumpdsfade: jumpdasegno;
4439
- abc_add_setjumploop(h, h->tp, h->tracktime, j);
4440
- abc_add_partbreak(h, h->tp, h->tracktime);
4441
- p += 5;
4442
- break;
4443
- }
4444
- if( !SDL_strncmp(p,"dacapo",6) && p[6] == ch ) {
4445
- h->tp = abc_check_track(h, h->tp);
4446
- j = (h->tp->slidevol == -2)? jumpdcfade: jumpdacapo;
4447
- abc_add_setjumploop(h, h->tp, h->tracktime, j);
4448
- abc_add_partbreak(h, h->tp, h->tracktime);
4449
- p += 7;
4450
- break;
4451
- }
4452
- if( !SDL_strncmp(p,"dacoda",6) && p[6] == ch ) {
4453
- h->tp = abc_check_track(h, h->tp);
4454
- j = (h->tp->slidevol == -2)? jumpdcfade: jumpdacapo;
4455
- abc_add_setjumploop(h, h->tp, h->tracktime, j);
4456
- abc_add_partbreak(h, h->tp, h->tracktime);
4457
- p += 7;
4458
- break;
4459
- }
4460
- if( ch == '!' ) {
4461
- for( t=0; p[t] && SDL_strchr("|[:]!",p[t])==0 && !SDL_isspace(p[t]); t++ ) ;
4462
- if( p[t] == '!' ) { // volume and other decorations, deprecated
4463
- h->tp = abc_check_track(h, h->tp);
4464
- abcvol = abc_parse_decorations(h, h->tp, p);
4465
- p = &p[t+1];
4466
- }
4467
- }
4468
- else {
4469
- h->tp = abc_check_track(h, h->tp);
4470
- abcvol = abc_parse_decorations(h, h->tp, p);
4471
- while( (ch=*p++) && (ch != '+') )
4472
- ;
4473
- }
4474
- break;
4475
- case '`': // back quotes are for readability
4476
- break;
4477
- case '.': // staccato marks
4478
- break;
4479
- default: // some kinda note must follow
4480
- if( SDL_strchr("abcdefgABCDEFG^_=X",ch) ) {
4481
- h->tp = abc_check_track(h, h->tp);
4482
- abc_track_clear_tiedvpos(h);
4483
- abcbeatvol = abc_beat_vol(h, abcvol, (h->tracktime - bartime)/notelen_notediv_to_ticks(h->speed,1,mnotediv));
4484
- p += abc_add_noteon(h, ch, p, h->tracktime, barsig, abcbeatvol, abceffect, abceffoper);
4485
- if( abceffoper != 255 ) abceffect = none;
4486
- p += abc_notelen(p, &notelen, &notediv);
4487
- if( *p=='-' ) {
4488
- p++;
4489
- if( h->tp->tail && h->tp->tail->flg != 1 )
4490
- h->tp->tienote = h->tp->tail;
4491
- }
4492
- tupletr = abc_tuplet(&notelen, &notediv, tupletp, tupletq, tupletr);
4493
- while( SDL_isspace(*p) ) p++; // allow spacing in broken rithm notation
4494
- p += abc_brokenrithm(p, &notelen, &notediv, &brokenrithm, abchornpipe);
4495
- thistime = notelen_notediv_to_ticks(h->speed, notelen*snotelen, notediv*snotediv);
4496
- if( abcfermata ) {
4497
- thistime <<= 1;
4498
- abcfermata = 0;
4499
- }
4500
- if( thistime > abcgrace ) {
4501
- thistime -= abcgrace;
4502
- abcgrace = 0;
4503
- }
4504
- else {
4505
- abcgrace -= thistime;
4506
- thistime = abcticks(h->speed);
4507
- abcgrace += abcticks(h->speed);
4508
- }
4509
- h->tracktime += thistime;
4510
- if( thistime > abcticks(h->speed) )
4511
- abc_add_noteoff(h, h->tp, h->tracktime - abcnoslurs - (( ch0 == '.')? thistime / 2: 0));
4512
- else
4513
- abc_add_noteoff(h, h->tp, h->tracktime);
4514
- abc_add_sync(h, h->tp, h->tracktime);
4515
- if( h->gchordon && (h->tp == h->tpc) )
4516
- abc_add_gchord(h, h->tracktime, bartime);
4517
- if( h->drumon && (h->tp == h->tpr) )
4518
- abc_add_drum(h, h->tracktime, bartime);
4519
- abcarpeggio = 0;
4520
- break;
4521
- }
4522
- if( SDL_strchr("zx",ch) ) {
4523
- h->tp = abc_check_track(h, h->tp);
4524
- abc_track_clear_tiednote(h);
4525
- p += abc_notelen(p, &notelen, &notediv);
4526
- tupletr = abc_tuplet(&notelen, &notediv, tupletp, tupletq, tupletr);
4527
- while( SDL_isspace(*p) ) p++; // allow spacing in broken rithm notation
4528
- p += abc_brokenrithm(p, &notelen, &notediv, &brokenrithm, abchornpipe);
4529
- thistime = notelen_notediv_to_ticks(h->speed, notelen*snotelen, notediv*snotediv);
4530
- if( abcfermata ) {
4531
- thistime <<= 1;
4532
- abcfermata = 0;
4533
- }
4534
- if( thistime > abcgrace ) {
4535
- thistime -= abcgrace;
4536
- abcgrace = 0;
4537
- }
4538
- else {
4539
- abcgrace -= thistime;
4540
- thistime = abcticks(h->speed);
4541
- abcgrace += abcticks(h->speed);
4542
- }
4543
- h->tracktime += thistime;
4544
- abc_add_sync(h, h->tp, h->tracktime);
4545
- if( h->gchordon && (h->tp == h->tpc) )
4546
- abc_add_gchord(h, h->tracktime, bartime);
4547
- if( h->drumon && (h->tp == h->tpr) )
4548
- abc_add_drum(h, h->tracktime, bartime);
4549
- abcarpeggio = 0;
4550
- break;
4551
- }
4552
- if( SDL_strchr("Z",ch) ) {
4553
- h->tp = abc_check_track(h, h->tp);
4554
- abc_track_clear_tiednote(h);
4555
- p += abc_notelen(p, &notelen, &notediv);
4556
- thistime = notelen_notediv_to_ticks(h->speed, notelen*mnotelen, notediv*mnotediv);
4557
- if( abcfermata ) {
4558
- thistime <<= 1;
4559
- abcfermata = 0;
4560
- }
4561
- if( thistime > abcgrace ) {
4562
- thistime -= abcgrace;
4563
- abcgrace = 0;
4564
- }
4565
- else {
4566
- abcgrace -= thistime;
4567
- thistime = abcticks(h->speed);
4568
- abcgrace += abcticks(h->speed);
4569
- }
4570
- h->tracktime += thistime;
4571
- SDL_snprintf(barsig, sizeof (barsig), "%s%s", sig[abckey], sig[abckey]); // reset the key signature
4572
- abc_add_sync(h, h->tp, h->tracktime);
4573
- if( h->gchordon && (h->tp == h->tpc) )
4574
- abc_add_gchord(h, h->tracktime, bartime);
4575
- if( h->drumon && (h->tp == h->tpr) )
4576
- abc_add_drum(h, h->tracktime, bartime);
4577
- abcarpeggio = 0;
4578
- break;
4579
- }
4580
- if( IsAlpha(ch) && *p==':' ) {
4581
- // some unprocessed field line?
4582
- while( *p ) p++; // skip it
4583
- break;
4584
- }
4585
- break;
4586
- }
4587
- ch0 = ch; // remember previous char, can be staccato dot...
4588
- if( pp ) { // did we have a U: macro substitution?
4589
- if( !*p ) {
4590
- p = pp;
4591
- pp = 0;
4592
- }
4593
- }
4594
- }
4595
- }
4596
- }
4597
- }
4598
- if( mmsp ) mmfclose(mmstack[mmsp]);
4599
- }
4600
- ABC_CleanupMacros(h); // we dont need them anymore
4601
- if( !h->track ) {
4602
- char buf[10];
4603
- SDL_snprintf(buf,sizeof (buf),"%u",abcxnumber);
4604
- abc_message("abc X:%s has no body", buf);
4605
- h->track = abc_check_track(h, h->track); // for sanity...
4606
- }
4607
- if( abcstate == INBODY ) {
4608
- // last but not least shut off all pending events
4609
- abc_recalculate_tracktime(h);
4610
- for( ttp=h->track; ttp; ttp=ttp->next )
4611
- abc_add_noteoff(h,ttp,h->tracktime);
4612
- abc_add_partbreak(h, h->track, h->tracktime);
4613
- t = abc_patno(h, h->tracktime);
4614
- if( abc_pattracktime(h, h->tracktime) % abcticks(64 * h->speed) ) t++;
4615
- if( global_part == ' ' ) {
4616
- partpat[26][1] = t;
4617
- if( abcparts ) {
4618
- for( t=0; t<26; t++ )
4619
- if( partpat[t][0] < partpat[t][1] ) break;
4620
- if( t == 26 ) {
4621
- abc_message("parts (%s) set but not used", abcparts);
4622
- abc_set_parts(&abcparts, 0); // forget the parts array
4623
- }
4624
- }
4625
- }
4626
- else
4627
- partpat[global_part - 'A'][1] = t;
4628
- if( !abcparts ) abc_song_to_parts(h, &abcparts, partpat);
4629
- orderlen = abc_partpat_to_orderlist(partpat, abcparts, h, &orderlist, orderlen);
4630
- }
4631
- abc_synchronise_tracks(h); // distribute all control events
4632
- abc_recalculate_tracktime(h);
4633
- /*
4634
-
4635
- abctrack:
4636
- tracktick long
4637
- note byte
4638
- octave byte
4639
- instrument byte
4640
- effects byte
4641
-
4642
- tick = tracktick modulo speed
4643
- row = (tracktick div speed) modulo 64
4644
- pat = (tracktick div speed) div 64
4645
- ord = calculated
4646
-
4647
- */
4648
- #if 0
4649
- if( (p=SDL_getenv(ABC_ENV_DUMPTRACKS)) ) {
4650
- printf("P:%s\n",abcparts);
4651
- for( t=0; t<26; t++ )
4652
- if( partpat[t][1] >= partpat[t][0] )
4653
- printf(" %c ",t+'A');
4654
- if( partpat[26][1] >= partpat[26][0] )
4655
- printf("All");
4656
- printf("\n");
4657
- for( t=0; t<27; t++ )
4658
- if( partpat[t][1] >= partpat[t][0] )
4659
- printf("%3d ",partpat[t][0]);
4660
- printf("\n");
4661
- for( t=0; t<27; t++ )
4662
- if( partpat[t][1] >= partpat[t][0] )
4663
- printf("%3d ",partpat[t][1]);
4664
- printf("\n");
4665
- for( t=0; (int)t<orderlen; t++ )
4666
- printf("%3d ",t);
4667
- printf("\n");
4668
- for( t=0; (int)t<orderlen; t++ )
4669
- printf("%3d ",orderlist[t]);
4670
- printf("\n");
4671
- abc_dumptracks(h,p);
4672
- }
4673
- #endif
4674
-
4675
- // set module variables
4676
- if( abctempo == 0 ) abctempo = abcrate;
4677
- if( _this->m_nDefaultTempo == 0 ) _this->m_nDefaultTempo = abctempo;
4678
- _this->m_nType = MOD_TYPE_ABC;
4679
- numpat = 1+(modticks(h->tracktime) / h->speed / 64);
4680
- if( numpat > MAX_PATTERNS )
4681
- numpat = MAX_PATTERNS;
4682
- _this->m_nDefaultSpeed = h->speed;
4683
- _this->m_nChannels = abc_numtracks(h);
4684
- _this->m_dwSongFlags = SONG_LINEARSLIDES;
4685
- _this->m_nMinPeriod = 28 << 2;
4686
- _this->m_nMaxPeriod = 1712 << 3;
4687
- // orderlist
4688
- for(t=0; t < (uint32_t)orderlen; t++){
4689
- if( t >= MAX_ORDERS )
4690
- break;
4691
- _this->Order[t] = orderlist[t];
4692
- }
4693
- SDL_free(orderlist); // get rid of orderlist memory
4694
- // ==============================
4695
- // Load the pattern info now!
4696
- if( ABC_ReadPatterns(_this->Patterns, _this->PatternSize, h, numpat, _this->m_nChannels) ) {
4697
- // :^( need one more channel to handle the global events ;^b
4698
- _this->m_nChannels++;
4699
- h->tp = abc_locate_track(h, "", 99);
4700
- abc_add_sync(h, h->tp, h->tracktime);
4701
- for( t=0; t<numpat; t++ ) {
4702
- CSoundFile_FreePattern(_this->Patterns[t]);
4703
- _this->Patterns[t] = NULL;
4704
- }
4705
- ABC_ReadPatterns(_this->Patterns, _this->PatternSize, h, numpat, _this->m_nChannels);
4706
- }
4707
- // load instruments after building the patterns (chan == 10 track handling)
4708
- if( !PAT_Load_Instruments(_this) ) {
4709
- avoid_reentry = 0;
4710
- return FALSE;
4711
- }
4712
- // ============================================================
4713
- // set panning positions
4714
- if( _this->m_nChannels > MAX_BASECHANNELS )
4715
- _this->m_nChannels = MAX_BASECHANNELS;
4716
- for(t=0; t<_this->m_nChannels; t++) {
4717
- _this->ChnSettings[t].nPan = 0x30+((t+2)%5)*((0xD0 - 0x30)/5); // 0x30 = std s3m val
4718
- _this->ChnSettings[t].nVolume = 64;
4719
- }
4720
- avoid_reentry = 0; // it is safe now, I'm finished
4721
- abc_set_parts(&abcparts, 0); // free the parts array
4722
- ABC_Cleanup(h); // we dont need it anymore
4723
- return 1;
4724
- }
4725
-