diff options
Diffstat (limited to 'libaudiofile/format.c')
-rw-r--r-- | libaudiofile/format.c | 396 |
1 files changed, 396 insertions, 0 deletions
diff --git a/libaudiofile/format.c b/libaudiofile/format.c new file mode 100644 index 0000000..6ee0361 --- /dev/null +++ b/libaudiofile/format.c @@ -0,0 +1,396 @@ +/* + Audio File Library + Copyright (C) 1998-2000, Michael Pruett <michael@68k.org> + Copyright (C) 2000, Silicon Graphics, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307 USA. +*/ + +/* + audiofile.c + + This file implements many of the main interface routines of the + Audio File Library. +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "audiofile.h" +#include "util.h" +#include "afinternal.h" +#include "afinternal.h" +#include "units.h" +#include "modules.h" + +extern _Unit _af_units[]; + +AFfileoffset afGetDataOffset (AFfilehandle file, int trackid) +{ + _Track *track; + + if (!_af_filehandle_ok(file)) + return -1; + + if ((track = _af_filehandle_get_track(file, trackid)) == NULL) + return -1; + + return track->fpos_first_frame; +} + +AFfileoffset afGetTrackBytes (AFfilehandle file, int trackid) +{ + _Track *track; + + if (!_af_filehandle_ok(file)) + return -1; + + track = _af_filehandle_get_track(file, trackid); + + return track->data_size; +} + +/* + afGetFrameSize returns the size (in bytes) of a sample frame from + the specified track of an audio file. + + stretch3to4 == AF_TRUE: size which user sees + stretch3to4 == AF_FALSE: size used in file +*/ +float afGetFrameSize (AFfilehandle file, int trackid, int stretch3to4) +{ + _Track *track; + + if (!_af_filehandle_ok(file)) + return -1; + + if ((track = _af_filehandle_get_track(file, trackid)) == NULL) + return -1; + + return _af_format_frame_size(&track->f, stretch3to4); +} + +float afGetVirtualFrameSize (AFfilehandle file, int trackid, int stretch3to4) +{ + _Track *track; + + if (!_af_filehandle_ok(file)) + return -1; + + if ((track = _af_filehandle_get_track(file, trackid)) == NULL) + return -1; + + return _af_format_frame_size(&track->v, stretch3to4); +} + +AFframecount afSeekFrame (AFfilehandle file, int trackid, AFframecount frame) +{ + _Track *track; + + 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 (frame < 0) + return track->nextvframe; + + /* Optimize the case of seeking to the current position. */ + if (frame == track->nextvframe) + return track->nextvframe; + + /* Limit request to the number of frames in the file. */ + if (track->totalvframes != -1) + if (frame > track->totalvframes) + frame = track->totalvframes - 1; + + /* + Now that the modules are not dirty and frame + represents a valid virtual frame, we call + _AFsetupmodules again after setting track->nextvframe. + + _AFsetupmodules will look at track->nextvframe and + compute track->nextfframe in clever and mysterious + ways. + */ + track->nextvframe = frame; + + if (_AFsetupmodules(file, track) != AF_SUCCEED) + return -1; + + return track->nextvframe; +} + +AFfileoffset afTellFrame (AFfilehandle file, int trackid) +{ + return afSeekFrame(file, trackid, -1); +} + +int afSetVirtualByteOrder (AFfilehandle handle, int track, int byteorder) +{ + _Track *currentTrack; + + if (!_af_filehandle_ok(handle)) + return -1; + + if (NULL == (currentTrack = _af_filehandle_get_track(handle, track))) + return AF_FAIL; + + if (byteorder != AF_BYTEORDER_BIGENDIAN && + byteorder != AF_BYTEORDER_LITTLEENDIAN) + { + _af_error(AF_BAD_BYTEORDER, "invalid byte order %d", byteorder); + return AF_FAIL; + } + + currentTrack->v.byteOrder = byteorder; + currentTrack->ms.modulesdirty = AF_TRUE; + + return AF_SUCCEED; +} + +int afGetByteOrder (AFfilehandle handle, int track) +{ + _Track *currentTrack; + + if (!_af_filehandle_ok(handle)) + return -1; + + if ((currentTrack = _af_filehandle_get_track(handle, track)) == NULL) + return -1; + + return (currentTrack->f.byteOrder); +} + +int afGetVirtualByteOrder (AFfilehandle handle, int track) +{ + _Track *currentTrack; + + if (!_af_filehandle_ok(handle)) + return -1; + + if ((currentTrack = _af_filehandle_get_track(handle, track)) == NULL) + return -1; + + return (currentTrack->v.byteOrder); +} + +AFframecount afGetFrameCount (AFfilehandle file, int trackid) +{ + _Track *track; + + if (!_af_filehandle_ok(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; + } + + return track->totalvframes; +} + +double afGetRate (AFfilehandle file, int trackid) +{ + _Track *track; + + if ((track = _af_filehandle_get_track(file, trackid)) == NULL) + return -1; + + return track->f.sampleRate; +} + +int afGetChannels (AFfilehandle file, int trackid) +{ + _Track *track; + + if ((track = _af_filehandle_get_track(file, trackid)) == NULL) + return -1; + + return track->f.channelCount; +} + +void afGetSampleFormat (AFfilehandle file, int trackid, int *sampleFormat, int *sampleWidth) +{ + _Track *track; + + if ((track = _af_filehandle_get_track(file, trackid)) == NULL) + return; + + if (sampleFormat != NULL) + *sampleFormat = track->f.sampleFormat; + + if (sampleFormat != NULL) + *sampleWidth = track->f.sampleWidth; +} + +void afGetVirtualSampleFormat (AFfilehandle file, int trackid, int *sampleFormat, int *sampleWidth) +{ + _Track *track; + + if ((track = _af_filehandle_get_track(file, trackid)) == NULL) + return; + + if (sampleFormat != NULL) + *sampleFormat = track->v.sampleFormat; + + if (sampleFormat != NULL) + *sampleWidth = track->v.sampleWidth; +} + +int afSetVirtualSampleFormat (AFfilehandle file, int trackid, + int sampleFormat, int sampleWidth) +{ + _Track *track; + + if (!_af_filehandle_ok(file)) + return -1; + + if ((track = _af_filehandle_get_track(file, trackid)) == NULL) + return -1; + + if (_af_set_sample_format(&track->v, sampleFormat, sampleWidth) == AF_FAIL) + return -1; + + track->ms.modulesdirty = AF_TRUE; + + return 0; +} + +/* XXXmpruett fix the version */ +int afGetFileFormat (AFfilehandle file, int *version) +{ + if (!_af_filehandle_ok(file)) + return -1; + + if (version != NULL) + { + if (_af_units[file->fileFormat].getversion) + *version = _af_units[file->fileFormat].getversion(file); + else + *version = 0; + } + + return file->fileFormat; +} + +int afSetVirtualChannels (AFfilehandle file, int trackid, int channelCount) +{ + _Track *track; + + if (!_af_filehandle_ok(file)) + return -1; + + if ((track = _af_filehandle_get_track(file, trackid)) == NULL) + return -1; + + track->v.channelCount = channelCount; + track->ms.modulesdirty = AF_TRUE; + + if (track->channelMatrix) + free(track->channelMatrix); + track->channelMatrix = NULL; + + return 0; +} + +double afGetVirtualRate (AFfilehandle file, int trackid) +{ + _Track *track; + + if ((track = _af_filehandle_get_track(file, trackid)) == NULL) + return -1; + + return track->v.sampleRate; +} + +int afSetVirtualRate (AFfilehandle file, int trackid, double rate) +{ + _Track *track; + + if (!_af_filehandle_ok(file)) + return -1; + + if ((track = _af_filehandle_get_track(file, trackid)) == NULL) + return -1; + + if (rate < 0) + { + _af_error(AF_BAD_RATE, "invalid sampling rate %.30g", rate); + return -1; + } + + track->v.sampleRate = rate; + track->ms.modulesdirty = AF_TRUE; + + return 0; +} + +void afSetChannelMatrix (AFfilehandle file, int trackid, double* matrix) +{ + _Track *track; + + if (!_af_filehandle_ok(file)) + return; + + if ((track = _af_filehandle_get_track(file, trackid)) == NULL) + return; + + if (track->channelMatrix != NULL) + free(track->channelMatrix); + track->channelMatrix = NULL; + + if (matrix != NULL) + { + int i, size; + + size = track->v.channelCount * track->f.channelCount; + + track->channelMatrix = (double *) malloc(size * sizeof (double)); + + for (i = 0; i < size; i++) + track->channelMatrix[i] = matrix[i]; + } +} + +int afGetVirtualChannels (AFfilehandle file, int trackid) +{ + _Track *track; + + if ((track = _af_filehandle_get_track(file, trackid)) == NULL) + return -1; + + return track->v.channelCount; +} |