-
Notifications
You must be signed in to change notification settings - Fork 0
/
print.html
592 lines (550 loc) · 74.2 KB
/
print.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
<!DOCTYPE HTML>
<html lang="en" class="light" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Ensoniq .ECW File Format Specification</title>
<meta name="robots" content="noindex">
<!-- Custom HTML head -->
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('light')
html.classList.add(theme);
var body = document.querySelector('body');
body.classList.remove('no-js')
body.classList.add('js');
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var body = document.querySelector('body');
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
body.classList.remove('sidebar-visible');
body.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded affix "><li class="part-title">.ECW file specification 1.5 (2009-1-29)</li><li class="chapter-item expanded "><a href="start.html"><strong aria-hidden="true">1.</strong> Getting Started</a></li><li class="chapter-item expanded "><a href="file_header.html"><strong aria-hidden="true">2.</strong> File Header</a></li><li class="chapter-item expanded "><a href="bank_map.html"><strong aria-hidden="true">3.</strong> Bank Map</a></li><li class="chapter-item expanded "><a href="drum_kit_map.html"><strong aria-hidden="true">4.</strong> Drum Kit Map</a></li><li class="chapter-item expanded "><a href="midi_patch_maps.html"><strong aria-hidden="true">5.</strong> MIDI Patch Maps</a></li><li class="chapter-item expanded "><a href="drum_note_maps.html"><strong aria-hidden="true">6.</strong> Drum Note Maps</a></li><li class="chapter-item expanded "><a href="inst_headers.html"><strong aria-hidden="true">7.</strong> Instrument Headers</a></li><li class="chapter-item expanded "><a href="patch_headers.html"><strong aria-hidden="true">8.</strong> Patch Headers</a></li><li class="chapter-item expanded "><a href="cubbe_holes.html"><strong aria-hidden="true">9.</strong> Cubbeholes</a></li><li class="chapter-item expanded "><a href="sample_headers.html"><strong aria-hidden="true">10.</strong> Sample Headers</a></li><li class="chapter-item expanded "><a href="samples.html"><strong aria-hidden="true">11.</strong> Sample Waveform Area / Sample Set Info Area</a></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<!-- Track and set sidebar scroll position -->
<script>
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
sidebarScrollbox.addEventListener('click', function(e) {
if (e.target.tagName === 'A') {
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
}
}, { passive: true });
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
sessionStorage.removeItem('sidebar-scroll');
if (sidebarScrollTop) {
// preserve sidebar scroll position when navigating via links within sidebar
sidebarScrollbox.scrollTop = sidebarScrollTop;
} else {
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
var activeSection = document.querySelector('#sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
</script>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Ensoniq .ECW File Format Specification</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="getting-started"><a class="header" href="#getting-started">Getting Started</a></h1>
<p>In this document, ".ECW file" or "waveset" refers to a file with an extension of ".ECW" which stores articulation and sample data used by the MIDI synthesizer of sound cards equipped with an ES1370, ES1371, or ES1373 chip. These sound cards include the Ensoniq AudioPCI, the Sound Blaster! AudioPCI, the Sound Blaster! PCI64, the Sound Blaster! PCI128, and the Sound Blaster Live!. The file also includes some text describing the file and some mysterious data which seems to be vestigial and completely unnecessary.</p>
<h2 id="disclaimer"><a class="header" href="#disclaimer">DISCLAIMER</a></h2>
<p>DISCLAIMER: THIS MATERIAL IS PROVIDED "AS IS". I verify the information contained in this list to the best of my ability, but I cannot be held responsible for any problems caused by use or misuse of the information.</p>
<p>Some file formats were not released by their creators, others are regarded as proprietary, which means that if your programs deal with them, you might be looking for trouble.</p>
<p>It is recommended that you make a backup copy of the original waveset file if you plan to make any alterations to it, because some values may cause your PC to crash or lock up during MIDI playback.</p>
<p>The .ECW file uses Intel byte order (LSB first).</p>
<p>Counts are given in DECIMAL, not hexadecimal. When TYPE is "string", the count is the length of the string in characters.</p>
<h1 id="contact-info"><a class="header" href="#contact-info">Contact Info</a></h1>
<ul>
<li><strong>Website</strong>: <a href="http://www.johnnengelmann.com">http://www.johnnengelmann.com</a></li>
<li><strong>E-mail</strong>: [email protected]</li>
</ul>
<div style="break-before: page; page-break-before: always;"></div><h1 id="file-header"><a class="header" href="#file-header">File Header</a></h1>
<p>The .ECW file header stores the text that is shown when the waveset is loaded in the configurator. It also specifies the size and quantity of the other sections of the file. The file header is 1930 bytes long.</p>
<div class="table-wrapper"><table><thead><tr><th style="text-align: center">OFFSET</th><th style="text-align: right">Count</th><th style="text-align: left">TYPE</th><th style="text-align: left">Description</th></tr></thead><tbody>
<tr><td style="text-align: center">0000h</td><td style="text-align: right">4</td><td style="text-align: left">string</td><td style="text-align: left">File ID (always <code>ECLW</code>)</td></tr>
<tr><td style="text-align: center">0004h</td><td style="text-align: right">4</td><td style="text-align: left">string</td><td style="text-align: left">Spacer. It's a series of 4 bytes of unknown purpose. The contents of a spacer are usually 01h, 00h, 01h, 00h; however, changing the contents does not seem to have any effect whatsoever. Only the size and placement of spacers matters; their contents do not.</td></tr>
<tr><td style="text-align: center">0008h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">File offset where allocation chunk starts</td></tr>
<tr><td style="text-align: center">000ch</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">Unknown. Always has value of 16.</td></tr>
<tr><td style="text-align: center">0010h</td><td style="text-align: right">80</td><td style="text-align: left">string</td><td style="text-align: left">Copyright info for this waveset</td></tr>
<tr><td style="text-align: center">0060h</td><td style="text-align: right">80</td><td style="text-align: left">string</td><td style="text-align: left">Waveset name</td></tr>
<tr><td style="text-align: center">00b0h</td><td style="text-align: right">256</td><td style="text-align: left">string</td><td style="text-align: left">Filename of this waveset (ignored by the configurator)</td></tr>
<tr><td style="text-align: center">01b0h</td><td style="text-align: right">80</td><td style="text-align: left">string</td><td style="text-align: left">Description of this waveset</td></tr>
<tr><td style="text-align: center">0200h</td><td style="text-align: right">1280</td><td style="text-align: left">string</td><td style="text-align: left">Information on this waveset. Usable length is only 963 bytes. 964~1280 bytes are reserved.</td></tr>
<tr><td style="text-align: center">0700h</td><td style="text-align: right">4</td><td style="text-align: left">string</td><td style="text-align: left">Spacer</td></tr>
<tr><td style="text-align: center">0704h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">File offset where bank map starts</td></tr>
<tr><td style="text-align: center">0708h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">Length in bytes of the bank map (always 256)</td></tr>
<tr><td style="text-align: center">070ch</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">Number of bank maps (always 1)</td></tr>
<tr><td style="text-align: center">0710h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">File offset where drum kit map starts</td></tr>
<tr><td style="text-align: center">0714h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">Length in bytes of the drum kit map (always 256)</td></tr>
<tr><td style="text-align: center">0718h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">Number of drum kit maps (always 1)</td></tr>
<tr><td style="text-align: center">071ch</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">File offset where MIDI patch maps start</td></tr>
<tr><td style="text-align: center">0720h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">Total length in bytes of all MIDI patch maps (always number of MIDI patch maps multiplied by 256)</td></tr>
<tr><td style="text-align: center">0724h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">Number of MIDI patch maps</td></tr>
<tr><td style="text-align: center">0728h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">File offset where drum note maps start</td></tr>
<tr><td style="text-align: center">072ch</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">Total length in bytes of all drum note maps (always number of drum note maps multiplied by 256)</td></tr>
<tr><td style="text-align: center">0730h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">Number of drum note maps</td></tr>
<tr><td style="text-align: center">0734h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">File offset where instrument headers start</td></tr>
<tr><td style="text-align: center">0738h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">Total length in bytes of all instrument headers (always number of instrument headers multiplied by 23)</td></tr>
<tr><td style="text-align: center">073ch</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">Number of instrument headers</td></tr>
<tr><td style="text-align: center">0740h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">File offset where patch headers start</td></tr>
<tr><td style="text-align: center">0744h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">Total length in bytes of all patch headers (always number of patch headers multiplied by 76)</td></tr>
<tr><td style="text-align: center">0748h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">Number of patch headers</td></tr>
<tr><td style="text-align: center">074ch</td><td style="text-align: right">4</td><td style="text-align: left">string</td><td style="text-align: left">Spacer</td></tr>
<tr><td style="text-align: center">0750h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">File offset where array #1 starts</td></tr>
<tr><td style="text-align: center">0754h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">Total length in bytes of all "cubbyholes" in array #1 (always number of "cubbyholes" in array #1, multiplied by 2)</td></tr>
<tr><td style="text-align: center">0758h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">Number of "cubbyholes" in array #1</td></tr>
<tr><td style="text-align: center">075ch</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">File offset where array #2 starts</td></tr>
<tr><td style="text-align: center">0760h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">Total length in bytes of all "cubbyholes" in array #2 (always number of "cubbyholes" in array #2, multiplied by 2)</td></tr>
<tr><td style="text-align: center">0764h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">Number of "cubbyholes" in array #2</td></tr>
<tr><td style="text-align: center">0768h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">File offset where array #3 starts</td></tr>
<tr><td style="text-align: center">076ch</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">Total length in bytes of all "cubbyholes" in array #3 (always number of "cubbyholes" in array #3, multiplied by 2)</td></tr>
<tr><td style="text-align: center">0770h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">Number of "cubbyholes" in array #3</td></tr>
<tr><td style="text-align: center">0774h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">File offset where sample headers start</td></tr>
<tr><td style="text-align: center">0778h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">Total length in bytes of all sample headers (always number of sample headers multiplied by 16)</td></tr>
<tr><td style="text-align: center">077ch</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">Number of sample headers</td></tr>
<tr><td style="text-align: center">0780h</td><td style="text-align: right">4</td><td style="text-align: left">string</td><td style="text-align: left">Spacer</td></tr>
<tr><td style="text-align: center">0784h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">File offset where sample waveform area begins</td></tr>
<tr><td style="text-align: center">0788h</td><td style="text-align: right">1</td><td style="text-align: left">dword</td><td style="text-align: left">Total length of sample waveform area in bytes</td></tr>
</tbody></table>
</div><div style="break-before: page; page-break-before: always;"></div><h1 id="bank-map"><a class="header" href="#bank-map">Bank Map</a></h1>
<p>The bank map assigns one MIDI patch map to each of the 128 MIDI banks. The bank map is 256 bytes long.</p>
<div class="table-wrapper"><table><thead><tr><th style="text-align: center">OFFSET</th><th style="text-align: right">Count</th><th style="text-align: center">TYPE</th><th style="text-align: left">Description</th></tr></thead><tbody>
<tr><td style="text-align: center">0000h</td><td style="text-align: right">1</td><td style="text-align: center">word</td><td style="text-align: left">MIDI patch map assigned to MIDI bank #0</td></tr>
<tr><td style="text-align: center">0002h</td><td style="text-align: right">1</td><td style="text-align: center">word</td><td style="text-align: left">MIDI patch map assigned to MIDI bank #1</td></tr>
<tr><td style="text-align: center">0004h</td><td style="text-align: right">1</td><td style="text-align: center">word</td><td style="text-align: left">MIDI patch map assigned to MIDI bank #2</td></tr>
<tr><td style="text-align: center">0006h</td><td style="text-align: right">1</td><td style="text-align: center">word</td><td style="text-align: left">MIDI patch map assigned to MIDI bank #3</td></tr>
<tr><td style="text-align: center">0008h ~ 00fch</td><td style="text-align: right">1</td><td style="text-align: center">word</td><td style="text-align: left">MIDI patch map assigned to MIDI bank #4~126</td></tr>
<tr><td style="text-align: center">00feh</td><td style="text-align: right">1</td><td style="text-align: center">word</td><td style="text-align: left">MIDI patch map assigned to MIDI bank #127</td></tr>
</tbody></table>
</div><div style="break-before: page; page-break-before: always;"></div><h1 id="drum-kit-map"><a class="header" href="#drum-kit-map">Drum Kit Map</a></h1>
<p>The drum kit map assigns one drum note map to each of the 128 MIDI drum kits. Each drum kit map is 256 bytes long.</p>
<div class="table-wrapper"><table><thead><tr><th style="text-align: center">OFFSET</th><th style="text-align: right">Count</th><th style="text-align: center">TYPE</th><th style="text-align: left">Description</th></tr></thead><tbody>
<tr><td style="text-align: center">0000h</td><td style="text-align: right">1</td><td style="text-align: center">word</td><td style="text-align: left">Drum note map assigned to MIDI drum kit #0</td></tr>
<tr><td style="text-align: center">0002h</td><td style="text-align: right">1</td><td style="text-align: center">word</td><td style="text-align: left">Drum note map assigned to MIDI drum kit #1</td></tr>
<tr><td style="text-align: center">0004h</td><td style="text-align: right">1</td><td style="text-align: center">word</td><td style="text-align: left">Drum note map assigned to MIDI drum kit #2</td></tr>
<tr><td style="text-align: center">0006h</td><td style="text-align: right">1</td><td style="text-align: center">word</td><td style="text-align: left">Drum note map assigned to MIDI drum kit #3</td></tr>
<tr><td style="text-align: center">0008h ~ 00fch</td><td style="text-align: right">1</td><td style="text-align: center">word</td><td style="text-align: left">Drum note map assigned to MIDI drum kit #4~126</td></tr>
<tr><td style="text-align: center">00feh</td><td style="text-align: right">1</td><td style="text-align: center">word</td><td style="text-align: left">Drum note map assigned to MIDI drum kit #127</td></tr>
</tbody></table>
</div><div style="break-before: page; page-break-before: always;"></div><h1 id="midi-patch-maps"><a class="header" href="#midi-patch-maps">MIDI Patch Maps</a></h1>
<p>The MIDI patch maps assign one instrument to each of the 128 MIDI patches. Each MIDI patch map corresponds to one or more MIDI banks. One MIDI patch map can be used by more than one MIDI bank; in fact, all of the MIDI banks can use the same MIDI patch map if desired (which would allow a smaller filesize and save system RAM). The number of MIDI patch maps is set in the .ECW file header. Each MIDI patch map is 256 bytes long.</p>
<div class="table-wrapper"><table><thead><tr><th>OFFSET</th><th>Count</th><th>TYPE</th><th>Description</th></tr></thead><tbody>
<tr><td>0000h</td><td>1</td><td>word</td><td>Instrument assigned to MIDI patch #0 when using a MIDI bank whose entry in the bank map is equal to 0</td></tr>
<tr><td>0002h</td><td>1</td><td>word</td><td>Instrument assigned to MIDI patch #1, bank #0</td></tr>
<tr><td>0004h</td><td>1</td><td>word</td><td>Instrument assigned to MIDI patch #2, bank #0</td></tr>
<tr><td>0006h</td><td>1</td><td>word</td><td>Instrument assigned to MIDI patch #3, bank #0</td></tr>
<tr><td>0008h~00fch</td><td>1</td><td>word</td><td>Instrument assigned to MIDI patch #4~126, bank #0</td></tr>
<tr><td>00feh</td><td>1</td><td>word</td><td>Instrument assigned to MIDI patch #127, bank #0</td></tr>
</tbody></table>
</div>
<p>If there are multiple MIDI patch maps (according to the file header), then the MIDI patch maps must follow one another immediately with no gaps between:</p>
<div class="table-wrapper"><table><thead><tr><th>OFFSET</th><th>Count</th><th>TYPE</th><th>Description</th></tr></thead><tbody>
<tr><td>0100h</td><td>1</td><td>word</td><td>Instrument assigned to MIDI patch #0 when using a MIDI bank whose entry in the bank map is equal to 1</td></tr>
<tr><td>0102h~01fch</td><td>1</td><td>word</td><td>Instrument assigned to MIDI patch #1~126 when using a MIDI bank whose entry in the bank map is equal to 1</td></tr>
<tr><td>01feh</td><td>1</td><td>word</td><td>Instrument assigned to MIDI patch #127 when using a MIDI bank whose entry in the bank map is equal to 1</td></tr>
<tr><td>0200h</td><td>1</td><td>word</td><td>Instrument assigned to MIDI patch #0 when using a MIDI bank whose entry in the bank map is equal to 2</td></tr>
<tr><td>...</td><td>...</td><td>...</td><td>etc.</td></tr>
</tbody></table>
</div><div style="break-before: page; page-break-before: always;"></div><h1 id="drum-note-maps"><a class="header" href="#drum-note-maps">Drum Note Maps</a></h1>
<p>The drum note maps assign one instrument to each of the 128 MIDI drum notes. Each drum note map corresponds to one or more MIDI drum kits. One drum note map can be used by more than one drum kit; in fact, all of the drum kits can use the same drum note map if desired (which would allow a smaller filesize and save system RAM). The number of drum note maps is set in the .ECW file header. Each drum note map is 256 bytes long.</p>
<div class="table-wrapper"><table><thead><tr><th style="text-align: left">OFFSET</th><th style="text-align: right">Count</th><th style="text-align: center">TYPE</th><th style="text-align: left">Description</th></tr></thead><tbody>
<tr><td style="text-align: left">0000h</td><td style="text-align: right">1</td><td style="text-align: center">word</td><td style="text-align: left">Instrument assigned to MIDI drum note #0 when using a drum kit whose entry in the drum kit map is equal to 0</td></tr>
<tr><td style="text-align: left">0002h</td><td style="text-align: right">1</td><td style="text-align: center">word</td><td style="text-align: left">Instrument assigned to MIDI patch #1, drum kit #0</td></tr>
<tr><td style="text-align: left">0004h</td><td style="text-align: right">1</td><td style="text-align: center">word</td><td style="text-align: left">Instrument assigned to MIDI patch #2, drum kit #0</td></tr>
<tr><td style="text-align: left">0006h</td><td style="text-align: right">1</td><td style="text-align: center">word</td><td style="text-align: left">Instrument assigned to MIDI patch #3, drum kit #0</td></tr>
<tr><td style="text-align: left">0008h~00fch</td><td style="text-align: right">1</td><td style="text-align: center">word</td><td style="text-align: left">Instrument assigned to MIDI patch #4~126, drum kit #0</td></tr>
<tr><td style="text-align: left">00feh</td><td style="text-align: right">1</td><td style="text-align: center">word</td><td style="text-align: left">Instrument assigned to MIDI patch #127, drum kit #0</td></tr>
</tbody></table>
</div>
<p>If there are multiple drum kit maps (according to the file header), then the drum kit maps must follow one another immediately with no gaps between:</p>
<div class="table-wrapper"><table><thead><tr><th style="text-align: left">OFFSET</th><th style="text-align: right">Count</th><th style="text-align: center">TYPE</th><th style="text-align: left">Description</th></tr></thead><tbody>
<tr><td style="text-align: left">0100h</td><td style="text-align: right">1</td><td style="text-align: center">word</td><td style="text-align: left">Instrument assigned to drum note #0 when using a drum kit whose entry in the drum kit map is equal to 1</td></tr>
<tr><td style="text-align: left">0102h~01fch</td><td style="text-align: right">1</td><td style="text-align: center">word</td><td style="text-align: left">Instrument assigned to drum note #1~126 when using a drum kit whose entry in the drum kit map is equal to 1</td></tr>
<tr><td style="text-align: left">01feh</td><td style="text-align: right">1</td><td style="text-align: center">word</td><td style="text-align: left">Instrument assigned to drum note #127 when using a drum kit whose entry in the drum kit map is equal to 1</td></tr>
<tr><td style="text-align: left">0200h</td><td style="text-align: right">1</td><td style="text-align: center">word</td><td style="text-align: left">Instrument assigned to drum note #0 when using a drum kit whose entry in the drum kit map is equal to 2</td></tr>
<tr><td style="text-align: left">0202h...</td><td style="text-align: right">1</td><td style="text-align: center">word</td><td style="text-align: left">...</td></tr>
</tbody></table>
</div><div style="break-before: page; page-break-before: always;"></div><h1 id="instrument-headers"><a class="header" href="#instrument-headers">Instrument Headers</a></h1>
<p>The instrument headers assign one or more patches (that is, the INTERNAL patches used in the waveset, as opposed to MIDI patches, which are EXTERNAL) to each of the instruments. The instrument headers also affect certain properties of the instruments, such as tuning and pan. The number of instrument headers is set in the .ECW file header. Each instrument header is 23 bytes long.</p>
<div class="table-wrapper"><table><thead><tr><th style="text-align: center">OFFSET</th><th style="text-align: center">Count</th><th style="text-align: center">TYPE</th><th style="text-align: left">Description</th></tr></thead><tbody>
<tr><td style="text-align: center">0000h</td><td style="text-align: center">1</td><td style="text-align: center">char</td><td style="text-align: left">Determines the function of the remaining 22 bytes in the current instrument header</td></tr>
</tbody></table>
</div>
<p>When the byte at offset 0000h of an instrument header has a value of 2, the rest of the header is arranged as follows:</p>
<div class="table-wrapper"><table><thead><tr><th style="text-align: center">OFFSET</th><th style="text-align: center">Count</th><th style="text-align: center">TYPE</th><th style="text-align: left">Description</th></tr></thead><tbody>
<tr><td style="text-align: center">0001h</td><td style="text-align: center">1</td><td style="text-align: center">char</td><td style="text-align: left">When set to a value of 0, only the first instrument sub-header (see below) is active. When set to 1, both sub-headers are used simultaneously for each note played. When set to 2, a split point is used to select which of the sub-headers is used for a given note. A value of 3 makes only the second sub-header active. (Other values make neither active.)</td></tr>
<tr><td style="text-align: center">0002h</td><td style="text-align: center">1</td><td style="text-align: center">char</td><td style="text-align: left">The note number above which only the second instrument sub-header is used; otherwise, only the first instrument sub-header is used. This is only the case when the byte at offset 0001h is set to a value of 2.</td></tr>
</tbody></table>
</div>
<h2 id="first-instrument-sub-header"><a class="header" href="#first-instrument-sub-header">FIRST INSTRUMENT SUB-HEADER</a></h2>
<blockquote>
<p>The type <code>int</code> is signed 16-bit integer and it's not 32-bit.</p>
</blockquote>
<div class="table-wrapper"><table><thead><tr><th style="text-align: center">OFFSET</th><th style="text-align: center">Count</th><th style="text-align: center">TYPE</th><th style="text-align: left">Description</th></tr></thead><tbody>
<tr><td style="text-align: center">0003h</td><td style="text-align: center">1</td><td style="text-align: center">int</td><td style="text-align: left">Patch assigned to this instrument sub-header</td></tr>
<tr><td style="text-align: center">0005h</td><td style="text-align: center">1</td><td style="text-align: center">char</td><td style="text-align: left">Amplitude and envelope steepness (signed)</td></tr>
<tr><td style="text-align: center">0006h</td><td style="text-align: center">1</td><td style="text-align: center">char</td><td style="text-align: left">Pan (signed; 193 seems to be extreme left and 64 seems to be extreme right)</td></tr>
<tr><td style="text-align: center">0007h</td><td style="text-align: center">1</td><td style="text-align: center">char</td><td style="text-align: left">Coarse tune (signed; measured in semitones)</td></tr>
<tr><td style="text-align: center">0008h</td><td style="text-align: center">1</td><td style="text-align: center">char</td><td style="text-align: left">Fine tune (signed; seems to be measured in increments of 1/256 of a semitone)</td></tr>
<tr><td style="text-align: center">0009h</td><td style="text-align: center">1</td><td style="text-align: center">int</td><td style="text-align: left">Amount of delay before onset of notes (seems to be measured in miliseconds)</td></tr>
<tr><td style="text-align: center">000bh</td><td style="text-align: center">1</td><td style="text-align: center">char</td><td style="text-align: left">Unknown. For tremolo strings and most if not all drum kit percussion, has value of either 1 or 2.</td></tr>
<tr><td style="text-align: center">000ch</td><td style="text-align: center">1</td><td style="text-align: center">char</td><td style="text-align: left">If, in two or more instrument sub-headers, the byte at offset 000ch has the same value, only one of the patches played by those instrument sub-headers can sound simultaneously. Examples of instruments where this is desirable include open/closed hi-hats and open/closed triangles.</td></tr>
</tbody></table>
</div>
<h2 id="second-instrument-sub-header-same-as-first"><a class="header" href="#second-instrument-sub-header-same-as-first">SECOND INSTRUMENT SUB-HEADER (same as first)</a></h2>
<div class="table-wrapper"><table><thead><tr><th style="text-align: center">OFFSET</th><th style="text-align: center">Count</th><th style="text-align: center">TYPE</th><th style="text-align: left">Description</th></tr></thead><tbody>
<tr><td style="text-align: center">000dh</td><td style="text-align: center">1</td><td style="text-align: center">int</td><td style="text-align: left">Patch assigned to this instrument sub-header</td></tr>
<tr><td style="text-align: center">000fh</td><td style="text-align: center">1</td><td style="text-align: center">char</td><td style="text-align: left">Amplitude and envelope steepness (see above)</td></tr>
<tr><td style="text-align: center">0010h</td><td style="text-align: center">1</td><td style="text-align: center">char</td><td style="text-align: left">Pan</td></tr>
<tr><td style="text-align: center">0011h</td><td style="text-align: center">1</td><td style="text-align: center">char</td><td style="text-align: left">Coarse tune</td></tr>
<tr><td style="text-align: center">0012h</td><td style="text-align: center">1</td><td style="text-align: center">char</td><td style="text-align: left">Fine tune</td></tr>
<tr><td style="text-align: center">0013h</td><td style="text-align: center">1</td><td style="text-align: center">int</td><td style="text-align: left">Delay</td></tr>
<tr><td style="text-align: center">0015h</td><td style="text-align: center">1</td><td style="text-align: center">char</td><td style="text-align: left">Unknown. For side stick and acoustic snare, has value of 1.</td></tr>
<tr><td style="text-align: center">0016h</td><td style="text-align: center">1</td><td style="text-align: center">char</td><td style="text-align: left">Probably same function as byte at offset 0000ch</td></tr>
</tbody></table>
</div>
<p>When the byte at offset 0000h of an instrument header has a value of 255, the
rest of the header is arranged as follows:</p>
<div class="table-wrapper"><table><thead><tr><th style="text-align: center">OFFSET</th><th style="text-align: center">Count</th><th style="text-align: center">TYPE</th><th style="text-align: left">Description</th></tr></thead><tbody>
<tr><td style="text-align: center">0001h</td><td style="text-align: center">1</td><td style="text-align: center">char</td><td style="text-align: left">Unknown.</td></tr>
<tr><td style="text-align: center">0002h</td><td style="text-align: center">1</td><td style="text-align: center">int</td><td style="text-align: left">The number of another instrument header.</td></tr>
<tr><td style="text-align: center">0004h</td><td style="text-align: center">1</td><td style="text-align: center">char</td><td style="text-align: left">When a MIDI note is played with a note number less than or equal to the value of this byte, the instrument header specified by the value at offset 0002h is used. (One can think of these bytes as IF-GOTO statements: IF the note number <= the value at offset 0004h, GOTO instrument header #X, where X is the value stored at offset 0002h.)</td></tr>
<tr><td style="text-align: center">0005h</td><td style="text-align: center">1</td><td style="text-align: center">int</td><td style="text-align: left">The number of another instrument header.</td></tr>
<tr><td style="text-align: center">0007h</td><td style="text-align: center">1</td><td style="text-align: center">char</td><td style="text-align: left">When a MIDI note is played with a note number less than or equal to the value of this byte, the instrument header specified by the value at offset 0005h is used.</td></tr>
<tr><td style="text-align: center">0008h</td><td style="text-align: center">1</td><td style="text-align: center">int</td><td style="text-align: left">The number of another instrument header.</td></tr>
<tr><td style="text-align: center">000ah</td><td style="text-align: center">1</td><td style="text-align: center">char</td><td style="text-align: left">When a MIDI note is played with a note number less than or equal to the value of this byte, the instrument header specified by the value at offset 0008h is used.</td></tr>
<tr><td style="text-align: center">000bh</td><td style="text-align: center">1</td><td style="text-align: center">int</td><td style="text-align: left">The number of another instrument header.</td></tr>
<tr><td style="text-align: center">000dh</td><td style="text-align: center">1</td><td style="text-align: center">char</td><td style="text-align: left">When a MIDI note is played with a note number less than or equal to the value of this byte, the instrument header specified by the value at offset 000bh is used.</td></tr>
<tr><td style="text-align: center">...</td><td style="text-align: center">...</td><td style="text-align: center">...</td><td style="text-align: left">...</td></tr>
<tr><td style="text-align: center">0014h</td><td style="text-align: center">1</td><td style="text-align: center">int</td><td style="text-align: left">The number of another instrument header.</td></tr>
<tr><td style="text-align: center">0016h</td><td style="text-align: center">1</td><td style="text-align: center">char</td><td style="text-align: left">When a MIDI note is played with a note number less than or equal to the value of this byte, the instrument header specified by the value at offset 0014h is used. (The value here MUST be 127.)</td></tr>
</tbody></table>
</div>
<p>If there are multiple instrument headers (according to the file header), then the instrument headers must follow one another immediately with no gaps between.</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="patch-headers"><a class="header" href="#patch-headers">Patch Headers</a></h1>
<p>The patch headers (which refers to the INTERNAL patches used in the waveset, as opposed to MIDI patches, which are EXTERNAL) assign one "cubbyhole" in array #1 to each patch. The patch headers also affect certain properties of the patches, such as the pitch and amplitude envelopes. The number of patch headers is set in the .ECW file header. Each patch header is 76 bytes long.</p>
<div class="table-wrapper"><table><thead><tr><th style="text-align: center">OFFSET</th><th style="text-align: right">Count</th><th style="text-align: center">TYPE</th><th style="text-align: left">Description</th></tr></thead><tbody>
<tr><td style="text-align: center">0000h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Magnitude of pitch envelope (signed). Negative values cause pitch to fall rather than rise. A value of 0 effectively disables pitch envelope.</td></tr>
<tr><td style="text-align: center">0001h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">MIDI controller 1 (modulation) sensitivity</td></tr>
<tr><td style="text-align: center">0002h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Scale. A value of 0 denotes a 12-tones-per-octave (i.e. chromatic) scale. A value of 1 causes this patch to ignore the MIDI note number, so that every key on the keyboard is the same pitch. A value of 2 denotes a 24- tones-per-octave (i.e. quarter tone) scale.</td></tr>
<tr><td style="text-align: center">0003h</td><td style="text-align: right">8</td><td style="text-align: center">string</td><td style="text-align: left">Unknown</td></tr>
<tr><td style="text-align: center">000bh</td><td style="text-align: right">1</td><td style="text-align: center">int</td><td style="text-align: left">"Cubbyhole" in array #1 assigned to this patch</td></tr>
<tr><td style="text-align: center">000dh</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Changes tuning slightly</td></tr>
<tr><td style="text-align: center">000eh</td><td style="text-align: right">2</td><td style="text-align: center">string</td><td style="text-align: left">Unknown</td></tr>
<tr><td style="text-align: center">0010h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Shifts the split points of the samples played by this patch</td></tr>
<tr><td style="text-align: center">0011h</td><td style="text-align: right">10</td><td style="text-align: center">string</td><td style="text-align: left">Unknown</td></tr>
<tr><td style="text-align: center">001bh</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Causes pitch to change more rapidly upon note release when pitch envelope is enabled. May be the destination of the release phase of the pitch envelope.</td></tr>
<tr><td style="text-align: center">001ch</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Delay before pitch envelope enters attack phase</td></tr>
<tr><td style="text-align: center">001dh</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Initial pitch for pitch envelope. Most if not all of the values dealing with the envelopes are unsigned and confined to values between 0 and 127. Using values between 128 and 255 typically generates unpredictable results.</td></tr>
<tr><td style="text-align: center">001eh</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Attack time for pitch envelope</td></tr>
<tr><td style="text-align: center">001fh</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Attack level for pitch envelope</td></tr>
<tr><td style="text-align: center">0020h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Decay time for pitch envelope</td></tr>
<tr><td style="text-align: center">0021h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Decay level for pitch envelope</td></tr>
<tr><td style="text-align: center">0022h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Sustain time for pitch envelope</td></tr>
<tr><td style="text-align: center">0023h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Sustain level for pitch envelope</td></tr>
<tr><td style="text-align: center">0024h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Release time for pitch envelope</td></tr>
<tr><td style="text-align: center">0025h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Influence of MIDI note velocity on magnitude of pitch envelope</td></tr>
<tr><td style="text-align: center">0026h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Unknown (may be proportional to attack time of pitch envelope)</td></tr>
<tr><td style="text-align: center">0027h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Influence of MIDI note number on pitch envelope time (0=none; 127=huge)</td></tr>
<tr><td style="text-align: center">0028h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">When set to 0, the pitch envelope enters the release phase when a MIDI note-off command is received. When set to 1, pitch envelope never enters the release phase.</td></tr>
<tr><td style="text-align: center">0029h</td><td style="text-align: right">2</td><td style="text-align: center">string</td><td style="text-align: left">Unknown</td></tr>
<tr><td style="text-align: center">002bh</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Delay before wavetable envelope enters attack phase. Seems to play the final wavetable while in this pre-attack phase. The "wavetable envelope" transitions from one sample in a sample set to another. This is useful in creating evolving timbres without using long samples. This only seems to work with the "ELEC PIANO 2" (simulates decay of the upper partials) and "SAWTOOTH" (simulates a sweeping resonant filter) sample sets, however; I'm not sure why it doesn't do the same with any sample set.</td></tr>
<tr><td style="text-align: center">002ch</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Initial wavetable for wavetable envelope</td></tr>
<tr><td style="text-align: center">002dh</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Attack time for wavetable envelope</td></tr>
<tr><td style="text-align: center">002eh</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Attack level for wavetable envelope</td></tr>
<tr><td style="text-align: center">002fh</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Decay time for wavetable envelope</td></tr>
<tr><td style="text-align: center">0030h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Decay level for wavetable envelope</td></tr>
<tr><td style="text-align: center">0031h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Sustain time for wavetable envelope</td></tr>
<tr><td style="text-align: center">0032h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Sustain level for wavetable envelope</td></tr>
<tr><td style="text-align: center">0033h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Release time for wavetable envelope</td></tr>
<tr><td style="text-align: center">0034h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Presumably influence of MIDI note velocity on magnitude of wavetable envelope (I haven't tested this)</td></tr>
<tr><td style="text-align: center">0035h</td><td style="text-align: right">1</td><td style="text-align: center">string</td><td style="text-align: left">Unknown</td></tr>
<tr><td style="text-align: center">0036h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Presumably influence of MIDI note number on wavetable envelope time (I haven't tested this)</td></tr>
<tr><td style="text-align: center">0037h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Presumably, when set to 0, the wavetable envelope enters the release phase when a MIDI note-off command is received; when set to 1, wavetable envelope never enters the release phase (I haven't tested this)</td></tr>
<tr><td style="text-align: center">0038h</td><td style="text-align: right">1</td><td style="text-align: center">string</td><td style="text-align: left">Unknown</td></tr>
<tr><td style="text-align: center">0039h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Possibly the destination of the release phase of the amplitude envelope.</td></tr>
<tr><td style="text-align: center">003ah</td><td style="text-align: right">1</td><td style="text-align: center">string</td><td style="text-align: left">Unknown</td></tr>
<tr><td style="text-align: center">003bh</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Initial amplitude for amplitude envelope**</td></tr>
<tr><td style="text-align: center">003ch</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Attack time for amplitude envelope</td></tr>
<tr><td style="text-align: center">003dh</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Attack level for amplitude envelope</td></tr>
<tr><td style="text-align: center">003eh</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Decay time for amplitude envelope</td></tr>
<tr><td style="text-align: center">003fh</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Decay level for amplitude envelope</td></tr>
<tr><td style="text-align: center">0040h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Sustain time for amplitude envelope</td></tr>
<tr><td style="text-align: center">0041h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Sustain level for amplitude envelope</td></tr>
<tr><td style="text-align: center">0042h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Release time for amplitude envelope</td></tr>
<tr><td style="text-align: center">0043h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Influence of MIDI note velocity on magnitude of amplitude envelope.</td></tr>
<tr><td style="text-align: center">0044h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Unknown. Seems to affect amplitude attack.</td></tr>
<tr><td style="text-align: center">0045h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Influence of MIDI note number on amplitude envelope time.</td></tr>
<tr><td style="text-align: center">0046h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">When set to 0, the amplitude envelope enters the release phase when a MIDI note-off command is received. When set to 1, amplitude envelope never enters the release phase.</td></tr>
<tr><td style="text-align: center">0047h</td><td style="text-align: right">1</td><td style="text-align: center">string</td><td style="text-align: left">Unknown</td></tr>
<tr><td style="text-align: center">0048h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Pitch LFO (i.e. vibrato) depth. A value above 0 will add pitch modulation to a patch even when MIDI controller 1 (modulation) is set to 0.</td></tr>
<tr><td style="text-align: center">0049h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Pitch LFO (i.e. vibrato) speed.</td></tr>
<tr><td style="text-align: center">004ah</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Delay before pitch LFO (i.e. vibrato) reaches full depth.</td></tr>
<tr><td style="text-align: center">004bh</td><td style="text-align: right">1</td><td style="text-align: center">string</td><td style="text-align: left">Unknown</td></tr>
</tbody></table>
</div><div style="break-before: page; page-break-before: always;"></div><h1 id="array-1-cubbyholes"><a class="header" href="#array-1-cubbyholes">Array #1 "Cubbyholes"</a></h1>
<p>The "cubbyholes" in array #1 assign one "cubbyhole" in array #3 to each "cubbyhole" in array #1. The number of "cubbyholes" in array #1 is set in the .ECW file header.</p>
<h2 id="cubbyhole-0"><a class="header" href="#cubbyhole-0">"CUBBYHOLE" #0:</a></h2>
<div class="table-wrapper"><table><thead><tr><th>OFFSET</th><th>Count</th><th>TYPE</th><th>Description</th></tr></thead><tbody>
<tr><td>0000h</td><td>1</td><td>int</td><td>"Cubbyhole" in array #3 assigned to this "cubbyhole".</td></tr>
</tbody></table>
</div>
<p>If there are multiple "cubbyholes" (according to the file header), then the "cubbyholes" must follow one another immediately with no gaps between.</p>
<h2 id="cubbyhole-1"><a class="header" href="#cubbyhole-1">"CUBBYHOLE" #1:</a></h2>
<div class="table-wrapper"><table><thead><tr><th>OFFSET</th><th>Count</th><th>TYPE</th><th>Description</th></tr></thead><tbody>
<tr><td>0002h</td><td>1</td><td>int</td><td>"Cubbyhole" in array #3 assigned to this "cubbyhole".</td></tr>
</tbody></table>
</div>
<h2 id="cubbyhole-2"><a class="header" href="#cubbyhole-2">"CUBBYHOLE" #2:</a></h2>
<div class="table-wrapper"><table><thead><tr><th>OFFSET</th><th>Count</th><th>TYPE</th><th>Description</th></tr></thead><tbody>
<tr><td>0004h</td><td>1</td><td>int</td><td>"Cubbyhole" in array #3 assigned to this "cubbyhole".</td></tr>
</tbody></table>
</div>
<p>etc.</p>
<hr />
<h1 id="array-2-cubbyholes"><a class="header" href="#array-2-cubbyholes">Array #2 "Cubbyholes"</a></h1>
<p>The "cubbyholes" in array #2 are linked to the sample set info area. The number of "cubbyholes" in array #2 is set in the .ECW file header.</p>
<h2 id="cubbyhole-0-1"><a class="header" href="#cubbyhole-0-1">"CUBBYHOLE" #0:</a></h2>
<div class="table-wrapper"><table><thead><tr><th>OFFSET</th><th>Count</th><th>TYPE</th><th>Description</th></tr></thead><tbody>
<tr><td>0000h</td><td>1</td><td>int</td><td>Corresponds to value in sample set header. The values tend to be extremely random, as if to thwart reverse engineering of the .ecw file format. (Also seems to affect snare drums in the 2 megabyte official waveset.)</td></tr>
</tbody></table>
</div>
<p>If there are multiple "cubbyholes" (according to the file header), then the "cubbyholes" must follow one another immediately with no gaps between.</p>
<h2 id="cubbyhole-1-1"><a class="header" href="#cubbyhole-1-1">"CUBBYHOLE" #1:</a></h2>
<div class="table-wrapper"><table><thead><tr><th>OFFSET</th><th>Count</th><th>TYPE</th><th>Description</th></tr></thead><tbody>
<tr><td>0002h</td><td>1</td><td>int</td><td>Corresponds to value in sample set header. The values tend to be extremely random, as if to thwart reverse engineering of the .ecw file format. (Also seems to affect snare drums in the 2 megabyte official waveset.)</td></tr>
</tbody></table>
</div>
<h2 id="cubbyhole-2-1"><a class="header" href="#cubbyhole-2-1">"CUBBYHOLE" #2:</a></h2>
<div class="table-wrapper"><table><thead><tr><th>OFFSET</th><th>Count</th><th>TYPE</th><th>Description</th></tr></thead><tbody>
<tr><td>0004h</td><td>1</td><td>int</td><td>Corresponds to value in sample set header. The values tend to be extremely random, as if to thwart reverse engineering of the .ecw file format. (Also seems to affect snare drums in the 2 megabyte official waveset.)</td></tr>
</tbody></table>
</div>
<p>etc.</p>
<hr />
<h1 id="array-3-cubbyholes"><a class="header" href="#array-3-cubbyholes">Array #3 "Cubbyholes"</a></h1>
<p>The "cubbyholes" in array #3 assign one sample header to each "cubbyhole" in array #3. The number of "cubbyholes" in array #3 is set in the .ECW file header.</p>
<h2 id="cubbyhole-0-2"><a class="header" href="#cubbyhole-0-2">"CUBBYHOLE" #0:</a></h2>
<div class="table-wrapper"><table><thead><tr><th>OFFSET</th><th>Count</th><th>TYPE</th><th>Description</th></tr></thead><tbody>
<tr><td>0000h</td><td>1</td><td>int</td><td>Sample header assigned to this "cubbyhole".</td></tr>
</tbody></table>
</div>
<p>If there are multiple "cubbyholes" (according to the file header), then the
"cubbyholes" must follow one another immediately with no gaps between.</p>
<h2 id="cubbyhole-1-2"><a class="header" href="#cubbyhole-1-2">"CUBBYHOLE" #1:</a></h2>
<div class="table-wrapper"><table><thead><tr><th>OFFSET</th><th>Count</th><th>TYPE</th><th>Description</th></tr></thead><tbody>
<tr><td>0002h</td><td>1</td><td>int</td><td>Sample header assigned to this "cubbyhole".</td></tr>
</tbody></table>
</div>
<h2 id="cubbyhole-2-2"><a class="header" href="#cubbyhole-2-2">"CUBBYHOLE" #2:</a></h2>
<div class="table-wrapper"><table><thead><tr><th>OFFSET</th><th>Count</th><th>TYPE</th><th>Description</th></tr></thead><tbody>
<tr><td>0004h</td><td>1</td><td>int</td><td>Sample header assigned to this "cubbyhole".</td></tr>
</tbody></table>
</div>
<p>etc.</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="sample-headers"><a class="header" href="#sample-headers">Sample Headers</a></h1>
<p>The sample headers indicate where the individual samples are to be found in the sample waveform area. They also specify how those samples are looped (if at all), and any split points between one sample and another. The number of sample headers is set in the .ECW file header. Each sample header is 16 bytes long.</p>
<div class="table-wrapper"><table><thead><tr><th style="text-align: center">OFFSET</th><th style="text-align: right">Count</th><th style="text-align: center">TYPE</th><th style="text-align: left">Description</th></tr></thead><tbody>
<tr><td style="text-align: center">0000h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">If a MIDI note is received with a MIDI note number above this value, the next sample header is used instead. If the MIDI note number is still greater than the byte value at offset 0000h of the next sample header, the sample header after the next sample header is used and so on until the MIDI note number is less than or equal to the byte value at offset 0000h.</td></tr>
<tr><td style="text-align: center">0001h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Determines whether the sample is looped, whether to apply tuning adjustments from patch and instrument headers when the sample is used as part of a drum kit, and whether to shift loop points further into the sample waveform area. When set to 0, no tuning adjustments are made when the sample is used in a drum kit. A value of 0 or 1 also disables looping. Values of 2 or higher enable looping using the loop points specified in the sample header (see below). Values of 129 or higher shift the loop points forward by an amount proportional to the value minus 128 (i.e. 129 will shift the loop points slightly, while 255 will shift them quite far into the sample waveform area). Be careful when experimenting with values over 129 as it is very possible to play past the end of the sample waveform area, which may cause Windows to crash.</td></tr>
<tr><td style="text-align: center">0002h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Fine tune (signed; seems to be in increments of 1/256 of a semitone)</td></tr>
<tr><td style="text-align: center">0003h</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Coarse tune (signed; measured in semitones)</td></tr>
<tr><td style="text-align: center">0004h</td><td style="text-align: right">1</td><td style="text-align: center">dword</td><td style="text-align: left">Offset in sample waveform area where this sample begins, multiplied by 8. Sample waveform data can be shared by multiple sample headers.</td></tr>
<tr><td style="text-align: center">0008h</td><td style="text-align: right">1</td><td style="text-align: center">dword</td><td style="text-align: left">Offset in sample waveform area of this sample's loop point, multiplied by 8.</td></tr>
<tr><td style="text-align: center">000bh</td><td style="text-align: right">1</td><td style="text-align: center">dword</td><td style="text-align: left">Offset in sample waveform area of this sample's end loop point, multiplied by 8 (fractional loop lengths permitted). This is also where the sample ends when looping is disabled. If a sample plays beyond the end of the file, the operating system may lock up.</td></tr>
</tbody></table>
</div>
<p>If there are multiple sample headers, then the sample headers must follow one another immediately with no gaps between.</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="sample-waveform-area--sample-set-info-area"><a class="header" href="#sample-waveform-area--sample-set-info-area">Sample Waveform Area / Sample Set Info Area</a></h1>
<p>The sample waveform area stores the actual sample waveform data used by the sound card's MIDI synthesizer. The sample waveform data is stored using 16-bit, mono, signed samples, with LSB first (Intel byte order). Theoretically, the sample waveform area can be up to 512 megabytes in size (sample start/loop/end loop points in the sample headers) are specified using dwords, which have a maximum value of 2^32 or 4294967296. Diving this value by 8 - the sample start/ loop/end loop points are measured in 1/8 bytes - we get 536870912 bytes, or 512 megabytes. The practical limit, however, is about 16 megabytes--the configurator refuses to load wavesets larger than that. (Perhaps the sound card driver or ENSCFG32.EXE could be hacked to increase the effective file size limit?) The size of the sample waveform area is set in the .ECW file header.</p>
<p>In the wavesets provided by Ensoniq/Creative, the beginning of the sample waveform area is not used to store samples. Rather, it contains the names of each sample set in the remainder of the sample waveform area and other data pertaining to these sample sets (here, "sample sets" means a single sample or multiple samples if the split point for a sample--i.e. the byte in offset 0 of a sample header--is less than 127, in which case the sample set would "continue" to the following sample until a value of 127 was reached.) This section does not seem to be needed for playback by the AudioPCI's softsynth, as changing the values of this section has little if any effect. I speculate that this area of the .ecw file was used by the proprietary software that Ensoniq/Creative used for designing the official wavesets, for displaying names for each sample set and such. I also speculate that the entire sample waveform area was at one point an Ensoniq file type itself, as the structure of the sample waveform area (as it exists in the wavesets provided by Ensoniq/Creative) resembles an independent file.</p>
<p>The beginning of the sample waveform area in the official .ecw files, which I will call the "Sample Set Info Area", has the following layout:</p>
<div class="table-wrapper"><table><thead><tr><th style="text-align: center">OFFSET</th><th style="text-align: right">Count</th><th style="text-align: center">TYPE</th><th style="text-align: left">Description</th></tr></thead><tbody>
<tr><td style="text-align: center">0000h</td><td style="text-align: right">4</td><td style="text-align: center">string</td><td style="text-align: left">Unknown (value of 16 in all wavesets provided by Ensoniq/Creative)</td></tr>
<tr><td style="text-align: center">0004h</td><td style="text-align: right">1</td><td style="text-align: center">dword</td><td style="text-align: left">Size of sample waveform area in bytes</td></tr>
<tr><td style="text-align: center">0008h</td><td style="text-align: right">4</td><td style="text-align: center">string</td><td style="text-align: left">Unknown (always "RDNS")</td></tr>
<tr><td style="text-align: center">000ch</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Unknown (always 14--length of sample set names?)</td></tr>
<tr><td style="text-align: center">000dh</td><td style="text-align: right">1</td><td style="text-align: center">char</td><td style="text-align: left">Always 22--probably length in bytes of each sample set header</td></tr>
<tr><td style="text-align: center">000eh</td><td style="text-align: right">1</td><td style="text-align: center">int</td><td style="text-align: left">Always 16--probably length in bytes of each sample header in duplicate copy of Sample Headers</td></tr>
<tr><td style="text-align: center">0010h</td><td style="text-align: right">1</td><td style="text-align: center">int</td><td style="text-align: left">Always 40--probably offset where first sample set header begins</td></tr>
<tr><td style="text-align: center">0012h</td><td style="text-align: right">1</td><td style="text-align: center">int</td><td style="text-align: left">Offset in sample waveform area where sample set headers begin</td></tr>
<tr><td style="text-align: center">0014h</td><td style="text-align: right">1</td><td style="text-align: center">int</td><td style="text-align: left">Size of duplicate copy of Sample Headers in bytes</td></tr>
<tr><td style="text-align: center">0016h</td><td style="text-align: right">1</td><td style="text-align: center">int</td><td style="text-align: left">Number of sample sets</td></tr>
<tr><td style="text-align: center">0018h</td><td style="text-align: right">1</td><td style="text-align: center">int</td><td style="text-align: left">Number of sample headers</td></tr>
<tr><td style="text-align: center">001ah</td><td style="text-align: right">14</td><td style="text-align: center">string</td><td style="text-align: left">Unknown. <code>"ENSONIQ ROM[null][null][null]"</code> in DOSTEST.ECW; <code>"[null]NSONIQ ROM[null][null][null]"</code> in all other wavesets provided by Ensoniq/Creative</td></tr>
</tbody></table>
</div>
<h2 id="sample-set-header-1"><a class="header" href="#sample-set-header-1">"SAMPLE SET HEADER" #1:</a></h2>
<div class="table-wrapper"><table><thead><tr><th style="text-align: center">OFFSET</th><th style="text-align: right">Count</th><th style="text-align: center">TYPE</th><th style="text-align: left">Description</th></tr></thead><tbody>
<tr><td style="text-align: center">0028h</td><td style="text-align: right">1</td><td style="text-align: center">dword</td><td style="text-align: left">Offset in the Sample Waveform Area where sample header for the first sample in this sample set is stored</td></tr>
<tr><td style="text-align: center">002ch</td><td style="text-align: right">1</td><td style="text-align: center">int</td><td style="text-align: left">Corresponds to a "cubbyhole" number in array #1</td></tr>
<tr><td style="text-align: center">002eh</td><td style="text-align: right">1</td><td style="text-align: center">int</td><td style="text-align: left">Corresponds to a value in array #2</td></tr>
<tr><td style="text-align: center">0030h</td><td style="text-align: right">14</td><td style="text-align: center">string</td><td style="text-align: left">Name of this sample set. Null-terminated string.</td></tr>
</tbody></table>
</div>
<p>If there are multiple sample set headers (according to the value at offset 0x16 of the sample waveform area), then the sample set headers must follow one another immediately with no gaps between.</p>
<h2 id="sample-set-header-2"><a class="header" href="#sample-set-header-2">"SAMPLE SET HEADER" #2:</a></h2>
<div class="table-wrapper"><table><thead><tr><th style="text-align: center">OFFSET</th><th style="text-align: right">Count</th><th style="text-align: center">TYPE</th><th style="text-align: left">Description</th></tr></thead><tbody>
<tr><td style="text-align: center">003eh</td><td style="text-align: right">1</td><td style="text-align: center">dword</td><td style="text-align: left">Offset in the Sample Waveform Area where sample header for the first sample in this sample set is stored</td></tr>
<tr><td style="text-align: center">0042h</td><td style="text-align: right">1</td><td style="text-align: center">int</td><td style="text-align: left">Corresponds to a "cubbyhole" number in array #1</td></tr>
<tr><td style="text-align: center">0044h</td><td style="text-align: right">1</td><td style="text-align: center">int</td><td style="text-align: left">Corresponds to a value in array #2</td></tr>
<tr><td style="text-align: center">0046h</td><td style="text-align: right">14</td><td style="text-align: center">string</td><td style="text-align: left">Name of this sample set. Null-terminated string.</td></tr>
</tbody></table>
</div>
<h2 id="sample-set-header-3"><a class="header" href="#sample-set-header-3">"SAMPLE SET HEADER" #3:</a></h2>
<div class="table-wrapper"><table><thead><tr><th style="text-align: center">OFFSET</th><th style="text-align: right">Count</th><th style="text-align: center">TYPE</th><th style="text-align: left">Description</th></tr></thead><tbody>
<tr><td style="text-align: center">0054h</td><td style="text-align: right">1</td><td style="text-align: center">dword</td><td style="text-align: left">Offset in the Sample Waveform Area where sample header for the first sample in this sample set is stored</td></tr>
<tr><td style="text-align: center">0058h</td><td style="text-align: right">1</td><td style="text-align: center">int</td><td style="text-align: left">Corresponds to a "cubbyhole" number in array #1</td></tr>
<tr><td style="text-align: center">005ah</td><td style="text-align: right">1</td><td style="text-align: center">int</td><td style="text-align: left">Corresponds to a value in array #2</td></tr>
<tr><td style="text-align: center">005ch</td><td style="text-align: right">14</td><td style="text-align: center">string</td><td style="text-align: left">Name of this sample set. Null-terminated string.</td></tr>
</tbody></table>
</div>
<p>etc.</p>
<hr />
<p>A duplicate copy of the Sample Headers follows the "Sample Set Headers". The actual sample waveform data seems to begin immediately afterward.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
</nav>
</div>
<!-- Livereload script (if served using the cli tool) -->
<script>
const wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
const wsAddress = wsProtocol + "//" + location.host + "/" + "__livereload";
const socket = new WebSocket(wsAddress);
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
<script>
window.playground_copyable = true;
</script>
<script src="elasticlunr.min.js"></script>
<script src="mark.min.js"></script>
<script src="searcher.js"></script>
<script src="clipboard.min.js"></script>
<script src="highlight.js"></script>
<script src="book.js"></script>
<!-- Custom JS scripts -->
<script>
window.addEventListener('load', function() {
window.setTimeout(window.print, 100);
});
</script>
</div>
</body>
</html>