@karaplay/file-coder 1.5.1 → 1.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,238 @@
1
+ # Release v1.5.2 - High PPQ File Support
2
+
3
+ **Date:** 2026-01-13
4
+ **Type:** Bug Fix
5
+
6
+ ## 🐛 Bug Fix: Incorrect Tempo Ratio for High PPQ Files
7
+
8
+ ### Problem
9
+
10
+ The file `Z2510006.emk` (Move On แบบใด - โจอี้ ภูวศิษฐ์) was incorrectly converted with:
11
+ - **Tempo Ratio:** 20x ❌ (should be 1x)
12
+ - **Duration:** 0:12 (12.83 seconds) ❌ (should be 4:16)
13
+ - **Tempo:** 87 BPM → 1,740 BPM ❌ (should stay 87 BPM)
14
+
15
+ **Root Cause:**
16
+ The system calculated tempo ratio as `PPQ / 24`:
17
+ - Z2510006 has `PPQ = 480`
18
+ - Calculated ratio: `480 / 24 = 20x` ❌
19
+ - But this file already has correct tempo and doesn't need adjustment!
20
+
21
+ ### Solution
22
+
23
+ Added special handling for **high PPQ files** (PPQ >= 480):
24
+
25
+ ```typescript
26
+ if (isZxioFormat) {
27
+ ratio = ticksPerBeat / 77.42; // ZXIO: 1.24x
28
+ } else if (ticksPerBeat >= 480) {
29
+ ratio = 1.0; // High PPQ: No adjustment needed ✅
30
+ } else {
31
+ ratio = ticksPerBeat / 24; // Standard MThd: 4x, 8x, etc.
32
+ }
33
+ ```
34
+
35
+ ### Results
36
+
37
+ **Before Fix:**
38
+ ```
39
+ Move On แบบใด (Z2510006.emk):
40
+ - Tempo: 87 → 1,740 BPM (20x) ❌
41
+ - Duration: 0:12 ❌
42
+ - Status: Incorrect
43
+ ```
44
+
45
+ **After Fix:**
46
+ ```
47
+ Move On แบบใด (Z2510006.emk):
48
+ - Tempo: 87 → 87 BPM (1x) ✅
49
+ - Duration: 4:16 ✅
50
+ - Matches reference KAR: 100% ✅
51
+ ```
52
+
53
+ ---
54
+
55
+ ## 📊 Impact
56
+
57
+ ### Files Affected
58
+
59
+ **Z2510006.emk only:**
60
+ - This is the only file in our test set with PPQ >= 480
61
+ - Other files (PPQ < 480) are not affected
62
+ - All 9/9 tests pass ✅
63
+
64
+ ### Tempo Ratio Distribution (Updated)
65
+
66
+ | Ratio | Format | Count | Files |
67
+ |-------|--------|-------|-------|
68
+ | 1.00x | MThd (High PPQ) | 1 | Z2510006 ✅ **NEW** |
69
+ | 1.24x | ZXIO | 3 | 001, 001_original, failed01 |
70
+ | 4.00x | MThd | 4 | Z2510001, Z2510002, Z2510004, Z2510005 |
71
+ | 8.00x | MThd | 1 | Z2510003 |
72
+
73
+ **Old (incorrect):**
74
+ - 20x: 1 file ❌ (removed)
75
+
76
+ ---
77
+
78
+ ## ✅ Testing
79
+
80
+ ### Test Results
81
+
82
+ ```
83
+ $ npm run test:emk
84
+
85
+ ✅ Passed: 9/9
86
+ ⚠️ Warnings: 0/9
87
+ ❌ Failed: 0/9
88
+
89
+ 🎉 All tests passed!
90
+ ```
91
+
92
+ ### Specific Test: Z2510006
93
+
94
+ ```
95
+ Testing: Z2510006.emk
96
+ ✅ PASS: All checks passed
97
+
98
+ Comparison with Reference KAR:
99
+ Converted Tempo: 87.00 BPM
100
+ Reference Tempo: 87.00 BPM
101
+ Match: YES ✅
102
+
103
+ Converted Duration: 256.64 s (4:16)
104
+ Reference Duration: 256.64 s (4:16)
105
+ Difference: 0.00 s
106
+ Match: YES ✅
107
+ ```
108
+
109
+ ---
110
+
111
+ ## 📝 Changed Files
112
+
113
+ ### Core Library
114
+
115
+ 1. **src/ncntokar.ts**
116
+ - Updated `fixEmkMidiTempo()` function
117
+ - Added PPQ >= 480 check
118
+
119
+ 2. **src/ncntokar.browser.ts**
120
+ - Updated `fixEmkMidiTempoBrowser()` function
121
+ - Same PPQ >= 480 logic
122
+
123
+ ### Documentation
124
+
125
+ 3. **EMK_REFERENCE_DATA.json**
126
+ - Updated Z2510006 expected values
127
+ - Tempo: 1740 → 87 BPM
128
+ - Duration: 12.83 → 256.64s
129
+ - Ratio: 20x → 1x
130
+
131
+ 4. **SONG_LIST.txt**
132
+ - Updated Z2510006 information
133
+ - Fixed duration statistics
134
+
135
+ ---
136
+
137
+ ## 🚀 Migration
138
+
139
+ ### From v1.5.1 to v1.5.2
140
+
141
+ **No Breaking Changes!**
142
+
143
+ Simply update:
144
+
145
+ ```bash
146
+ npm install @karaplay/file-coder@1.5.2
147
+ ```
148
+
149
+ **All existing code continues to work.**
150
+
151
+ ### What Changed
152
+
153
+ If you were converting `Z2510006.emk` or similar files with PPQ >= 480:
154
+
155
+ **Before (v1.5.1):**
156
+ ```typescript
157
+ // Would produce incorrect 12-second file
158
+ convertEmkToKar({
159
+ inputEmk: 'Z2510006.emk',
160
+ outputKar: 'output.kar'
161
+ });
162
+ // Duration: 0:12 ❌
163
+ ```
164
+
165
+ **After (v1.5.2):**
166
+ ```typescript
167
+ // Now produces correct 4:16 file
168
+ convertEmkToKar({
169
+ inputEmk: 'Z2510006.emk',
170
+ outputKar: 'output.kar'
171
+ });
172
+ // Duration: 4:16 ✅
173
+ ```
174
+
175
+ ---
176
+
177
+ ## 🎓 Technical Details
178
+
179
+ ### PPQ (Pulses Per Quarter Note)
180
+
181
+ **Common PPQ Values:**
182
+ - 96: Standard (ratio = 96/24 = 4x)
183
+ - 120: Standard (ratio = 120/24 = 5x)
184
+ - 480: High resolution (ratio = 1x, no conversion needed)
185
+
186
+ **Why PPQ 480 is different:**
187
+ - Higher temporal resolution
188
+ - Usually means the file is already properly timed
189
+ - Common in professional MIDI editors
190
+ - Doesn't need our EMK tempo correction
191
+
192
+ ### Detection Logic
193
+
194
+ ```typescript
195
+ // ZXIO: Always 1.24x
196
+ if (isZxioFormat) {
197
+ return ticksPerBeat / 77.42;
198
+ }
199
+
200
+ // High PPQ: No conversion
201
+ if (ticksPerBeat >= 480) {
202
+ return 1.0; // ← NEW in v1.5.2
203
+ }
204
+
205
+ // Standard MThd: Calculate ratio
206
+ return ticksPerBeat / 24;
207
+ ```
208
+
209
+ ---
210
+
211
+ ## 📚 Documentation
212
+
213
+ ### Updated Documentation
214
+
215
+ - [SONG_LIST.txt](./SONG_LIST.txt) - Corrected Z2510006 info
216
+ - [EMK_REFERENCE_DATA.json](./EMK_REFERENCE_DATA.json) - Updated test data
217
+ - [RELEASE_v1.5.2.md](./RELEASE_v1.5.2.md) - This file
218
+
219
+ ### Related Documentation
220
+
221
+ - [TEMPO_TRICKS_SUMMARY.md](./TEMPO_TRICKS_SUMMARY.md) - Tempo handling guide
222
+ - [EMK_TEST_SUITE_README.md](./EMK_TEST_SUITE_README.md) - Test suite guide
223
+ - [EMK_SONGS_INFO.md](./EMK_SONGS_INFO.md) - Song information
224
+
225
+ ---
226
+
227
+ ## ✨ Summary
228
+
229
+ **Fixed:** Z2510006.emk now converts correctly with proper 4:16 duration
230
+ **Added:** Support for high PPQ files (PPQ >= 480)
231
+ **Status:** All 9/9 tests pass ✅
232
+ **Breaking:** None - fully backward compatible
233
+
234
+ ---
235
+
236
+ **Recommended Action:** Update to v1.5.2 if you're converting files with high PPQ values.
237
+
238
+ **npm:** https://www.npmjs.com/package/@karaplay/file-coder
@@ -0,0 +1,274 @@
1
+ # Release v1.5.3 - Corrupted MIDI Repair
2
+
3
+ **Date:** 2026-01-13
4
+ **Type:** Bug Fix + New Feature
5
+
6
+ ## 🐛 Bug Fix: Corrupted MIDI Track Support
7
+
8
+ ### Problem
9
+
10
+ The file `f0000001.emk` (อีกครั้ง - โลโซ/Loso) failed to convert with:
11
+ - **Error:** "Bad MIDI file. Expected 'MTrk', got: 'iF'" ❌
12
+ - **Cause:** MIDI file had garbage bytes (0x6984461d "iF") instead of valid "MTrk" header at track 3
13
+ - **Result:** Conversion failed with undefined error
14
+
15
+ **Root Cause:**
16
+ Some EMK files contain corrupted MIDI data with garbage bytes inserted before valid track headers, causing MIDI parsers to fail.
17
+
18
+ ### Solution
19
+
20
+ Added automatic MIDI repair functionality:
21
+
22
+ ```typescript
23
+ // New function: repairCorruptedMidi()
24
+ export function repairCorruptedMidi(midiBuffer: Buffer): {
25
+ repaired: Buffer;
26
+ fixed: boolean;
27
+ corrections: number;
28
+ }
29
+ ```
30
+
31
+ **How it works:**
32
+ 1. Scans MIDI file for invalid track headers
33
+ 2. Detects garbage bytes before "MTrk" chunks
34
+ 3. Removes corrupted data
35
+ 4. Rebuilds valid MIDI file automatically
36
+
37
+ ### Results
38
+
39
+ **Before Fix (v1.5.2):**
40
+ ```
41
+ f0000001.emk (อีกครั้ง - โลโซ):
42
+ ❌ Error: Bad MIDI file. Expected 'MTrk', got: 'iF'
43
+ ❌ Status: Cannot convert
44
+ ```
45
+
46
+ **After Fix (v1.5.3):**
47
+ ```
48
+ f0000001.emk (อีกครั้ง - โลโซ):
49
+ ✅ Conversion: SUCCESS!
50
+ ✅ Duration: 0:58 (58.96s)
51
+ ✅ Tempo: 344 BPM (4x ratio)
52
+ ✅ Warning: Fixed 1 corrupted MIDI track(s)
53
+ ```
54
+
55
+ ---
56
+
57
+ ## 📊 Impact
58
+
59
+ ### Conversion Success Rate Improvement
60
+
61
+ **Before v1.5.3:**
62
+ - Total Files: 11
63
+ - Success: 9 (82%)
64
+ - Failed: 2 (18%)
65
+
66
+ **After v1.5.3:**
67
+ - Total Files: 11
68
+ - Success: **10 (91%)** ✅ +9%
69
+ - Failed: 1 (9%)
70
+
71
+ ### Files Status
72
+
73
+ **Fixed:**
74
+ - ✅ `f0000001.emk` (อีกครั้ง - โลโซ) - Now converts successfully!
75
+
76
+ **Still Failed:**
77
+ - ❌ `500006.emk` - Completely corrupted (no zlib blocks), cannot be recovered
78
+
79
+ ---
80
+
81
+ ## 🔧 Technical Details
82
+
83
+ ### Corrupted MIDI Example
84
+
85
+ ```
86
+ Offset Chunk ID Status
87
+ ------ -------- ------
88
+ 14 MTrk ✅ Valid
89
+ 59 MTrk ✅ Valid
90
+ 1431 iF ❌ CORRUPTED! (should be MTrk)
91
+ 1440 MTrk ✅ Valid (found after skipping 9 bytes)
92
+ ...
93
+ ```
94
+
95
+ ### Repair Process
96
+
97
+ ```typescript
98
+ // Automatic repair in convertNcnToKar()
99
+ let midiBuffer: Buffer = fs.readFileSync(options.inputMidi);
100
+ const repairResult = repairCorruptedMidi(midiBuffer);
101
+
102
+ if (repairResult.fixed) {
103
+ midiBuffer = repairResult.repaired as Buffer;
104
+ warnings.push(`Fixed ${repairResult.corrections} corrupted MIDI track(s)`);
105
+ }
106
+ ```
107
+
108
+ **Detection:**
109
+ - Scans for "MTrk" signature (0x4D54726B)
110
+ - When invalid chunk found, searches next 100 bytes for valid "MTrk"
111
+ - Skips garbage bytes and continues
112
+
113
+ **Safety:**
114
+ - Never modifies header (MThd)
115
+ - Preserves all valid tracks
116
+ - Only removes garbage bytes between tracks
117
+ - Returns original if repair fails
118
+
119
+ ---
120
+
121
+ ## 📝 Changed Files
122
+
123
+ ### Core Library
124
+
125
+ 1. **src/ncntokar.ts**
126
+ - Added `repairCorruptedMidi()` function
127
+ - Integrated automatic repair in `convertNcnToKar()`
128
+ - Reports corrupted tracks in warnings
129
+
130
+ 2. **src/index.ts**
131
+ - Exported `repairCorruptedMidi` for external use
132
+
133
+ ### Documentation
134
+
135
+ 3. **SONG_LIST.txt**
136
+ - Added เพลงที่ 10: อีกครั้ง (โลโซ)
137
+ - Updated success rate: 82% → 91%
138
+ - Updated failed files: 2 → 1
139
+
140
+ 4. **RELEASE_v1.5.3.md**
141
+ - This file
142
+
143
+ ---
144
+
145
+ ## 🚀 Migration
146
+
147
+ ### From v1.5.2 to v1.5.3
148
+
149
+ **No Breaking Changes!**
150
+
151
+ Simply update:
152
+
153
+ ```bash
154
+ npm install @karaplay/file-coder@1.5.3
155
+ ```
156
+
157
+ **All existing code continues to work.**
158
+
159
+ ### What Changed
160
+
161
+ If you were trying to convert `f0000001.emk`:
162
+
163
+ **Before (v1.5.2):**
164
+ ```typescript
165
+ convertEmkToKar({
166
+ inputEmk: 'f0000001.emk',
167
+ outputKar: 'output.kar'
168
+ });
169
+ // ❌ Error: Bad MIDI file
170
+ ```
171
+
172
+ **After (v1.5.3):**
173
+ ```typescript
174
+ convertEmkToKar({
175
+ inputEmk: 'f0000001.emk',
176
+ outputKar: 'output.kar'
177
+ });
178
+ // ✅ Success! (with warning about fixed MIDI track)
179
+ ```
180
+
181
+ ---
182
+
183
+ ## 🎯 Use Cases
184
+
185
+ ### When This Fix Helps
186
+
187
+ ✅ **Corrupted Track Headers:**
188
+ - Garbage bytes before MTrk chunks
189
+ - Invalid chunk IDs in MIDI file
190
+ - Malformed track structures
191
+
192
+ ✅ **Automatic Recovery:**
193
+ - No manual intervention needed
194
+ - Transparent to the user
195
+ - Warning message in result
196
+
197
+ ❌ **When It Doesn't Help:**
198
+ - Completely corrupted files (like 500006.emk)
199
+ - Files with no zlib blocks
200
+ - Files that can't be decoded at all
201
+
202
+ ---
203
+
204
+ ## 🧪 Testing
205
+
206
+ ### Test: f0000001.emk
207
+
208
+ ```typescript
209
+ import { convertEmkToKar, validateKarTempo } from '@karaplay/file-coder';
210
+
211
+ const result = convertEmkToKar({
212
+ inputEmk: 'f0000001.emk',
213
+ outputKar: 'output.kar'
214
+ });
215
+
216
+ console.log('Success:', result.success); // true ✅
217
+ console.log('Title:', result.metadata.title); // "14 อีกครั้ง "
218
+ console.log('Artist:', result.metadata.artist); // "โลโซ (Loso)"
219
+ console.log('Warnings:', result.warnings);
220
+ // ["Fixed 1 corrupted MIDI track(s)", ...]
221
+
222
+ const validation = validateKarTempo(karBuffer);
223
+ console.log('Duration:', validation.durationMinutes); // "0:58"
224
+ console.log('Tempo:', validation.tempo); // 344 BPM
225
+ ```
226
+
227
+ ### Manual Repair Test
228
+
229
+ ```typescript
230
+ import { repairCorruptedMidi } from '@karaplay/file-coder';
231
+
232
+ const midiBuffer = fs.readFileSync('corrupted.mid');
233
+ const result = repairCorruptedMidi(midiBuffer);
234
+
235
+ if (result.fixed) {
236
+ console.log('Repaired!');
237
+ console.log('Corrections:', result.corrections);
238
+ fs.writeFileSync('repaired.mid', result.repaired);
239
+ } else {
240
+ console.log('No corruption detected or repair failed');
241
+ }
242
+ ```
243
+
244
+ ---
245
+
246
+ ## 📚 Documentation
247
+
248
+ ### Updated Documentation
249
+
250
+ - [SONG_LIST.txt](./SONG_LIST.txt) - Added f0000001.emk info
251
+ - [RELEASE_v1.5.3.md](./RELEASE_v1.5.3.md) - This file
252
+
253
+ ### Related Documentation
254
+
255
+ - [EMK_TEST_SUITE_README.md](./EMK_TEST_SUITE_README.md) - Test suite guide
256
+ - [TEMPO_TRICKS_SUMMARY.md](./TEMPO_TRICKS_SUMMARY.md) - Tempo handling
257
+ - [RELEASE_v1.5.2.md](./RELEASE_v1.5.2.md) - High PPQ fix
258
+
259
+ ---
260
+
261
+ ## ✨ Summary
262
+
263
+ **Fixed:** f0000001.emk now converts successfully! ✅
264
+ **Added:** Automatic corrupted MIDI repair
265
+ **Improved:** Success rate from 82% to 91%
266
+ **Breaking:** None - fully backward compatible
267
+
268
+ **Remaining Issue:** 500006.emk still cannot be converted (file completely corrupted)
269
+
270
+ ---
271
+
272
+ **Recommended Action:** Update to v1.5.3 to get automatic MIDI repair for corrupted EMK files.
273
+
274
+ **npm:** https://www.npmjs.com/package/@karaplay/file-coder