1 /** 2 * @license License: Web Enabled Audio and Sound Enhancement Library (aka the Weasel audio library) Copyright 2011 - 2013 Warren Willmey. It is covered by the GNU General Public License version 3 as published by the Free Software Foundation, you should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. 3 */ 4 5 /** Namespace for Web Enabled Audio and Sound Enhancement Library (aka the Weasel audio library). 6 * @const 7 */ 8 var weasel = weasel||{}; 9 10 11 // --------------------------------------------------------------------------- 12 /** The Web Enabled Audio and Sound Enhancement Library (aka the Weasel audio library) major version number. 13 * 14 * @type {int} 15 * @const 16 */ 17 weasel.LibraryVersionMajor = 1; 18 // --------------------------------------------------------------------------- 19 /** The Web Enabled Audio and Sound Enhancement Library (aka the Weasel audio library) minor version number. 20 * 21 * @type {int} 22 * @const 23 */ 24 weasel.LibraryVersionMinor = 9; 25 // --------------------------------------------------------------------------- 26 /** The Web Enabled Audio and Sound Enhancement Library (aka the Weasel audio library) maintenance version number. 27 * 28 * @type {int} 29 * @const 30 */ 31 weasel.LibraryVersionMaintenance = 1; 32 33 // --------------------------------------------------------------------------- 34 /** The Web Enabled Audio and Sound Enhancement Library (aka the Weasel audio library) version number. 35 * 36 * @type {string} 37 * @const 38 */ 39 weasel.LibraryVersionNumber = weasel.LibraryVersionMajor + '.' + weasel.LibraryVersionMinor + '.' + weasel.LibraryVersionMaintenance; 40 41 // --------------------------------------------------------------------------- 42 /** Object containing constants that a Ultimate Soundtracker 1.21 module require. 43 * 44 * @constructor 45 * @const 46 */ 47 weasel.FormatUltimateSoundTracker121 = 48 { 49 /** The offset into the module data containing the Title. 50 * 51 * @const 52 * @type {int} 53 */ 54 Title: 0 55 /** The maximum title length in bytes. 56 * 57 * @const 58 * @type {int} 59 */ 60 , MaxTitleLength:20 61 /** The offset into the module data to the 15 sample header. 62 * 63 * @const 64 * @type {int} 65 */ 66 , SampleHeaders: 20 67 /** The offset in bytes, from the beginning of the module, to the Song Length. 68 * Which is the number of patterns listed in the Pattern Sequence Table before 69 * the song restarts back to Pattern Sequence Table entry 0. It should be noted 70 * that there may be other unused patterns listed pasted the end of the song. 71 * 72 * @const 73 * @enum {int} 74 */ 75 , SongLength: 470 76 /** The offset in bytes, from the beginning of the module, to where the Song Speed 77 * (also refered to as the BPM, Beats Per Minute) is stored. The Song Speed 78 * has a range of 0-220, this limit was set down in Ultimate Soundtracker 1.8. 79 * 80 * @const 81 * @enum {int} 82 */ 83 , SongSpeed: 471 84 /** The offset in bytes, from the beginning of the module, to the Pattern Sequence 85 * Table. This table contains the order that each pattern is play in. 86 * 87 * @const 88 * @enum {int} 89 */ 90 , PatternSequenceTable: 472 91 92 /** The offset in bytes, from the beginning of the module, to the first pattern. 93 * 94 * @const 95 * @enum {int} 96 */ 97 , PatternData: 600 98 99 /** The array of 15 Sample Headers each containing the sample name, length, volume etc. 100 * 101 * @const 102 * @enum {int} 103 */ 104 , SampleHeader: { 105 SampleName : 0 106 , MaxNameLength : 22 107 , LengthInWords : 22 108 , Volume : 24 109 , RepeatOffsetInBytes : 26 110 , RepeatLengthInWords : 28 111 , HeaderSize : 30 112 } 113 114 /** The offsets into the pattern data per channel and data masks to extract instrument and effect numbers. 115 * 116 * @const 117 * @enum {int} 118 */ 119 , Channel: { 120 Note: 0 121 , InstrumentNumber: 2 122 , Effect: 2 123 , EffectParameters: 3 124 , EffectMask: 0x0f 125 , InstrumentNumberMask: 0xf0 126 , InstrumentNumberShiftBitsRight: 4 127 } 128 129 /** The supported effects in a Ultimate Soundtracker module. 130 * 131 * @const 132 * @enum {int} 133 */ 134 , Effects: { 135 None: 0 136 , Arpeggio: 1 137 , Pitchbend: 2 138 } 139 140 /** The size of the Ultimate Soundtracker header plus the first pattern (which 141 * is always present). This represents the bare minimum amount of data needed for a Ultimate Soundtracker module. 142 * 143 * @const 144 * @type {int} 145 */ 146 , MinimumHeaderSize: 1624 147 /** The maximum size of a sample (in bytes) in a Ultimate Soundtracker module, 148 * this value is derived from the patch list on the ST-01 sample disk. In that 149 * ALL samples on that disk are under 9999 bytes. 150 * @const 151 * @type {int} 152 */ 153 , MaxSampleSize: 9999 154 /** The total length in bytes of the sequence table in a Ultimate Soundtracker module. 155 * @const 156 * @type {int} 157 */ 158 , SequenceTableLength: 128 159 /** The maximum number of unique patterns allowed in a Ultimate Soundtracker module. 160 * @const 161 * @type {int} 162 */ 163 , MaxUniquePatterns: 64 164 /** The number of bytes needed to store each pattern in a Ultimate Soundtracker module. 165 * @const 166 * @type {int} 167 */ 168 , PatternSize: 1024 169 /** The number of rows per pattern in a Ultimate Soundtracker module. 170 * @const 171 * @type {int} 172 */ 173 , NumberOfRowsPerPattern: 64 174 /** The number of channels per pattern in a Ultimate Soundtracker module. 175 * @const 176 * @type {int} 177 */ 178 , NumberOfChannels: 4 179 /** The number of instruments in a Ultimate Soundtracker module. 180 * @const 181 * @type {int} 182 */ 183 , NumberOfInstruments: 15 184 /** The size in byte of the Ultimate Soundtracker module header, after this the pattern data appears. 185 * @const 186 * @type {int} 187 */ 188 , ModuleHeaderSize: 600 189 /** Number of bytes required per pattern cell. 190 * @const 191 * @type {int} 192 */ 193 , BytesPerRowCell: 4 194 195 /** The number of Ticks spent per row, which is 6. This value does not change 196 * in Ultimate Soundtracker, later module formats allow it to change. 197 * @const 198 * @type {int} 199 */ 200 , TicksPerRow: 6 201 202 /** Number of octaves used in a Ultimate Soundtracker 1.21 module. 203 * @const 204 * @type {int} 205 */ 206 , Octaves: 3 207 208 /** Number of notes per octave in a Ultimate Soundtracker 1.21 module, chromatic scale. 209 * @const 210 * @type {int} 211 */ 212 , NotesPerOctave: 12 213 214 /** Total notes present in a Ultimate Soundtracker 1.21 module.. 215 * @const 216 * @type {int} 217 */ 218 , TotalNotes: 3 * 12 219 // Hardware clock values. 220 // 221 // , CIATimerNTSC: 715909 // CIA Timer Hz clock is based on (CPU frequency / 10), Clock Constant can also be used (ClockConstant[NTSC|PAL] / 5). 222 /** The Amiga NTSC clock constant, used to compute the sampling frequency on North America machines. 223 * @const 224 * @type {int} 225 */ 226 , ClockConstantNTSC: 3579545 227 228 /** The Amiga PAL clock constant, used to compute the sampling frequency on European machines. 229 * @const 230 * @type {int} 231 */ 232 , ClockConstantPAL: 3546895 233 234 /** 235 * Time in milliseconds that Ultimate Soundtracker waits between telling the DMA to stop playing and start a new Sample. 236 * Debatable whether this is needed, there may be some tunes that require synchronisation of samples/channels for phaser effects. 237 * As noted below the pause loop is 500 of the "dbf" 68000 instruction, which takes 10 clock cycles to execute. 238 * (500 * 10) = 5000 / 448 ( approx number of clock cycles CPU has per scanline) = 11.16 scanlines. 239 * Plus some other bits. 240 * 241 * @const 242 * @type {float} 243 */ 244 , WaitForDMAToStop: 0.768 245 246 /** Table to convert the period into the note and octave in human readable form. 247 * Amiga period value (used to set the pitch of the note) to Note table. 248 * Notice that these values are NTSC, not PAL.. 249 * 250 * @const 251 * @enum {string} 252 */ 253 , NoteTable: { 254 856 : 'C-1' 255 , 808 : 'C#1' 256 , 762 : 'D-1' 257 , 720 : 'D#1' 258 , 678 : 'E-1' 259 , 640 : 'F-1' 260 , 604 : 'F#1' 261 , 570 : 'G-1' 262 , 538 : 'G#1' 263 , 508 : 'A-1' 264 , 480 : 'A#1' 265 , 453 : 'B-1' 266 267 , 428 : 'C-2' 268 , 404 : 'C#2' 269 , 381 : 'D-2' 270 , 360 : 'D#2' 271 , 339 : 'E-2' 272 , 320 : 'F-2' 273 , 302 : 'F#2' 274 , 285 : 'G-2' 275 , 269 : 'G#2' 276 , 254 : 'A-2' 277 , 240 : 'A#2' 278 , 226 : 'B-2' 279 280 , 214 : 'C-3' 281 , 202 : 'C#3' 282 , 190 : 'D-3' 283 , 180 : 'D#3' 284 , 170 : 'E-3' 285 , 160 : 'F-3' 286 , 151 : 'F#3' 287 , 143 : 'G-3' 288 , 135 : 'G#3' 289 , 127 : 'A-3' 290 , 120 : 'A#3' 291 , 113 : 'B-3' 292 } 293 294 295 /** 296 * Period note table used to find arpeggio period values from the base note period. 297 * Again notice these are the NTSC values, not PAL. 298 * Table is terminated with a zero, which indicates the note will not be played. 299 * Karsten Obarski original routine does not take into account the end of the table 300 * so playing B-3 with arpeggio 0x37 effectively dropping you into random data territory, 301 * because song variables (tick speed etc) are stored immediately after the note table. 302 * Without a doubt Karsten would be aware of this when composing and avoided this issue, 303 * but many other people probably would not. 304 * 305 * @const 306 * @type {array} 307 */ 308 , PeriodTable: [ 309 856 310 , 808 311 , 762 312 , 720 313 , 678 314 , 640 315 , 604 316 , 570 317 , 538 318 , 508 319 , 480 320 , 453 321 322 , 428 323 , 404 324 , 381 325 , 360 326 , 339 327 , 320 328 , 302 329 , 285 330 , 269 331 , 254 332 , 240 333 , 226 334 335 , 214 336 , 202 337 , 190 338 , 180 339 , 170 340 , 160 341 , 151 342 , 143 343 , 135 344 , 127 345 , 120 346 , 113 347 , 0 348 349 // Here ends the period table, however due to the Arpeggio command being able to 350 // add 0-15 on top of note period 113 value "random" memory can get picked up. 351 // Which if you use the program Utimate Soundtracker is in fact the note period table in ASCii ("c-1 c#1 d-1 d#1 e-1 f-1 f#1"). 352 // Alternative if you use the 68000 assembly replay routine provided by Karsten Obarski you DO end up with random data (memory offsets and track row, pattern position would be stored there). 353 // So as the composer would have used the Ultimate Soundtracker editor to compose their tunes it makes sense to use the ASCii note period text as the random data, because they did. 354 // Big thanks to the WinUAE team (Ultimate Amiga Emulator) for writing such a nice debugger that took the sting out of find this quirk (along with the SLL7.mod, actually S.L.L. uses this "effect" a few times, SLL6.mod as well). 355 // 356 // Well, if only life was that easy, there is bug associated with this problem, in that any new sample will NOT be started (or restarted) and the current sample continues playing from its current position at the newly assigned period and volume. 357 // According to the Amiga Hardware Reference Manual page 141, section "Stopping the Audio DMA" it says "If the DMA channel is disabled for a very short time (less that two sampling periods) it may stay on and thus continue from where it it left off." 358 // So because this random data causes a very low sampling rate (140hz range) the samples do not stop when the DMA is set to stop and it takes the assignment of a new period value but does not change instrument (which means in effect a note gets skipped). 359 // 360 // The cut off point varies from implementation of the replay routine, but basically there is a software pause loop prior to the DMA being re-enabled. 361 // In the Editor for Ultimate Soundtracker this loop uses a counter of 500, in the form: 362 // move.l #500, d0 363 // pause: dbra d0, pause 364 // move.l #$8000, d0 365 // or.w enableDMAChannels, d0 366 // move.w d0, $dff096 // Enable DMA Audio channels. 367 // This pause (plus some other bits, like disabling the DMA) on a stock Amiga takes about 12 scanlines, which is 0.768ms ( (1000ms / (50fps * 312.5 scanlines)) * 12 scanlines). 368 // Which results in a minimum frequency of ~2604hz before this bug appears. (1000ms / 2604hz) * 2 Sampling Periods = ~0.768ms. 369 // 2604hz = period value of 1374, which as you can see is less that every value in this "Random" data. 370 // 371 , 0x632D // "c-" 372 , 0x3120 // "1 " 373 , 0x6323 // "c#" 374 , 0x3120 // "1 " 375 376 , 0x642D // "d-" 377 , 0x3120 // "1 " 378 , 0x6423 // "d#" 379 , 0x3120 // "1 " 380 381 , 0x652D // "e-" 382 , 0x3120 // "1 " 383 , 0x662D // "f-" 384 , 0x3120 // "1 " 385 386 , 0x6623 // "f#" 387 , 0x3120 // "1 " 388 ] 389 }; 390