Subversion Repositories svn.mios32

Rev

Rev 1457 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1453 tk 1
// $Id: mbcv_file_b.c 1653 2013-01-09 23:08:59Z tk $
2
/*
3
 * Bank access functions
4
 *
5
 * NOTE: before accessing the SD Card, the upper level function should
6
 * synchronize with the SD Card semaphore!
7
 *   MUTEX_SDCARD_TAKE; // to take the semaphore
8
 *   MUTEX_SDCARD_GIVE; // to release the semaphore
9
 *
10
 * ==========================================================================
11
 *
12
 *  Copyright (C) 2008 Thorsten Klose (tk@midibox.org)
13
 *  Licensed for personal non-commercial use only.
14
 *  All other rights reserved.
15
 *
16
 * ==========================================================================
17
 */
18
 
19
/////////////////////////////////////////////////////////////////////////////
20
// Include files
21
/////////////////////////////////////////////////////////////////////////////
22
 
23
#include <mios32.h>
24
 
25
#include <string.h>
26
 
27
#include "file.h"
28
#include "mbcv_file.h"
29
#include "mbcv_file_b.h"
30
 
31
#include "mbcv_patch.h"
32
 
33
 
34
 
35
/////////////////////////////////////////////////////////////////////////////
36
// for optional debugging messages via DEBUG_MSG (defined in mios32_config.h)
37
// should be 1 by default to ensure that error messages are print
38
/////////////////////////////////////////////////////////////////////////////
39
#define DEBUG_VERBOSE_LEVEL 1
40
 
41
 
42
/////////////////////////////////////////////////////////////////////////////
43
// Local definitions
44
/////////////////////////////////////////////////////////////////////////////
45
 
46
// in which subdirectory of the SD card are the files located?
47
// use "/" for root
48
// use "/<dir>/" for a subdirectory in root
49
// use "/<dir>/<subdir>/" to reach a subdirectory in <dir>, etc..
50
 
51
#define MBCV_FILES_PATH "/"
52
//#define MBCV_FILES_PATH "/MySongs/"
53
 
54
 
55
// defined locally to avoid usage of C++ constants
56
// TODO: should be overworked
57
#define CV_PATCH_CHANNELS 8
58
#define CV_PATCH_SIZE     0x400 // in halfwords!
59
#define CV_NUM_PATCHES    128
60
 
61
 
62
/////////////////////////////////////////////////////////////////////////////
63
// Local types
64
/////////////////////////////////////////////////////////////////////////////
65
 
66
// Structure of bank file:
67
//    file_type[10]
68
//    mbcv_file_b_header_t
69
//    Patch 0: mbcv_file_b_patch_t
70
//               Channel 0: mbcv_file_b_channel_t
71
//               Channel 1: ...
72
//    Patch 1: ...
73
//
74
// Size for 128 patches
75
// each consists of 0x400 halfwords = 0x800 bytes (2k)
76
// 10 + 24 + 128 * (24 + 8 * 2048)
77
// 10 + 24 + 128 * 16408
78
// 10 + 24 + 2100224
79
// -> 2100258 bytes (good that SD cards are so cheap today ;)
80
 
81
// not defined as structure: 
82
// file_type[10] will contain "MBCV2_B" + 0 (zero-terminated string)
83
typedef struct {
84
  char name[20];      // bank name consists of 20 characters, no zero termination, patted with spaces
85
  u16  num_patches;   // number of patches per bank (usually 128)
86
  u16  patch_size;    // reserved size for each patch
87
} mbcv_file_b_header_t;  // 24 bytes
88
 
89
typedef struct {
90
  char name[20];      // patch name consists of 20 characters, no zero termination, patted with spaces
91
  u8   num_channels;  // number of channels in patch (usually 8)
92
  u8   reserved1;     // reserved for future extensions
93
  u8   reserved2;     // reserved for future extensions
94
  u8   reserved3;     // reserved for future extensions
95
} mbcv_file_b_patch_t;  // 24 bytes
96
 
97
 
98
// bank informations stored in RAM
99
typedef struct {
100
  unsigned valid: 1;  // bank is accessible
101
 
102
  mbcv_file_b_header_t header;
103
 
104
  file_t file;      // file informations
105
} mbcv_file_b_info_t;
106
 
107
 
108
/////////////////////////////////////////////////////////////////////////////
109
// Local prototypes
110
/////////////////////////////////////////////////////////////////////////////
111
 
112
 
113
/////////////////////////////////////////////////////////////////////////////
114
// Local variables
115
/////////////////////////////////////////////////////////////////////////////
116
 
117
static mbcv_file_b_info_t mbcv_file_b_info[MBCV_FILE_B_NUM_BANKS];
118
 
119
static u8 cached_patch_name[21];
120
static u8 cached_bank;
121
static u8 cached_patch;
122
 
1457 tk 123
// TODO: only temporary used - make this global?
124
static u16 patch_buffer[CV_PATCH_SIZE];
1453 tk 125
 
1457 tk 126
 
1453 tk 127
/////////////////////////////////////////////////////////////////////////////
128
// Initialisation
129
/////////////////////////////////////////////////////////////////////////////
130
s32 MBCV_FILE_B_Init(u32 mode)
131
{
132
  // invalidate all bank infos
133
  MBCV_FILE_B_UnloadAllBanks();
134
 
135
  return 0; // no error
136
}
137
 
138
 
139
/////////////////////////////////////////////////////////////////////////////
140
// Loads all banks
141
// Called from MBCV_FILE_CheckSDCard() when the SD card has been connected
142
// returns < 0 on errors
143
/////////////////////////////////////////////////////////////////////////////
144
s32 MBCV_FILE_B_LoadAllBanks(void)
145
{
146
  s32 status = 0;
147
 
148
  // load all banks
149
  u8 bank;
150
  for(bank=0; bank<MBCV_FILE_B_NUM_BANKS; ++bank) {
151
    s32 error = MBCV_FILE_B_Open(bank);
152
#if DEBUG_VERBOSE_LEVEL >= 2
153
    DEBUG_MSG("[MBCV_FILE_B] Tried to open bank %c file, status: %d\n", 'A'+bank, error);
154
#endif
155
#if 0
156
    if( error == -2 ) {
157
      error = MBCV_FILE_B_Create(bank);
158
#if DEBUG_VERBOSE_LEVEL >= 2
159
      DEBUG_MSG("[MBCV_FILE_B] Tried to create bank %c file, status: %d\n", 'A'+bank, error);
160
#endif
161
    }
162
#endif
163
    status |= error;
164
  }
165
 
166
  return status;
167
}
168
 
169
 
170
/////////////////////////////////////////////////////////////////////////////
171
// Unloads all banks
172
// Called from MBCV_FILE_CheckSDCard() when the SD card has been disconnected
173
// returns < 0 on errors
174
/////////////////////////////////////////////////////////////////////////////
175
s32 MBCV_FILE_B_UnloadAllBanks(void)
176
{
177
  // invalidate all bank infos
178
  u8 bank;
179
  for(bank=0; bank<MBCV_FILE_B_NUM_BANKS; ++bank)
180
    mbcv_file_b_info[bank].valid = 0;
181
 
182
  return 0; // no error
183
}
184
 
185
 
186
/////////////////////////////////////////////////////////////////////////////
187
// Returns number of patches in bank
188
// Returns 0 if bank not valid
189
/////////////////////////////////////////////////////////////////////////////
190
s32 MBCV_FILE_B_NumPatches(u8 bank)
191
{
192
  if( (bank < MBCV_FILE_B_NUM_BANKS) && mbcv_file_b_info[bank].valid )
193
    return mbcv_file_b_info[bank].header.num_patches;
194
 
195
  return 0;
196
}
197
 
198
 
199
/////////////////////////////////////////////////////////////////////////////
200
// create a complete bank file
201
// returns < 0 on errors (error codes are documented in mbcv_file.h)
202
/////////////////////////////////////////////////////////////////////////////
203
s32 MBCV_FILE_B_Create(u8 bank)
204
{
205
  if( bank >= MBCV_FILE_B_NUM_BANKS )
206
    return MBCV_FILE_B_ERR_INVALID_BANK;
207
 
208
  mbcv_file_b_info_t *info = &mbcv_file_b_info[bank];
209
  info->valid = 0; // set to invalid as long as we are not sure if file can be accessed
210
 
211
  char filepath[MAX_PATH];
212
  sprintf(filepath, "%sMBCV_B%d.V2", MBCV_FILES_PATH, bank+1);
213
 
214
#if DEBUG_VERBOSE_LEVEL >= 2
215
  DEBUG_MSG("[MBCV_FILE_B] Creating new bank file '%s'\n", filepath);
216
#endif
217
 
218
  s32 status = 0;
219
  if( (status=FILE_WriteOpen(filepath, 1)) < 0 ) {
220
#if DEBUG_VERBOSE_LEVEL >= 1
221
    DEBUG_MSG("[MBCV_FILE_B] Failed to create file, status: %d\n", status);
222
#endif
223
    return status;
224
  }
225
 
226
  // write mbcv_file_b_header
227
  const char file_type[10] = "MBCV2_B";
228
  status |= FILE_WriteBuffer((u8 *)file_type, 10);
229
 
230
  // write bank name w/o zero terminator
231
  char bank_name[21];
232
  sprintf(bank_name, "Default Bank        ");
233
  memcpy(info->header.name, bank_name, 20);
234
  status |= FILE_WriteBuffer((u8 *)info->header.name, 20);
235
#if DEBUG_VERBOSE_LEVEL >= 2
236
  DEBUG_MSG("[MBCV_FILE_B] writing '%s'...\n", bank_name);
237
#endif
238
 
239
  // number of patches and size
240
  info->header.num_patches = CV_NUM_PATCHES;
241
  info->header.patch_size = sizeof(mbcv_file_b_patch_t) + CV_PATCH_CHANNELS * 2 * CV_PATCH_SIZE;
242
  status |= FILE_WriteHWord(info->header.num_patches);
243
  status |= FILE_WriteHWord(info->header.patch_size);
244
 
245
  // close file
246
  status |= FILE_WriteClose();
247
 
248
  if( status >= 0 )
249
    // bank valid - caller should fill the patch slots with useful data now
250
    info->valid = 1;
251
 
252
#if DEBUG_VERBOSE_LEVEL >= 2
253
  DEBUG_MSG("[MBCV_FILE_B] Bank file created with status %d\n", status);
254
#endif
255
 
256
  return status;
257
}
258
 
259
 
260
/////////////////////////////////////////////////////////////////////////////
261
// open a bank file
262
// returns < 0 on errors (error codes are documented in mbcv_file.h)
263
/////////////////////////////////////////////////////////////////////////////
264
s32 MBCV_FILE_B_Open(u8 bank)
265
{
266
  if( bank >= MBCV_FILE_B_NUM_BANKS )
267
    return MBCV_FILE_B_ERR_INVALID_BANK;
268
 
269
  mbcv_file_b_info_t *info = &mbcv_file_b_info[bank];
270
 
271
  info->valid = 0; // will be set to valid if bank header has been read successfully
272
 
273
  char filepath[MAX_PATH];
274
  sprintf(filepath, "%sMBCV_B%d.V2", MBCV_FILES_PATH, bank+1);
275
 
276
#if DEBUG_VERBOSE_LEVEL >= 2
277
  DEBUG_MSG("[MBCV_FILE_B] Open bank file '%s'\n", filepath);
278
#endif
279
 
280
  s32 status;
281
  if( (status=FILE_ReadOpen((file_t*)&info->file, filepath)) < 0 ) {
282
#if DEBUG_VERBOSE_LEVEL >= 1
283
    DEBUG_MSG("[MBCV_FILE_B] failed to open file, status: %d\n", status);
284
#endif
285
    return status;
286
  }
287
 
288
  // read and check header
289
  // in order to avoid endianess issues, we have to read the sector bytewise!
290
  char file_type[10];
291
  if( (status=FILE_ReadBuffer((u8 *)file_type, 10)) < 0 ) {
292
#if DEBUG_VERBOSE_LEVEL >= 1
293
    DEBUG_MSG("[MBCV_FILE_B] failed to read header, status: %d\n", status);
294
#endif
295
    return status;
296
  }
297
 
298
  if( strncmp(file_type, "MBCV2_B", 10) != 0 ) {
299
#if DEBUG_VERBOSE_LEVEL >= 1
300
    file_type[9] = 0; // ensure that string is terminated
301
    DEBUG_MSG("[MBCV_FILE_B] wrong header type: %s\n", file_type);
302
#endif
303
    return MBCV_FILE_B_ERR_FORMAT;
304
  }
305
 
306
  status |= FILE_ReadBuffer((u8 *)info->header.name, 20);
307
  status |= FILE_ReadHWord((u16 *)&info->header.num_patches);
308
  status |= FILE_ReadHWord((u16 *)&info->header.patch_size);
309
 
310
  if( status < 0 ) {
311
#if DEBUG_VERBOSE_LEVEL >= 1
312
    DEBUG_MSG("[MBCV_FILE_B] file access error while reading header, status: %d\n", status);
313
#endif
314
    return MBCV_FILE_B_ERR_READ;
315
  }
316
 
317
  // close file (so that it can be re-opened)
318
  FILE_ReadClose((file_t*)&info->file);
319
 
320
  // bank is valid! :)
321
  info->valid = 1;
322
 
323
#if DEBUG_VERBOSE_LEVEL >= 2
324
  DEBUG_MSG("[MBCV_FILE_B] bank is valid! Number of Patches: %d, Patch Size: %d\n", info->header.num_patches, info->header.patch_size);
325
#endif
326
 
327
  // finally (re-)load cached patch name - status of this function doesn't matter
328
  char dummy[21];
329
  MBCV_FILE_B_PatchPeekName(cached_bank, cached_patch, 1, dummy); // non-cached!
330
 
331
  return 0; // no error
332
}
333
 
334
 
335
/////////////////////////////////////////////////////////////////////////////
336
// reads a patch from bank
337
// returns < 0 on errors (error codes are documented in mbcv_file.h)
338
/////////////////////////////////////////////////////////////////////////////
339
s32 MBCV_FILE_B_PatchRead(u8 bank, u8 patch)
340
{
341
  if( bank >= MBCV_FILE_B_NUM_BANKS )
342
    return MBCV_FILE_B_ERR_INVALID_BANK;
343
 
344
  mbcv_file_b_info_t *info = &mbcv_file_b_info[bank];
345
 
346
  if( !info->valid )
347
    return MBCV_FILE_B_ERR_NO_FILE;
348
 
349
  if( patch >= info->header.num_patches )
350
    return MBCV_FILE_B_ERR_INVALID_PATCH;
351
 
352
  // re-open file
353
  if( FILE_ReadReOpen((file_t*)&info->file) < 0 )
354
    return -1; // file cannot be re-opened
355
 
356
  // change to file position
357
  s32 status;
358
  u32 offset = 10 + sizeof(mbcv_file_b_header_t) + patch * info->header.patch_size;
359
  if( (status=FILE_ReadSeek(offset)) < 0 ) {
360
#if DEBUG_VERBOSE_LEVEL >= 1
361
    DEBUG_MSG("[MBCV_FILE_B] failed to change patch offset in file, status: %d\n", status);
362
#endif
363
    // close file (so that it can be re-opened)
364
    FILE_ReadClose((file_t*)&info->file);
365
    return MBCV_FILE_B_ERR_READ;
366
  }
367
 
368
  status |= FILE_ReadBuffer((u8 *)mbcv_patch_name, 20);
369
  mbcv_patch_name[20] = 0;
370
 
371
  u8 num_channels = 0;
372
  status |= FILE_ReadByte(&num_channels);
373
 
374
  u8 reserved = 0;
375
  status |= FILE_ReadByte(&reserved);
376
  status |= FILE_ReadByte(&reserved);
377
  status |= FILE_ReadByte(&reserved);
378
 
379
#if DEBUG_VERBOSE_LEVEL >= 2
380
  DEBUG_MSG("[MBCV_FILE_B] read patch %c%03d '%s', %d channels\n", 'A'+bank, patch, mbcv_patch_name, num_channels);
381
#endif
382
 
383
  // reduce number of channels if required
384
  if( num_channels > CV_PATCH_CHANNELS )
385
    num_channels = CV_PATCH_CHANNELS;
386
 
387
  if( status >= 0 ) {
388
    u8 cv;
389
    for(cv=0; cv<CV_PATCH_CHANNELS; ++cv) {
1457 tk 390
      status |= FILE_ReadBuffer((u8 *)patch_buffer, 2*CV_PATCH_SIZE);
1453 tk 391
 
392
      // check status before pasting into CV channel
393
      if( status < 0 ) {
394
#if DEBUG_VERBOSE_LEVEL >= 1
395
    DEBUG_MSG("[MBCV_FILE_B] read channel #%d failed due to file access error, status: %d\n", cv+1, status);
396
#endif
397
    break;
398
      }
399
 
1653 tk 400
      MBCV_PATCH_Paste(cv, (u16 *)patch_buffer);
1453 tk 401
    }
402
  }
403
 
404
  // close file (so that it can be re-opened)
405
  FILE_ReadClose((file_t*)&info->file);
406
 
407
  if( status < 0 ) {
408
#if DEBUG_VERBOSE_LEVEL >= 1
409
    DEBUG_MSG("[MBCV_FILE_B] error while reading file, status: %d\n", status);
410
#endif
411
    return MBCV_FILE_B_ERR_READ;
412
  } else {
413
#if DEBUG_VERBOSE_LEVEL >= 2
414
  DEBUG_MSG("[MBCV_FILE_B] read finished successfully!\n");
415
#endif
416
  }
417
 
418
  return 0; // no error
419
}
420
 
421
 
422
/////////////////////////////////////////////////////////////////////////////
423
// writes a patch into bank
424
// returns < 0 on errors (error codes are documented in mbcv_file.h)
425
/////////////////////////////////////////////////////////////////////////////
426
s32 MBCV_FILE_B_PatchWrite(u8 bank, u8 patch, u8 rename_if_empty_name)
427
{
428
  if( bank >= MBCV_FILE_B_NUM_BANKS )
429
    return MBCV_FILE_B_ERR_INVALID_BANK;
430
 
431
  mbcv_file_b_info_t *info = &mbcv_file_b_info[bank];
432
 
433
  if( !info->valid )
434
    return MBCV_FILE_B_ERR_FORMAT;
435
 
436
  if( patch >= info->header.num_patches )
437
    return MBCV_FILE_B_ERR_INVALID_PATCH;
438
 
439
 
440
  // TODO: before writing into patch slot, we should check if it already exists, and then
441
  // compare layer parameters with given constraints available in following defines/variables:
442
 
443
  // ok, we should at least check, if the resulting size is within the given range
444
  u16 expected_patch_size = sizeof(mbcv_file_b_patch_t) + CV_PATCH_CHANNELS * 2 * CV_PATCH_SIZE;
445
 
446
  if( expected_patch_size > info->header.patch_size ) {
447
#if DEBUG_VERBOSE_LEVEL >= 1
448
    DEBUG_MSG("[MBCV_FILE_B] Resulting patch is too large for slot in bank (is: %d, max: %d)\n",
449
       expected_patch_size, info->header.patch_size);
450
    return MBCV_FILE_B_ERR_P_TOO_LARGE;
451
#endif
452
  }
453
 
454
  char filepath[MAX_PATH];
455
  sprintf(filepath, "%sMBCV_B%d.V2", MBCV_FILES_PATH, bank+1);
456
 
457
#if DEBUG_VERBOSE_LEVEL >= 2
458
  DEBUG_MSG("[MBCV_FILE_B] Open bank file '%s' for writing\n", filepath);
459
#endif
460
 
461
  s32 status = 0;
462
  if( (status=FILE_WriteOpen(filepath, 0)) < 0 ) {
463
#if DEBUG_VERBOSE_LEVEL >= 1
464
    DEBUG_MSG("[MBCV_FILE_B] Failed to open file, status: %d\n", status);
465
#endif
466
    FILE_WriteClose(); // important to free memory given by malloc
467
    return status;
468
  }
469
 
470
  // change to file position
471
  u32 offset = 10 + sizeof(mbcv_file_b_header_t) + patch * info->header.patch_size;
472
  if( (status=FILE_WriteSeek(offset)) < 0 ) {
473
#if DEBUG_VERBOSE_LEVEL >= 1
474
    DEBUG_MSG("[MBCV_FILE_B] failed to change patch offset in file, status: %d\n", status);
475
#endif
476
    FILE_WriteClose(); // important to free memory given by malloc
477
    return status;
478
  }
479
 
480
  // rename patch if name is empty
481
  if( rename_if_empty_name ) {
482
    int i;
483
    u8 found_char = 0;
484
    u8 *label = (u8 *)&mbcv_patch_name[5];
485
    for(i=0; i<15; ++i)
486
      if( label[i] != ' ' ) {
487
    found_char = 1;
488
    break;
489
      }
490
 
491
    if( !found_char )
492
      memcpy(label, "Unnamed        ", 15);
493
  }
494
 
495
  // write patch name w/o zero terminator
496
  status |= FILE_WriteBuffer((u8 *)mbcv_patch_name, 20);
497
 
498
#if DEBUG_VERBOSE_LEVEL >= 2
499
  DEBUG_MSG("[MBCV_FILE_B] writing patch %c%03d '%s'...\n", 'A'+bank, patch, mbcv_patch_name);
500
#endif
501
 
502
  // header information
503
  u8 num_channels = CV_PATCH_CHANNELS;
504
  status |= FILE_WriteByte(num_channels);
505
 
506
  u8 reserved = 0;
507
  status |= FILE_WriteByte(reserved);
508
  status |= FILE_WriteByte(reserved);
509
  status |= FILE_WriteByte(reserved);
510
 
511
 
512
  // write patches
513
  u8 cv;
514
  for(cv=0; cv<num_channels; ++cv) {
1457 tk 515
    MBCV_PATCH_Copy(cv, patch_buffer);
516
    status |= FILE_WriteBuffer((u8 *)patch_buffer, 2*CV_PATCH_SIZE);
1453 tk 517
  }
518
 
519
 
520
  // fill remaining bytes with zero if required
521
  while( expected_patch_size < info->header.patch_size ) {
522
    status |= FILE_WriteByte(0x00);
523
    ++expected_patch_size;
524
  }
525
 
526
  // close file
527
  status |= FILE_WriteClose();
528
 
529
#if DEBUG_VERBOSE_LEVEL >= 2
530
  DEBUG_MSG("[MBCV_FILE_B] Patch written with status %d\n", status);
531
#endif
532
 
533
  return (status < 0) ? MBCV_FILE_B_ERR_WRITE : 0;
534
}
535
 
536
 
537
/////////////////////////////////////////////////////////////////////////////
538
// returns a patch name from disk w/o overwriting patches in RAM
539
//
540
// used in SAVE menu to display the patch name which will be overwritten
541
// 
542
// function can be called frequently w/o performance loss, as the name
543
// of bank/patch will be cached.
544
// non_cached=1 forces an update regardless of bank/patch number
545
//
546
// *name will contain 20 characters + 0 terminator regardless of status
547
//
548
// returns < 0 on errors (error codes are documented in mbcv_file.h)
549
/////////////////////////////////////////////////////////////////////////////
550
s32 MBCV_FILE_B_PatchPeekName(u8 bank, u8 patch, u8 non_cached, char *patch_name)
551
{
552
  if( !non_cached && cached_bank == bank && cached_patch == patch ) {
553
    // name is in cache
554
    memcpy(patch_name, cached_patch_name, 21);
555
    return 0; // no error
556
  }
557
 
558
  cached_bank = bank;
559
  cached_patch = patch;
560
 
561
#if DEBUG_VERBOSE_LEVEL >= 2
562
  DEBUG_MSG("[MBCV_FILE_B] Loading Patch Name for %c%03d\n", 'A'+bank, patch);
563
#endif
564
 
565
  // initial patch name
566
  memcpy(cached_patch_name, "-----<Disk Error>   ", 21);
567
 
568
  if( bank >= MBCV_FILE_B_NUM_BANKS )
569
    return MBCV_FILE_B_ERR_INVALID_BANK;
570
 
571
  mbcv_file_b_info_t *info = &mbcv_file_b_info[bank];
572
 
573
  if( !info->valid )
574
    return MBCV_FILE_B_ERR_NO_FILE;
575
 
576
  if( patch >= info->header.num_patches )
577
    return MBCV_FILE_B_ERR_INVALID_PATCH;
578
 
579
  // re-open file
580
  if( FILE_ReadReOpen((file_t*)&info->file) < 0 )
581
    return -1; // file cannot be re-opened
582
 
583
  // change to file position
584
  s32 status;
585
  u32 offset = 10 + sizeof(mbcv_file_b_header_t) + patch * info->header.patch_size;
586
  if( (status=FILE_ReadSeek(offset)) < 0 ) {
587
#if DEBUG_VERBOSE_LEVEL >= 1
588
    DEBUG_MSG("[MBCV_FILE_B] failed to change patch offset in file, status: %d\n", status);
589
#endif
590
    // close file (so that it can be re-opened)
591
    FILE_ReadClose((file_t*)&info->file);
592
    return MBCV_FILE_B_ERR_READ;
593
  }
594
 
595
  // read name
596
  status |= FILE_ReadBuffer((u8 *)cached_patch_name, 20);
597
  cached_patch_name[20] = 0;
598
 
599
  // close file (so that it can be re-opened)
600
  FILE_ReadClose((file_t*)&info->file);
601
 
602
  // fill category with "-----" if it is empty
603
  int i;
604
  u8 found_char = 0;
605
  for(i=0; i<5; ++i)
606
    if( cached_patch_name[i] != ' ' ) {
607
      found_char = 1;
608
      break;
609
    }
610
  if( !found_char )
611
    memcpy(&cached_patch_name[0], "-----", 5);
612
 
613
 
614
  // fill label with "<empty>" if it is empty
615
  found_char = 0;
616
  for(i=5; i<20; ++i)
617
    if( cached_patch_name[i] != ' ' ) {
618
      found_char = 1;
619
      break;
620
    }
621
  if( !found_char )
622
    memcpy(&cached_patch_name[5], "<empty>        ", 15);
623
 
624
 
625
  // copy into return variable
626
  memcpy(patch_name, cached_patch_name, 21);
627
 
628
#if DEBUG_VERBOSE_LEVEL >= 2
629
  DEBUG_MSG("[MBCV_FILE_B] Loading Patch Name for %c%03d successfull\n", 'A'+bank, patch);
630
#endif
631
 
632
  return 0; // no error
633
}