Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/trackmod/protracker.c

    r43dd72b7 r7e69e0e  
    113113}
    114114
    115 
    116 /** Decode pattern cell.
    117  *
    118  * @param pattern Pattern
    119  * @param row     Row number
    120  * @param channel Channel number
    121  * @param cell    Place to store decoded cell
    122  */
    123 static void protracker_decode_cell(uint32_t cdata, trackmod_cell_t *cell)
    124 {
    125         uint32_t code;
    126 
    127         code = uint32_t_be2host(cdata);
    128         cell->period = (code >> (4 * 4)) & 0xfff;
    129         cell->instr = (((code >> (7 * 4)) & 0xf) << 4) |
    130             ((code >> (3 * 4)) & 0xf);
    131         cell->effect = code & 0xfff;
    132 }
    133 
    134 /** Load Protracker patterns.
    135  *
    136  * @param f      File to read from
    137  * @param module Module being loaded to
    138  * @return       EOK on success, ENOMEM if out of memory, EIO on I/O error.
    139  */
    140 static int protracker_load_patterns(FILE *f, trackmod_module_t *module)
    141 {
    142         size_t cells;
    143         size_t i, j;
    144         int rc;
    145         size_t nread;
    146         uint32_t *buf = NULL;
    147 
    148         cells = module->channels * protracker_pattern_rows;
    149         buf = calloc(sizeof(uint32_t), cells);
    150 
    151         if (buf == NULL) {
    152                 rc = ENOMEM;
    153                 goto error;
    154         }
    155 
    156         for (i = 0; i < module->patterns; i++) {
    157                 module->pattern[i].rows = protracker_pattern_rows;
    158                 module->pattern[i].channels = module->channels;
    159                 module->pattern[i].data = calloc(sizeof(trackmod_cell_t), cells);
    160                 if (module->pattern[i].data == NULL) {
    161                         rc = ENOMEM;
    162                         goto error;
    163                 }
    164 
    165                 nread = fread(buf, sizeof(uint32_t), cells, f);
    166                 if (nread != cells) {
    167                         printf("Error reading pattern.\n");
    168                         rc = EIO;
    169                         goto error;
    170                 }
    171 
    172                 /* Decode cells */
    173                 for (j = 0; j < cells; j++) {
    174                         protracker_decode_cell(buf[j],
    175                             &module->pattern[i].data[j]);
    176                 }
    177         }
    178 
    179         free(buf);
    180         return EOK;
    181 error:
    182         free(buf);
    183         return rc;
    184 }
    185 
    186 /** Load protracker samples.
    187  *
    188  * @param f      File being read from
    189  * @param sample Sample header
    190  * @param module Module being loaded to
    191  * @return       EOk on success, ENOMEM if out of memory, EIO on I/O error.
    192  */
    193 static int protracker_load_samples(FILE *f, protracker_smp_t *smp,
    194     trackmod_module_t *module)
    195 {
    196         int rc;
    197         size_t i;
    198         uint8_t ftval;
    199         size_t nread;
    200         trackmod_sample_t *sample;
    201 
    202         for (i = 0; i < module->instrs; i++) {
    203                 module->instr[i].samples = 1;
    204                 module->instr[i].sample = calloc(1, sizeof(trackmod_sample_t));
    205                 if (module->instr[i].sample == NULL) {
    206                         printf("Error allocating sample.\n");
    207                         rc = ENOMEM;
    208                         goto error;
    209                 }
    210 
    211                 sample = &module->instr[i].sample[0];
    212                 sample->length =
    213                     uint16_t_be2host(smp[i].length) * 2;
    214                 sample->bytes_smp = 1;
    215                 sample->data = calloc(1, sample->length);
    216                 if (sample->data == NULL) {
    217                         printf("Error allocating sample.\n");
    218                         rc = ENOMEM;
    219                         goto error;
    220                 }
    221 
    222                 nread = fread(sample->data, 1, sample->length, f);
    223                 if (nread != sample->length) {
    224                         printf("Error reading sample.\n");
    225                         rc = EIO;
    226                         goto error;
    227                 }
    228 
    229                 sample->def_vol = smp[i].def_vol;
    230 
    231                 sample->loop_start =
    232                     uint16_t_be2host(smp[i].loop_start) * 2;
    233                 sample->loop_len =
    234                     uint16_t_be2host(smp[i].loop_len) * 2;
    235                 if (sample->loop_len <= 2)
    236                         sample->loop_type = tl_no_loop;
    237                 else
    238                         sample->loop_type = tl_forward_loop;
    239 
    240                 /* Finetune is a 4-bit signed value. */
    241                 ftval = smp[i].finetune & 0x0f;
    242                 sample->finetune =
    243                         (ftval & 0x8) ? (ftval & 0x7) - 8 : ftval;
    244         }
    245 
    246         return EOK;
    247 error:
    248         return rc;
    249 }
    250 
    251115/** Load protracker module.
    252116 *
     
    264128        protracker_order_list_t *order_list;
    265129        protracker_smp_t *sample;
     130        size_t nread;
    266131        size_t samples;
    267132        size_t channels;
    268133        size_t patterns;
    269         size_t i;
    270         size_t nread;
     134        size_t cells;
     135        size_t i, j;
    271136        int rc;
    272137
     
    327192        module->channels = channels;
    328193
    329         module->instrs = samples;
    330         module->instr = calloc(sizeof(trackmod_instr_t), samples);
    331         if (module->instr == NULL) {
     194        module->samples = samples;
     195        module->sample = calloc(sizeof(trackmod_sample_t), samples);
     196        if (module->sample == NULL) {
    332197                printf("Out of memory.\n");
    333198                rc = ENOMEM;
     
    356221        }
    357222
    358         /* The 'mark' byte may or may not contain a valid restart position */
    359         if (order_list->mark < order_list->order_list_len) {
    360                 module->restart_pos = order_list->mark;
    361         }
    362 
    363223        /* Load patterns */
    364         rc = protracker_load_patterns(f, module);
    365         if (rc != EOK)
    366                 goto error;
     224
     225        cells = channels * protracker_pattern_rows;
     226
     227        for (i = 0; i < patterns; i++) {
     228                module->pattern[i].rows = protracker_pattern_rows;
     229                module->pattern[i].channels = channels;
     230                module->pattern[i].data = calloc(sizeof(uint32_t), cells);
     231
     232                nread = fread(module->pattern[i].data,
     233                    sizeof(uint32_t), cells, f);
     234                if (nread != cells) {
     235                        printf("Error reading pattern.\n");
     236                        rc = EIO;
     237                        goto error;
     238                }
     239
     240                /* Convert byte order */
     241                for (j = 0; j < cells; j++) {
     242                        module->pattern[i].data[j] = uint32_t_be2host(
     243                            module->pattern[i].data[j]);
     244                }
     245        }
    367246
    368247        /* Load samples */
    369         rc = protracker_load_samples(f, sample, module);
    370         if (rc != EOK)
    371                 goto error;
     248        for (i = 0; i < samples; i++) {
     249                module->sample[i].length =
     250                    uint16_t_be2host(sample[i].length) * 2;
     251                module->sample[i].data = calloc(1, module->sample[i].length);
     252                if (module->sample[i].data == NULL) {
     253                        printf("Error allocating sample.\n");
     254                        rc = ENOMEM;
     255                        goto error;
     256                }
     257
     258                nread = fread(module->sample[i].data, 1, module->sample[i].length,
     259                        f);
     260                if (nread != module->sample[i].length) {
     261                        printf("Error reading sample.\n");
     262                        rc = EIO;
     263                        goto error;
     264                }
     265
     266                module->sample[i].def_vol = sample[i].def_vol;
     267                module->sample[i].loop_start =
     268                    uint16_t_be2host(sample[i].loop_start) * 2;
     269                module->sample[i].loop_len =
     270                    uint16_t_be2host(sample[i].loop_len) * 2;
     271                if (module->sample[i].loop_len <= 2)
     272                        module->sample[i].loop_len = 0;
     273        }
    372274
    373275        (void) fclose(f);
    374 
    375         module->def_bpm = protracker_def_bpm;
    376         module->def_tpr = protracker_def_tpr;
    377276
    378277        *rmodule = module;
Note: See TracChangeset for help on using the changeset viewer.