AFfilesetup RawFile::completeSetup(AFfilesetup setup) { AFfilesetup newSetup; if (setup->trackSet && setup->trackCount != 1) { _af_error(AF_BAD_FILESETUP, "raw file must have exactly one track"); return AF_NULL_FILESETUP; } TrackSetup *track = setup->getTrack(); if (!track) { _af_error(AF_BAD_FILESETUP, "could not access track in file setup"); return AF_NULL_FILESETUP; } if (track->aesDataSet) { _af_error(AF_BAD_FILESETUP, "raw file cannot have AES data"); return AF_NULL_FILESETUP; } if (track->markersSet && track->markerCount != 0) { _af_error(AF_BAD_NUMMARKS, "raw file cannot have markers"); return AF_NULL_FILESETUP; } if (setup->instrumentSet && setup->instrumentCount != 0) { _af_error(AF_BAD_NUMINSTS, "raw file cannot have instruments"); return AF_NULL_FILESETUP; } if (setup->miscellaneousSet && setup->miscellaneousCount != 0) { _af_error(AF_BAD_NUMMISC, "raw file cannot have miscellaneous data"); return AF_NULL_FILESETUP; } newSetup = (_AFfilesetup *) _af_malloc(sizeof (_AFfilesetup)); *newSetup = rawDefaultFileSetup; newSetup->tracks = (TrackSetup *) _af_malloc(sizeof (TrackSetup)); newSetup->tracks[0] = setup->tracks[0]; newSetup->tracks[0].f.compressionParams = NULL; newSetup->tracks[0].markerCount = 0; newSetup->tracks[0].markers = NULL; return newSetup; }
/* Parse miscellaneous data chunks such as name, author, copyright, and annotation chunks. */ status IFFFile::parseMiscellaneous(const Tag &type, size_t size) { int misctype = AF_MISC_UNRECOGNIZED; assert(type == "NAME" || type == "AUTH" || type == "(c) " || type == "ANNO"); /* Skip zero-length miscellaneous chunks. */ if (size == 0) return AF_FAIL; m_miscellaneousCount++; m_miscellaneous = (Miscellaneous *) _af_realloc(m_miscellaneous, m_miscellaneousCount * sizeof (Miscellaneous)); if (type == "NAME") misctype = AF_MISC_NAME; else if (type == "AUTH") misctype = AF_MISC_AUTH; else if (type == "(c) ") misctype = AF_MISC_COPY; else if (type == "ANNO") misctype = AF_MISC_ANNO; m_miscellaneous[m_miscellaneousCount - 1].id = m_miscellaneousCount; m_miscellaneous[m_miscellaneousCount - 1].type = misctype; m_miscellaneous[m_miscellaneousCount - 1].size = size; m_miscellaneous[m_miscellaneousCount - 1].position = 0; m_miscellaneous[m_miscellaneousCount - 1].buffer = _af_malloc(size); m_fh->read(m_miscellaneous[m_miscellaneousCount - 1].buffer, size); return AF_SUCCEED; }
/* Parse miscellaneous data chunks such as name, author, copyright, and annotation chunks. */ static status ParseMiscellaneous (AFfilehandle file, AFvirtualfile *fh, uint32_t type, size_t size) { int misctype = AF_MISC_UNRECOGNIZED; assert(!memcmp(&type, "NAME", 4) || !memcmp(&type, "AUTH", 4) || !memcmp(&type, "(c) ", 4) || !memcmp(&type, "ANNO", 4)); /* Skip zero-length miscellaneous chunks. */ if (size == 0) return AF_FAIL; file->miscellaneousCount++; file->miscellaneous = _af_realloc(file->miscellaneous, file->miscellaneousCount * sizeof (_Miscellaneous)); if (!memcmp(&type, "NAME", 4)) misctype = AF_MISC_NAME; else if (!memcmp(&type, "AUTH", 4)) misctype = AF_MISC_AUTH; else if (!memcmp(&type, "(c) ", 4)) misctype = AF_MISC_COPY; else if (!memcmp(&type, "ANNO", 4)) misctype = AF_MISC_ANNO; file->miscellaneous[file->miscellaneousCount - 1].id = file->miscellaneousCount; file->miscellaneous[file->miscellaneousCount - 1].type = misctype; file->miscellaneous[file->miscellaneousCount - 1].size = size; file->miscellaneous[file->miscellaneousCount - 1].position = 0; file->miscellaneous[file->miscellaneousCount - 1].buffer = _af_malloc(size); af_fread(file->miscellaneous[file->miscellaneousCount - 1].buffer, size, 1, file->fh); return AF_SUCCEED; }
AFfilesetup afNewFileSetup (void) { AFfilesetup setup; setup = (_AFfilesetup *) _af_malloc(sizeof (_AFfilesetup)); if (setup == NULL) return AF_NULL_FILESETUP; *setup = _af_default_file_setup; setup->tracks = _af_tracksetup_new(setup->trackCount); setup->instruments = _af_instsetup_new(setup->instrumentCount); if (setup->miscellaneousCount == 0) setup->miscellaneous = NULL; else { setup->miscellaneous = (MiscellaneousSetup *) _af_calloc(setup->miscellaneousCount, sizeof (MiscellaneousSetup)); for (int i=0; i<setup->miscellaneousCount; i++) { setup->miscellaneous[i].id = i+1; setup->miscellaneous[i].type = 0; setup->miscellaneous[i].size = 0; } } return setup; }
void afInitMarkComment(AFfilesetup setup, int trackid, int markid, const char *commstr) { int markno; int length; if (!_af_filesetup_ok(setup)) return; TrackSetup *track = setup->getTrack(trackid); if (!track) return; for (markno=0; markno<track->markerCount; markno++) { if (track->markers[markno].id == markid) break; } if (markno == track->markerCount) { _af_error(AF_BAD_MARKID, "no marker id %d for file setup", markid); return; } length = strlen(commstr); if (track->markers[markno].comment) free(track->markers[markno].comment); if ((track->markers[markno].comment = (char *) _af_malloc(length+1)) == NULL) return; strcpy(track->markers[markno].comment, commstr); }
/* Parse marker chunks, which contain the positions and names of loop markers. */ static status ParseMARK (AFfilehandle file, AFvirtualfile *fh, u_int32_t type, size_t size) { _Track *track; int i; u_int16_t numMarkers; assert(!memcmp(&type, "MARK", 4)); track = _af_filehandle_get_track(file, AF_DEFAULT_TRACK); af_fread(&numMarkers, sizeof (u_int16_t), 1, fh); numMarkers = BENDIAN_TO_HOST_INT16(numMarkers); track->markerCount = numMarkers; if (numMarkers) track->markers = _af_marker_new(numMarkers); for (i=0; i<numMarkers; i++) { u_int16_t markerID = 0; u_int32_t markerPosition = 0; u_int8_t sizeByte = 0; char *markerName = NULL; af_fread(&markerID, sizeof (u_int16_t), 1, fh); markerID = BENDIAN_TO_HOST_INT16(markerID); af_fread(&markerPosition, sizeof (u_int32_t), 1, fh); markerPosition = BENDIAN_TO_HOST_INT32(markerPosition); af_fread(&sizeByte, sizeof (unsigned char), 1, fh); markerName = _af_malloc(sizeByte + 1); af_fread(markerName, sizeof (unsigned char), sizeByte, fh); markerName[sizeByte] = '\0'; #ifdef DEBUG printf("marker id: %d, position: %d, name: %s\n", markerID, markerPosition, markerName); printf("size byte: %d\n", sizeByte); #endif /* If sizeByte is even, then 1+sizeByte (the length of the string) is odd. Skip an extra byte to make it even. */ if ((sizeByte % 2) == 0) af_fseek(fh, 1, SEEK_CUR); track->markers[i].id = markerID; track->markers[i].position = markerPosition; track->markers[i].name = markerName; track->markers[i].comment = _af_strdup(""); } return AF_SUCCEED; }
/* Parse an adtl sub-chunk within a LIST chunk. */ status WAVEFile::parseADTLSubChunk(const Tag &id, uint32_t size) { Track *track = getTrack(); AFfileoffset endPos = fh->tell() + size; while (fh->tell() < endPos) { Tag chunkID; uint32_t chunkSize; readTag(&chunkID); readU32(&chunkSize); if (chunkID == "labl" || chunkID == "note") { uint32_t id; long length=chunkSize-4; char *p = (char *) _af_malloc(length); readU32(&id); fh->read(p, length); Marker *marker = track->getMarker(id); if (marker) { if (chunkID == "labl") { free(marker->name); marker->name = p; } else if (chunkID == "note") { free(marker->comment); marker->comment = p; } else free(p); } else free(p); /* If chunkSize is odd, skip an extra byte at the end of the chunk. */ if ((chunkSize % 2) != 0) fh->seek(1, File::SeekFromCurrent); } else { /* If chunkSize is odd, skip an extra byte. */ fh->seek(chunkSize + (chunkSize % 2), File::SeekFromCurrent); } } return AF_SUCCEED; }
_WAVEInfo *waveinfo_new (void) { _WAVEInfo *waveinfo = _af_malloc(sizeof (_WAVEInfo)); waveinfo->factOffset = 0; waveinfo->miscellaneousStartOffset = 0; waveinfo->totalMiscellaneousSize = 0; waveinfo->markOffset = 0; waveinfo->dataSizeOffset = 0; return waveinfo; }
/* Parse an INFO sub-chunk within a LIST chunk. */ status WAVEFile::parseINFOSubChunk(const Tag &id, uint32_t size) { AFfileoffset endPos = fh->tell() + size; while (fh->tell() < endPos) { int misctype = AF_MISC_UNRECOGNIZED; Tag miscid; uint32_t miscsize; readTag(&miscid); readU32(&miscsize); if (miscid == "IART") misctype = AF_MISC_AUTH; else if (miscid == "INAM") misctype = AF_MISC_NAME; else if (miscid == "ICOP") misctype = AF_MISC_COPY; else if (miscid == "ICMT") misctype = AF_MISC_ICMT; else if (miscid == "ICRD") misctype = AF_MISC_ICRD; else if (miscid == "ISFT") misctype = AF_MISC_ISFT; if (misctype != AF_MISC_UNRECOGNIZED) { char *string = (char *) _af_malloc(miscsize); fh->read(string, miscsize); miscellaneousCount++; miscellaneous = (Miscellaneous *) _af_realloc(miscellaneous, sizeof (Miscellaneous) * miscellaneousCount); miscellaneous[miscellaneousCount-1].id = miscellaneousCount; miscellaneous[miscellaneousCount-1].type = misctype; miscellaneous[miscellaneousCount-1].size = miscsize; miscellaneous[miscellaneousCount-1].position = 0; miscellaneous[miscellaneousCount-1].buffer = string; } else { fh->seek(miscsize, File::SeekFromCurrent); } /* Make the current position an even number of bytes. */ if (miscsize % 2 != 0) fh->seek(1, File::SeekFromCurrent); } return AF_SUCCEED; }
void SampleVisionFile::addMiscellaneous(int type, const char *data) { m_miscellaneousCount++; m_miscellaneous = (Miscellaneous *) _af_realloc(m_miscellaneous, m_miscellaneousCount * sizeof (Miscellaneous)); Miscellaneous &m = m_miscellaneous[m_miscellaneousCount - 1]; m.id = m_miscellaneousCount; m.type = type; m.size = strlen(data); m.position = 0; m.buffer = _af_malloc(m.size); memcpy(m.buffer, data, m.size); }
_AFmoduleinst _AFg711initcompress (_Track *trk, AFvirtualfile *fh, bool seekok, bool headerless, AFframecount *chunkframes) { _AFmoduleinst ret = _AFnewmodinst(&g711compress); g711_data *d; d = (g711_data *) _af_malloc(sizeof (g711_data)); d->trk = trk; d->fh = fh; d->seekok = seekok; d->trk->fpos_next_frame = d->trk->fpos_first_frame; ret.modspec = d; return ret; }
_AFmoduleinst _af_ms_adpcm_init_decompress (_Track *track, AFvirtualfile *fh, bool seekok, bool headerless, AFframecount *chunkframes) { _AFmoduleinst ret = _AFnewmodinst(&ms_adpcm_decompress); ms_adpcm_data *d; AUpvlist pv; long l; void *v; assert(af_ftell(fh) == track->fpos_first_frame); d = (ms_adpcm_data *) _af_malloc(sizeof (ms_adpcm_data)); d->track = track; d->fh = fh; d->track->frames2ignore = 0; d->track->fpos_next_frame = d->track->fpos_first_frame; pv = d->track->f.compressionParams; if (_af_pv_getlong(pv, _AF_MS_ADPCM_NUM_COEFFICIENTS, &l)) d->numCoefficients = l; else _af_error(AF_BAD_CODEC_CONFIG, "number of coefficients not set"); if (_af_pv_getptr(pv, _AF_MS_ADPCM_COEFFICIENTS, &v)) memcpy(d->coefficients, v, sizeof (int16_t) * 256 * 2); else _af_error(AF_BAD_CODEC_CONFIG, "coefficient array not set"); if (_af_pv_getlong(pv, _AF_FRAMES_PER_BLOCK, &l)) d->framesPerBlock = l; else _af_error(AF_BAD_CODEC_CONFIG, "samples per block not set"); if (_af_pv_getlong(pv, _AF_BLOCK_SIZE, &l)) d->blockAlign = l; else _af_error(AF_BAD_CODEC_CONFIG, "block size not set"); *chunkframes = d->framesPerBlock; ret.modspec = d; return ret; }
void afInitMarkName(AFfilesetup setup, int trackid, int markid, const char *namestr) { int markno; int length; if (!_af_filesetup_ok(setup)) return; TrackSetup *track = setup->getTrack(trackid); if (!track) return; for (markno=0; markno<track->markerCount; markno++) { if (track->markers[markno].id == markid) break; } if (markno == track->markerCount) { _af_error(AF_BAD_MARKID, "no marker id %d for file setup", markid); return; } length = strlen(namestr); if (length > 255) { _af_error(AF_BAD_STRLEN, "warning: marker name truncated to 255 characters"); length = 255; } if (track->markers[markno].name) free(track->markers[markno].name); if ((track->markers[markno].name = (char *) _af_malloc(length+1)) == NULL) return; strncpy(track->markers[markno].name, namestr, length); /* The null terminator is not set by strncpy if strlen(namestr) > length. Set it here. */ track->markers[markno].name[length] = '\0'; }
_Track *_af_track_new (void) { _Track *t = _af_malloc(sizeof (_Track)); t->valid = _AF_VALID_TRACK; t->id = AF_DEFAULT_TRACK; t->f.compressionParams = NULL; t->v.compressionParams = NULL; t->channelMatrix = NULL; t->markerCount = 0; t->markers = NULL; t->hasAESData = AF_FALSE; memset(t->aesData, 0, 24); t->totalfframes = 0; t->nextfframe = 0; t->frames2ignore = 0; t->fpos_first_frame = 0; t->fpos_next_frame = 0; t->fpos_after_data = 0; t->totalvframes = 0; t->nextvframe = 0; t->data_size = 0; t->ms.modulesdirty = AF_TRUE; t->ms.nmodules = 0; t->ms.chunk = NULL; t->ms.module = NULL; t->ms.buffer = NULL; t->ms.filemodinst.mod = NULL; return t; }
_AFmoduleinst _af_ima_adpcm_init_decompress (_Track *track, AFvirtualfile *fh, bool seekok, bool headerless, AFframecount *chunkframes) { _AFmoduleinst ret = _AFnewmodinst(&ima_adpcm_decompress); ima_adpcm_data *d; AUpvlist pv; int i; long l; void *v; assert(af_ftell(fh) == track->fpos_first_frame); d = (ima_adpcm_data *) _af_malloc(sizeof (ima_adpcm_data)); d->track = track; d->fh = fh; d->track->frames2ignore = 0; d->track->fpos_next_frame = d->track->fpos_first_frame; pv = d->track->f.compressionParams; if (_af_pv_getlong(pv, _AF_SAMPLES_PER_BLOCK, &l)) d->samplesPerBlock = l; else _af_error(AF_BAD_CODEC_CONFIG, "samples per block not set"); if (_af_pv_getlong(pv, _AF_BLOCK_SIZE, &l)) d->blockAlign = l; else _af_error(AF_BAD_CODEC_CONFIG, "block size not set"); *chunkframes = d->samplesPerBlock / d->track->f.channelCount; ret.modspec = d; return ret; }
int afReadFrames (AFfilehandle file, int trackid, void *samples, int nvframeswanted) { _Track *track; _AFmoduleinst *firstmod; _AFchunk *userc; AFframecount nvframesleft, nvframes2read; int bytes_per_vframe; AFframecount vframe; if (!_af_filehandle_ok(file)) return -1; if (!_af_filehandle_can_read(file)) return -1; if ((track = _af_filehandle_get_track(file, trackid)) == NULL) return -1; if (track->ms.modulesdirty) { if (_AFsetupmodules(file, track) != AF_SUCCEED) return -1; } /*if (file->seekok) {*/ if (af_fseek(file->fh, track->fpos_next_frame, SEEK_SET) < 0) { _af_error(AF_BAD_LSEEK, "unable to position read pointer at next frame"); return -1; } /* } */ if (track->totalvframes == -1) nvframes2read = nvframeswanted; else { nvframesleft = track->totalvframes - track->nextvframe; nvframes2read = (nvframeswanted > nvframesleft) ? nvframesleft : nvframeswanted; } bytes_per_vframe = _af_format_frame_size(&track->v, AF_TRUE); firstmod = &track->ms.module[track->ms.nmodules-1]; userc = &track->ms.chunk[track->ms.nmodules]; track->filemodhappy = AF_TRUE; vframe = 0; if (!track->ms.mustuseatomicnvframes) { assert(track->frames2ignore == 0); userc->buf = samples; userc->nframes = nvframes2read; (*firstmod->mod->run_pull)(firstmod); if (track->filemodhappy) vframe += userc->nframes; } else { bool eof = AF_FALSE; if (track->frames2ignore != 0) { userc->nframes = track->frames2ignore; userc->buf = _af_malloc(track->frames2ignore * bytes_per_vframe); if (userc->buf == AF_NULL) return 0; (*firstmod->mod->run_pull)(firstmod); /* Have we hit EOF? */ if (userc->nframes < track->frames2ignore) eof = AF_TRUE; track->frames2ignore = 0; free(userc->buf); userc->buf = NULL; } /* Now start reading useful frames, until EOF or premature EOF. */ while (track->filemodhappy && !eof && vframe < nvframes2read) { AFframecount nvframes2pull; userc->buf = (char *) samples + bytes_per_vframe * vframe; if (vframe <= nvframes2read - _AF_ATOMIC_NVFRAMES) nvframes2pull = _AF_ATOMIC_NVFRAMES; else nvframes2pull = nvframes2read - vframe; userc->nframes = nvframes2pull; (*firstmod->mod->run_pull)(firstmod); if (track->filemodhappy) { vframe += userc->nframes; if (userc->nframes < nvframes2pull) eof = AF_TRUE; } } } track->nextvframe += vframe; return vframe; }