bool _af_ms_adpcm_format_ok (_AudioFormat *f) { if (f->channelCount != 1 && f->channelCount != 2) { _af_error(AF_BAD_COMPRESSION, "MS ADPCM compression requires 1 or 2 channels"); return false; } if (f->sampleFormat != AF_SAMPFMT_TWOSCOMP || f->sampleWidth != 16) { _af_error(AF_BAD_COMPRESSION, "MS ADPCM compression requires 16-bit signed integer format"); f->sampleFormat = AF_SAMPFMT_TWOSCOMP; f->sampleWidth = 16; /* non-fatal */ } if (f->byteOrder != AF_BYTEORDER_BIGENDIAN) { _af_error(AF_BAD_COMPRESSION, "MS ADPCM compression requires big endian format"); f->byteOrder = AF_BYTEORDER_BIGENDIAN; /* non-fatal */ } return true; }
bool _af_ima_adpcm_format_ok (_AudioFormat *f) { if (f->channelCount != 1) { _af_error(AF_BAD_COMPRESSION, "IMA ADPCM compression requires 1 channel"); return AF_FALSE; } if (f->sampleFormat != AF_SAMPFMT_TWOSCOMP || f->sampleWidth != 16) { _af_error(AF_BAD_COMPRESSION, "IMA ADPCM compression requires 16-bit signed integer format"); f->sampleFormat = AF_SAMPFMT_TWOSCOMP; f->sampleWidth = 16; /* non-fatal */ } if (f->byteOrder != AF_BYTEORDER_BIGENDIAN) { _af_error(AF_BAD_COMPRESSION, "IMA ADPCM compression requires big endian format"); f->byteOrder = AF_BYTEORDER_BIGENDIAN; /* non-fatal */ } return AF_TRUE; }
void *_af_malloc (size_t size) { void *p; if (size <= 0) { _af_error(AF_BAD_MALLOC, "bad memory allocation size request %lu", (unsigned long)size); return NULL; } p = malloc(size); #ifdef AF_DEBUG if (p) memset(p, 0xff, size); #endif if (p == NULL) { _af_error(AF_BAD_MALLOC, "allocation of %lu bytes failed", (unsigned long)size); return NULL; } return p; }
void g711run_push (_AFmoduleinst *i) { g711_data *d = (g711_data *)i->modspec; AFframecount frames2write = i->inc->nframes; AFframecount samps2write = i->inc->nframes * i->inc->f.channelCount; int framesize = sizeof (g711samp) * (i->inc->f.channelCount); AFframecount nfr; assert(d->trk->f.compressionType == AF_COMPRESSION_G711_ULAW || d->trk->f.compressionType == AF_COMPRESSION_G711_ALAW); /* Compress frames into i->outc. */ if (d->trk->f.compressionType == AF_COMPRESSION_G711_ULAW) linear2ulaw_buf(i->inc->buf, i->outc->buf, samps2write); else linear2alaw_buf(i->inc->buf, i->outc->buf, samps2write); /* Write the compressed data. */ nfr = af_fwrite(i->outc->buf, framesize, frames2write, d->fh); CHNK(printf("writing %d frames to g711 file\n", frames2write)); if (nfr != frames2write) { /* report error if we haven't already */ if (d->trk->filemodhappy) { /* i/o error */ if (nfr < 0) _af_error(AF_BAD_WRITE, "unable to write data (%s) -- " "wrote %d out of %d frames", strerror(errno), d->trk->nextfframe + nfr, d->trk->nextfframe + frames2write); /* usual disk full error */ else _af_error(AF_BAD_WRITE, "unable to write data (disk full) -- " "wrote %d out of %d frames", d->trk->nextfframe + nfr, d->trk->nextfframe + frames2write); d->trk->filemodhappy = AF_FALSE; } } d->trk->nextfframe += nfr; d->trk->totalfframes = d->trk->nextfframe; d->trk->fpos_next_frame += (nfr>0) ? nfr/framesize : 0; assert(!d->seekok || (af_ftell(d->fh) == d->trk->fpos_next_frame)); }
/* This routine gets instrument parameters. npv is number of valid AUpvlist pairs */ void _af_instparam_get (AFfilehandle file, int instid, AUpvlist pvlist, int npv, bool forceLong) { int i, instno, j; if (!_af_filehandle_ok(file)) return; if ((instno = _af_handle_instrument_index_from_id(file, instid)) == -1) return; if (AUpvgetmaxitems(pvlist) < npv) npv = AUpvgetmaxitems(pvlist); for (i=0; i < npv; i++) { int param; int type; AUpvgetparam(pvlist, i, ¶m); if ((j = _af_instparam_index_from_id(file->fileFormat, param)) == -1) /* no parameter with that id; ignore */ continue; type = _af_units[file->fileFormat].instrumentParameters[j].type; /* forceLong is true when this routine called by afGetInstParamLong(). */ if (forceLong && type != AU_PVTYPE_LONG) { _af_error(AF_BAD_INSTPTYPE, "type of instrument parameter %d is not AU_PVTYPE_LONG", param); continue; } AUpvsetvaltype(pvlist, i, type); switch (type) { case AU_PVTYPE_LONG: AUpvsetval(pvlist, i, &file->instruments[instno].values[j].l); break; case AU_PVTYPE_DOUBLE: AUpvsetval(pvlist, i, &file->instruments[instno].values[j].d); break; case AU_PVTYPE_PTR: AUpvsetval(pvlist, i, &file->instruments[instno].values[j].v); break; default: _af_error(AF_BAD_INSTPTYPE, "invalid instrument parameter type %d", type); return; } } }
AFfilesetup CAFFile::completeSetup(AFfilesetup setup) { if (setup->trackSet && setup->trackCount != 1) { _af_error(AF_BAD_NUMTRACKS, "CAF file must have 1 track"); return AF_NULL_FILESETUP; } TrackSetup *track = &setup->tracks[0]; if (track->sampleFormatSet) { if (track->f.isUnsigned()) { _af_error(AF_BAD_FILEFMT, "CAF format does not support unsigned data"); return AF_NULL_FILESETUP; } } else _af_set_sample_format(&track->f, AF_SAMPFMT_TWOSCOMP, track->f.sampleWidth); if (track->f.isSigned() && (track->f.sampleWidth < 1 || track->f.sampleWidth > 32)) { _af_error(AF_BAD_WIDTH, "invalid sample width %d for CAF file (must be 1-32)", track->f.sampleWidth); return AF_NULL_FILESETUP; } if (!track->byteOrderSet) track->f.byteOrder = _AF_BYTEORDER_NATIVE; if (track->f.compressionType != AF_COMPRESSION_NONE && track->f.compressionType != AF_COMPRESSION_G711_ULAW && track->f.compressionType != AF_COMPRESSION_G711_ALAW && track->f.compressionType != AF_COMPRESSION_IMA) { _af_error(AF_BAD_COMPTYPE, "compression format %d not supported in CAF file", track->f.compressionType); return AF_NULL_FILESETUP; } if (track->markersSet && track->markerCount) { _af_error(AF_BAD_NOT_IMPLEMENTED, "CAF does not yet support markers"); return AF_NULL_FILESETUP; } return _af_filesetup_copy(setup, &cafDefaultFileSetup, true); }
/* _af_filesetup_ok and _af_filehandle_ok are sanity check routines which are called at the beginning of every external subroutine. */ bool _af_filesetup_ok (AFfilesetup setup) { if (setup == AF_NULL_FILESETUP) { _af_error(AF_BAD_FILESETUP, "null file setup"); return false; } if (setup->valid != _AF_VALID_FILESETUP) { _af_error(AF_BAD_FILESETUP, "invalid file setup"); return false; } return true; }
bool _af_filehandle_ok (AFfilehandle file) { if (file == AF_NULL_FILEHANDLE) { _af_error(AF_BAD_FILEHANDLE, "null file handle"); return false; } if (file->m_valid != _AF_VALID_FILEHANDLE) { _af_error(AF_BAD_FILEHANDLE, "invalid file handle"); return false; } return true; }
status RawFile::readInit(AFfilesetup fileSetup) { if (!fileSetup) { _af_error(AF_BAD_FILESETUP, "a valid AFfilesetup is required for reading raw data"); return AF_FAIL; } if (initFromSetup(fileSetup) == AF_FAIL) return AF_FAIL; TrackSetup *trackSetup = fileSetup->getTrack(); if (!trackSetup) return AF_FAIL; Track *track = getTrack(); /* Set the track's data offset. */ if (trackSetup->dataOffsetSet) track->fpos_first_frame = trackSetup->dataOffset; else track->fpos_first_frame = 0; /* Set the track's frame count. */ if (trackSetup->frameCountSet) { track->totalfframes = trackSetup->frameCount; } else { AFfileoffset filesize = m_fh->length(); if (filesize == -1) track->totalfframes = -1; else { /* Ensure that the data offset is valid. */ if (track->fpos_first_frame > filesize) { _af_error(AF_BAD_FILESETUP, "data offset is larger than file size"); return AF_FAIL; } filesize -= track->fpos_first_frame; track->totalfframes = filesize / (int) _af_format_frame_size(&track->f, false); } track->data_size = filesize; } return AF_SUCCEED; }
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); }
static status next_write_header (AFfilehandle file) { _Track *track; int frameSize; u_int32_t offset, length, encoding, sampleRate, channelCount; track = _af_filehandle_get_track(file, AF_DEFAULT_TRACK); frameSize = _af_format_frame_size(&track->f, AF_FALSE); if (track->f.compressionType == AF_COMPRESSION_G711_ULAW || track->f.compressionType == AF_COMPRESSION_G711_ALAW) frameSize = frameSize / 2; offset = HOST_TO_BENDIAN_INT32(track->fpos_first_frame); length = HOST_TO_BENDIAN_INT32(track->totalfframes * frameSize); encoding = HOST_TO_BENDIAN_INT32(nextencodingtype(&track->f)); sampleRate = HOST_TO_BENDIAN_INT32(track->f.sampleRate); channelCount = HOST_TO_BENDIAN_INT32(track->f.channelCount); if (af_fseek(file->fh, 0, SEEK_SET) != 0) _af_error(AF_BAD_LSEEK, "bad seek"); af_fwrite(".snd", 4, 1, file->fh); af_fwrite(&offset, 4, 1, file->fh); af_fwrite(&length, 4, 1, file->fh); af_fwrite(&encoding, 4, 1, file->fh); af_fwrite(&sampleRate, 4, 1, file->fh); af_fwrite(&channelCount, 4, 1, file->fh); return AF_SUCCEED; }
void afSetMarkPosition (AFfilehandle file, int trackid, int markid, AFframecount position) { if (!_af_filehandle_ok(file)) return; if (!file->checkCanWrite()) return; Track *track = file->getTrack(trackid); if (!track) return; Marker *marker = track->getMarker(markid); if (!marker) return; if (position < 0) { #ifdef __WXOSX__ _af_error(AF_BAD_MARKPOS, "invalid marker position %jd", #else _af_error(AF_BAD_MARKPOS, "invalid marker position %"PRId64, #endif static_cast<intmax_t>(position)); position = 0; }
static status next_write_header (AFfilehandle file) { _Track *track; int frameSize; uint32_t offset, length, encoding, sampleRate, channelCount; track = _af_filehandle_get_track(file, AF_DEFAULT_TRACK); frameSize = _af_format_frame_size(&track->f, false); offset = track->fpos_first_frame; length = track->totalfframes * frameSize; encoding = nextencodingtype(&track->f); sampleRate = track->f.sampleRate; channelCount = track->f.channelCount; if (af_fseek(file->fh, 0, SEEK_SET) != 0) _af_error(AF_BAD_LSEEK, "bad seek"); af_fwrite(".snd", 4, 1, file->fh); af_write_uint32_be(&offset, file->fh); af_write_uint32_be(&length, file->fh); af_write_uint32_be(&encoding, file->fh); af_write_uint32_be(&sampleRate, file->fh); af_write_uint32_be(&channelCount, file->fh); return AF_SUCCEED; }
AUpvlist afQuery (int querytype, int arg1, int arg2, int arg3, int arg4) { switch (querytype) { case AF_QUERYTYPE_INST: return _afQueryInstrument(arg1, arg2, arg3, arg4); case AF_QUERYTYPE_INSTPARAM: return _afQueryInstrumentParameter(arg1, arg2, arg3, arg4); case AF_QUERYTYPE_LOOP: return _afQueryLoop(arg1, arg2, arg3, arg4); case AF_QUERYTYPE_FILEFMT: return _afQueryFileFormat(arg1, arg2, arg3, arg4); case AF_QUERYTYPE_COMPRESSION: return _afQueryCompression(arg1, arg2, arg3, arg4); case AF_QUERYTYPE_COMPRESSIONPARAM: /* FIXME: This selector is not implemented. */ return AU_NULL_PVLIST; case AF_QUERYTYPE_MISC: /* FIXME: This selector is not implemented. */ return AU_NULL_PVLIST; case AF_QUERYTYPE_MARK: return _afQueryMarker(arg1, arg2, arg3, arg4); } _af_error(AF_BAD_QUERYTYPE, "bad query type"); return AU_NULL_PVLIST; }
/* Set the sampleFormat and sampleWidth fields in f, and set the PCM info to the appropriate default values for the given sample format and sample width. */ status _af_set_sample_format (AudioFormat *f, int sampleFormat, int sampleWidth) { switch (sampleFormat) { case AF_SAMPFMT_UNSIGNED: case AF_SAMPFMT_TWOSCOMP: if (sampleWidth < 1 || sampleWidth > 32) { _af_error(AF_BAD_SAMPFMT, "illegal sample width %d for integer data", sampleWidth); return AF_FAIL; } else { int bytes; f->sampleFormat = sampleFormat; f->sampleWidth = sampleWidth; bytes = _af_format_sample_size_uncompressed(f, false); if (sampleFormat == AF_SAMPFMT_TWOSCOMP) f->pcm = _af_default_signed_integer_pcm_mappings[bytes]; else f->pcm = _af_default_unsigned_integer_pcm_mappings[bytes]; } break; case AF_SAMPFMT_FLOAT: f->sampleFormat = sampleFormat; f->sampleWidth = 32; f->pcm = _af_default_float_pcm_mapping; break; case AF_SAMPFMT_DOUBLE: f->sampleFormat = sampleFormat; f->sampleWidth = 64; /*for convenience */ f->pcm = _af_default_double_pcm_mapping; break; default: _af_error(AF_BAD_SAMPFMT, "unknown sample format %d", sampleFormat); return AF_FAIL; } return AF_SUCCEED; }
_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 *_af_realloc (void *p, size_t size) { if (size <= 0) { _af_error(AF_BAD_MALLOC, "bad memory allocation size request %lu", (unsigned long)size); return NULL; } p = realloc(p, size); if (p == NULL) { _af_error(AF_BAD_MALLOC, "allocation of %lu bytes failed", (unsigned long)size); return NULL; } return p; }
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'; }
Loop *Instrument::getLoop(int loopID) { for (int i=0; i<loopCount; i++) if (loops[i].id == loopID) return &loops[i]; _af_error(AF_BAD_LOOPID, "no loop with id %d for instrument %d\n", loopID, id); return NULL; }
bool _af_filehandle_can_read (AFfilehandle file) { if (file->access != _AF_READ_ACCESS) { _af_error(AF_BAD_NOREADACC, "file not opened for read access"); return false; } return true; }
bool _af_filehandle_can_write (AFfilehandle file) { if (file->access != _AF_WRITE_ACCESS) { _af_error(AF_BAD_NOWRITEACC, "file not opened for write access"); return false; } return true; }
int _af_handle_instrument_index_from_id (AFfilehandle file, int id) { int i; for (i = 0; i < file->instrumentCount; i++) if (file->instruments[i].id == id) return i; _af_error(AF_BAD_INSTID, "invalid instrument id %d", id); return -1; }
Marker *Track::getMarker(int markerID) { for (int i=0; i<markerCount; i++) if (markers[i].id == markerID) return &markers[i]; _af_error(AF_BAD_MARKID, "no marker with id %d found in track %d", markerID, id); return NULL; }
int _af_setup_instrument_index_from_id (AFfilesetup setup, int id) { int i; for (i = 0; i < setup->instrumentCount; i++) if (setup->instruments[i].id == id) return i; _af_error(AF_BAD_INSTID, "invalid instrument id %d", id); return -1; }
int _af_handle_loop_index_from_id (AFfilehandle file, int instno, int loopid) { int i; for (i=0; i<file->instruments[instno].loopCount; i++) if (file->instruments[instno].loops[i].id == loopid) return i; _af_error(AF_BAD_LOOPID, "no loop with id %d for instrument %d", loopid, file->instruments[instno].id); return -1; }
static void ms_adpcm_run_pull (_AFmoduleinst *module) { ms_adpcm_data *d = (ms_adpcm_data *) module->modspec; AFframecount frames2read = module->outc->nframes; AFframecount nframes = 0; int i, framesPerBlock, blockCount; ssize_t blocksRead, bytesDecoded; framesPerBlock = d->framesPerBlock; assert(module->outc->nframes % framesPerBlock == 0); blockCount = module->outc->nframes / framesPerBlock; /* Read the compressed frames. */ blocksRead = af_fread(module->inc->buf, d->blockAlign, blockCount, d->fh); /* Decompress into module->outc. */ for (i=0; i<blockCount; i++) { bytesDecoded = ms_adpcm_decode_block(d, (const uint8_t *) module->inc->buf + i * d->blockAlign, (int16_t *) module->outc->buf + i * d->framesPerBlock * d->track->f.channelCount); nframes += framesPerBlock; } d->track->nextfframe += nframes; if (blocksRead > 0) d->track->fpos_next_frame += blocksRead * d->blockAlign; assert(af_ftell(d->fh) == d->track->fpos_next_frame); /* If we got EOF from read, then we return the actual amount read. Complain only if there should have been more frames in the file. */ if (d->track->totalfframes != -1 && nframes != frames2read) { /* Report error if we haven't already */ if (d->track->filemodhappy) { _af_error(AF_BAD_READ, "file missing data -- read %d frames, should be %d", d->track->nextfframe, d->track->totalfframes); d->track->filemodhappy = false; } } module->outc->nframes = nframes; }
bool _af_g711_format_ok (_AudioFormat *f) { if (f->sampleFormat != AF_SAMPFMT_TWOSCOMP || f->sampleWidth != 16) { _af_error(AF_BAD_COMPRESSION, "G711 compression requires 16-bit signed integer format"); f->sampleFormat = AF_SAMPFMT_TWOSCOMP; f->sampleWidth = 16; /* non-fatal */ } if (f->byteOrder != AF_BYTEORDER_BIGENDIAN) { _af_error(AF_BAD_COMPRESSION, "G711 compression requires big endian format"); f->byteOrder = AF_BYTEORDER_BIGENDIAN; /* non-fatal */ } return AF_TRUE; }
void *_af_calloc (size_t nmemb, size_t size) { void *p; if (nmemb <= 0 || size <= 0) { _af_error(AF_BAD_MALLOC, "bad memory allocation size request " "%lu elements of %lu bytes each", (unsigned long)nmemb, (unsigned long)size); return NULL; } p = calloc(nmemb, size); if (p == NULL) { _af_error(AF_BAD_MALLOC, "allocation of %lu bytes failed", (unsigned long)nmemb*size); return NULL; } return p; }
/* ARGSUSED2 */ AUpvlist _afQueryMarker (int arg1, int arg2, int arg3, int arg4) { switch (arg1) { case AF_QUERY_SUPPORTED: return _af_pv_long(_af_units[arg2].markerCount != 0); case AF_QUERY_MAX_NUMBER: return _af_pv_long(_af_units[arg2].markerCount); } _af_error(AF_BAD_QUERY, "bad query selector"); return AU_NULL_PVLIST; }
void afInitFileFormat (AFfilesetup setup, int filefmt) { if (!_af_filesetup_ok(setup)) return; if (filefmt < 0 || filefmt >= _AF_NUM_UNITS) { _af_error(AF_BAD_FILEFMT, "unrecognized file format %d", filefmt); return; } if (!_af_units[filefmt].implemented) { _af_error(AF_BAD_NOT_IMPLEMENTED, "%s format not currently supported", _af_units[filefmt].name); return; } setup->fileFormat = filefmt; }