source: trunk/third/audiofile/libaudiofile/setup.c @ 17099

Revision 17099, 16.9 KB checked in by ghudson, 23 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r17098, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2        Audio File Library
3        Copyright (C) 2000, Silicon Graphics, Inc.
4
5        This library is free software; you can redistribute it and/or
6        modify it under the terms of the GNU Library General Public
7        License as published by the Free Software Foundation; either
8        version 2 of the License, or (at your option) any later version.
9
10        This library is distributed in the hope that it will be useful,
11        but WITHOUT ANY WARRANTY; without even the implied warranty of
12        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13        Library General Public License for more details.
14
15        You should have received a copy of the GNU Library General Public
16        License along with this library; if not, write to the
17        Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18        Boston, MA  02111-1307  USA.
19*/
20
21/*
22        setup.c
23*/
24
25#ifdef HAVE_CONFIG_H
26#include <config.h>
27#endif
28
29#include <stdlib.h>
30#include <string.h>
31
32#include <audiofile.h>
33
34#include "afinternal.h"
35#include "pcm.h"
36#include "util.h"
37#include "units.h"
38#include "marker.h"
39
40extern _Unit _af_units[];
41
42_AFfilesetup _af_default_file_setup =
43{
44        _AF_VALID_FILESETUP,    /* valid */
45#if WORDS_BIGENDIAN
46        AF_FILE_AIFFC,  /* file format */
47#else
48        AF_FILE_WAVE,   /* file format */
49#endif
50        AF_FALSE,       /* trackSet */
51        AF_FALSE,       /* instrumentSet */
52        AF_FALSE,       /* miscellaneousSet */
53        1,              /* trackCount */
54        NULL,           /* tracks */
55        1,              /* instrumentCount */
56        NULL,           /* instruments */
57        0,              /* miscellaneousCount */
58        NULL            /* miscellaneous */
59};
60
61_InstrumentSetup _af_default_instrumentsetup =
62{
63        0,              /* id */
64        2,              /* loopCount */
65        NULL,           /* loops */
66        AF_FALSE        /* loopSet */
67};
68
69_TrackSetup _af_default_tracksetup =
70{
71        0,
72        {
73                44100.0,
74                AF_SAMPFMT_TWOSCOMP,
75                16,
76#if WORDS_BIGENDIAN
77                AF_BYTEORDER_BIGENDIAN,
78#else
79                AF_BYTEORDER_LITTLEENDIAN,
80#endif
81                { SLOPE_INT16, 0, MIN_INT16, MAX_INT16 },
82                2,
83                AF_COMPRESSION_NONE,
84                NULL
85        },
86        AF_FALSE,       /* rateSet */
87        AF_FALSE,       /* sampleFormatSet */
88        AF_FALSE,       /* sampleWidthSet */
89        AF_FALSE,       /* byteOrderSet */
90        AF_FALSE,       /* channelCountSet */
91        AF_FALSE,       /* compressionSet */
92        AF_FALSE,       /* aesDataSet */
93        AF_FALSE,       /* markersSet */
94        AF_FALSE,       /* dataOffsetSet */
95        AF_FALSE,       /* frameCountSet */
96
97        4,              /* markerCount */
98        NULL,           /* markers */
99        0,              /* dataOffset */
100        0               /* frameCount */
101};
102
103_TrackSetup *_af_tracksetup_new (int trackCount)
104{
105        int             i;
106        _TrackSetup     *tracks;
107
108        if (trackCount == 0)
109                return NULL;
110
111        tracks = _af_calloc(trackCount, sizeof (_TrackSetup));
112        if (tracks == NULL)
113                return NULL;
114
115        for (i=0; i<trackCount; i++)
116        {
117                tracks[i] = _af_default_tracksetup;
118
119                tracks[i].id = AF_DEFAULT_TRACK + i;
120
121                /* XXXmpruett deal with compression */
122
123                _af_set_sample_format(&tracks[i].f, tracks[i].f.sampleFormat,
124                        tracks[i].f.sampleWidth);
125
126                if (tracks[i].markerCount == 0)
127                        tracks[i].markers = NULL;
128                else
129                {
130                        int     j;
131                        tracks[i].markers = _af_calloc(tracks[i].markerCount,
132                                sizeof (_MarkerSetup));
133
134                        if (tracks[i].markers == NULL)
135                                return NULL;
136
137                        for (j=0; j<tracks[i].markerCount; j++)
138                        {
139                                tracks[i].markers[j].id = j+1;
140
141                                tracks[i].markers[j].name = _af_strdup("");
142                                if (tracks[i].markers[j].name == NULL)
143                                        return NULL;
144
145                                tracks[i].markers[j].comment = _af_strdup("");
146                                if (tracks[i].markers[j].comment == NULL)
147                                        return NULL;
148                        }
149                }
150        }
151
152        return tracks;
153}
154
155_InstrumentSetup *_af_instsetup_new (int instrumentCount)
156{
157        int     i;
158
159        _InstrumentSetup        *instruments;
160
161        if (instrumentCount == 0)
162                return NULL;
163        instruments = _af_calloc(instrumentCount, sizeof (_InstrumentSetup));
164        if (instruments == NULL)
165                return NULL;
166
167        for (i=0; i<instrumentCount; i++)
168        {
169                instruments[i] = _af_default_instrumentsetup;
170                instruments[i].id = AF_DEFAULT_INST + i;
171                if (instruments[i].loopCount == 0)
172                        instruments[i].loops = NULL;
173                else
174                {
175                        int     j;
176                        instruments[i].loops = _af_calloc(instruments[i].loopCount, sizeof (_LoopSetup));
177                        if (instruments[i].loops == NULL)
178                                return NULL;
179
180                        for (j=0; j<instruments[i].loopCount; j++)
181                                instruments[i].loops[j].id = j+1;
182                }
183        }
184
185        return instruments;
186}
187
188AFfilesetup afNewFileSetup (void)
189{
190        AFfilesetup     setup;
191
192        setup = _af_malloc(sizeof (_AFfilesetup));
193        if (setup == NULL) return AF_NULL_FILESETUP;
194
195        *setup = _af_default_file_setup;
196
197        setup->tracks = _af_tracksetup_new(setup->trackCount);
198
199        setup->instruments = _af_instsetup_new(setup->instrumentCount);
200
201        if (setup->miscellaneousCount == 0)
202                setup->miscellaneous = NULL;
203        else
204        {
205                int     i;
206
207                setup->miscellaneous = _af_calloc(setup->miscellaneousCount,
208                        sizeof (_MiscellaneousSetup));
209                for (i=0; i<setup->miscellaneousCount; i++)
210                {
211                        setup->miscellaneous[i].id = i+1;
212                        setup->miscellaneous[i].type = 0;
213                        setup->miscellaneous[i].size = 0;
214                }
215        }
216
217        return setup;
218}
219
220/*
221        Free the specified track's markers and their subfields.
222*/
223void _af_setup_free_markers (AFfilesetup setup, int trackno)
224{
225        if (setup->tracks[trackno].markerCount != 0)
226        {
227                int     i;
228                for (i=0; i<setup->tracks[trackno].markerCount; i++)
229                {
230                        free(setup->tracks[trackno].markers[i].name);
231                        free(setup->tracks[trackno].markers[i].comment);
232                }
233
234                free(setup->tracks[trackno].markers);
235        }
236
237        setup->tracks[trackno].markers = NULL;
238        setup->tracks[trackno].markerCount = 0;
239}
240
241/*
242        Free the specified setup's tracks and their subfields.
243*/
244void _af_setup_free_tracks (AFfilesetup setup)
245{
246        int     i;
247
248        if (setup->tracks)
249        {
250                for (i=0; i<setup->trackCount; i++)
251                {
252                        _af_setup_free_markers(setup, i);
253                }
254
255                free(setup->tracks);
256        }
257
258        setup->tracks = NULL;
259        setup->trackCount = 0;
260}
261
262/*
263        Free the specified instrument's loops.
264*/
265void _af_setup_free_loops (AFfilesetup setup, int instno)
266{
267        if (setup->instruments[instno].loops)
268        {
269                free(setup->instruments[instno].loops);
270        }
271
272        setup->instruments[instno].loops = NULL;
273        setup->instruments[instno].loopCount = 0;
274}
275
276/*
277        Free the specified setup's instruments and their subfields.
278*/
279void _af_setup_free_instruments (AFfilesetup setup)
280{
281        int i;
282
283        if (setup->instruments)
284        {
285                for (i = 0; i < setup->instrumentCount; i++)
286                        _af_setup_free_loops(setup, i);
287
288                free(setup->instruments);
289        }
290
291        setup->instruments = NULL;
292        setup->instrumentCount = 0;
293}
294
295void afFreeFileSetup (AFfilesetup setup)
296{
297        if (!_af_filesetup_ok(setup))
298                return;
299
300        _af_setup_free_tracks(setup);
301
302        _af_setup_free_instruments(setup);
303
304        if (setup->miscellaneousCount)
305        {
306                free(setup->miscellaneous);
307                setup->miscellaneous = NULL;
308                setup->miscellaneousCount = 0;
309        }
310
311        memset(setup, 0, sizeof (_AFfilesetup));
312        free(setup);
313}
314
315void afInitFileFormat (AFfilesetup setup, int filefmt)
316{
317        if (!_af_filesetup_ok(setup))
318                return;
319
320        if (filefmt < 0 || filefmt > _AF_NUM_UNITS)
321        {
322                _af_error(AF_BAD_FILEFMT, "unrecognized file format %d",
323                        filefmt);
324                return;
325        }
326
327        if (_af_units[filefmt].implemented == AF_FALSE)
328        {
329                _af_error(AF_BAD_NOT_IMPLEMENTED,
330                        "%s format not currently supported",
331                        _af_units[filefmt].name);
332                return;
333        }
334
335        setup->fileFormat = filefmt;
336}
337
338void afInitChannels (AFfilesetup setup, int trackid, int channels)
339{
340        _TrackSetup     *track;
341
342        if (!_af_filesetup_ok(setup))
343                return;
344
345        if ((track = _af_filesetup_get_tracksetup(setup, trackid)) == NULL)
346                return;
347
348        if (channels < 1)
349        {
350                _af_error(AF_BAD_CHANNELS, "invalid number of channels %d",
351                        channels);
352                return;
353        }
354
355        track->f.channelCount = channels;
356        track->channelCountSet = AF_TRUE;
357}
358
359void afInitSampleFormat (AFfilesetup setup, int trackid, int sampfmt, int sampwidth)
360{
361        _TrackSetup     *track;
362
363        if (!_af_filesetup_ok(setup))
364                return;
365
366        if ((track = _af_filesetup_get_tracksetup(setup, trackid)) == NULL)
367                return;
368
369        _af_set_sample_format(&track->f, sampfmt, sampwidth);
370
371        track->sampleFormatSet = AF_TRUE;
372        track->sampleWidthSet = AF_TRUE;
373}
374
375void afInitByteOrder (AFfilesetup setup, int trackid, int byteorder)
376{
377        _TrackSetup     *track;
378
379        if (!_af_filesetup_ok(setup))
380                return;
381
382        if ((track = _af_filesetup_get_tracksetup(setup, trackid)) == NULL)
383                return;
384
385        if (byteorder != AF_BYTEORDER_BIGENDIAN &&
386                byteorder != AF_BYTEORDER_LITTLEENDIAN)
387        {
388                _af_error(AF_BAD_BYTEORDER, "invalid byte order %d", byteorder);
389                return;
390        }
391
392        track->f.byteOrder = byteorder;
393        track->byteOrderSet = AF_TRUE;
394}
395
396void afInitRate (AFfilesetup setup, int trackid, double rate)
397{
398        _TrackSetup     *track;
399
400        if (!_af_filesetup_ok(setup))
401                return;
402
403        if ((track = _af_filesetup_get_tracksetup(setup, trackid)) == NULL)
404                return;
405
406        if (rate <= 0.0)
407        {
408                _af_error(AF_BAD_RATE, "invalid sample rate %.30g", rate);
409                return;
410        }
411
412        track->f.sampleRate = rate;
413        track->rateSet = AF_TRUE;
414}
415
416/*
417        track data: data offset within the file (initialized for raw reading only)
418*/
419void afInitDataOffset (AFfilesetup setup, int trackid, AFfileoffset offset)
420{
421        _TrackSetup     *track;
422
423        if (!_af_filesetup_ok(setup))
424                return;
425
426        if ((track = _af_filesetup_get_tracksetup(setup, trackid)) == NULL)
427                return;
428
429        if (offset < 0)
430        {
431                _af_error(AF_BAD_DATAOFFSET, "invalid data offset %d", offset);
432                return;
433        }
434
435        track->dataOffset = offset;
436        track->dataOffsetSet = AF_TRUE;
437}
438
439/*
440        track data: data offset within the file (initialized for raw reading only)
441*/
442void afInitFrameCount (AFfilesetup setup, int trackid, AFfileoffset count)
443{
444        _TrackSetup     *track;
445
446        if (!_af_filesetup_ok(setup))
447                return;
448
449        if ((track = _af_filesetup_get_tracksetup(setup, trackid)) == NULL)
450                return;
451
452        if (count < 0)
453        {
454                _af_error(AF_BAD_FRAMECNT, "invalid frame count %d", count);
455                return;
456        }
457
458        track->frameCount = count;
459        track->frameCountSet = AF_TRUE;
460}
461
462#define alloccopy(type, n, var, copyfrom) \
463{ \
464        if (n == 0) \
465                var = NULL; \
466        else \
467        { \
468                if ((var = _af_calloc(n, sizeof (type))) == NULL) \
469                        goto fail; \
470                memcpy((var), (copyfrom), (n) * sizeof (type)); \
471        } \
472}
473
474AFfilesetup _af_filesetup_copy (AFfilesetup setup, AFfilesetup defaultSetup,
475        bool copyMarks)
476{
477        AFfilesetup     newsetup;
478        int             i;
479        int             instrumentCount, miscellaneousCount, trackCount;
480
481        newsetup = _af_malloc(sizeof (_AFfilesetup));
482        if (newsetup == AF_NULL_FILESETUP)
483                return AF_NULL_FILESETUP;
484
485#ifdef DEBUG
486        printf("default: trackset=%d instset=%d miscset=%d\n",
487                defaultSetup->trackSet, defaultSetup->instrumentSet,
488                defaultSetup->miscellaneousSet);
489        printf("setup: trackset=%d instset=%d miscset=%d\n",
490                setup->trackSet, setup->instrumentSet, setup->miscellaneousSet);
491#endif
492
493        *newsetup = *defaultSetup;
494
495        newsetup->tracks = NULL;
496        newsetup->instruments = NULL;
497        newsetup->miscellaneous = NULL;
498
499        /* Copy tracks. */
500        trackCount = setup->trackSet ? setup->trackCount :
501                newsetup->trackSet ? newsetup->trackCount : 0;
502        alloccopy(_TrackSetup, trackCount, newsetup->tracks, setup->tracks);
503        newsetup->trackCount = trackCount;
504
505        /* Copy instruments. */
506        instrumentCount = setup->instrumentSet ? setup->instrumentCount :
507                newsetup->instrumentSet ? newsetup->instrumentCount : 0;
508        alloccopy(_InstrumentSetup, instrumentCount, newsetup->instruments, setup->instruments);
509        newsetup->instrumentCount = instrumentCount;
510
511        /* Copy miscellaneous information. */
512        miscellaneousCount = setup->miscellaneousSet ? setup->miscellaneousCount :
513                newsetup->miscellaneousSet ? newsetup->miscellaneousCount : 0;
514        alloccopy(_MiscellaneousSetup, miscellaneousCount, newsetup->miscellaneous, setup->miscellaneous);
515        newsetup->miscellaneousCount = miscellaneousCount;
516
517        for (i=0; i<setup->trackCount; i++)
518        {
519                int     j;
520                _TrackSetup     *track = &newsetup->tracks[i];
521
522                /* XXXmpruett set compression information */
523
524                if (setup->tracks[i].markersSet == AF_FALSE &&
525                        copyMarks == AF_FALSE)
526                {
527                        track->markers = NULL;
528                        track->markerCount = 0;
529                        continue;
530                }
531
532                alloccopy(_MarkerSetup, setup->tracks[i].markerCount,
533                        track->markers, setup->tracks[i].markers);
534                track->markerCount = setup->tracks[i].markerCount;
535
536                for (j=0; j<setup->tracks[i].markerCount; j++)
537                {
538                        track->markers[j].name =
539                                _af_strdup(setup->tracks[i].markers[j].name);
540                        if (track->markers[j].name == NULL)
541                                goto fail;
542
543                        track->markers[j].comment =
544                                _af_strdup(setup->tracks[i].markers[j].comment);
545                        if (track->markers[j].comment == NULL)
546                                goto fail;
547                }
548        }
549
550        for (i=0; i<newsetup->instrumentCount; i++)
551        {
552                _InstrumentSetup        *instrument = &newsetup->instruments[i];
553                alloccopy(_LoopSetup, setup->instruments[i].loopCount,
554                        instrument->loops, setup->instruments[i].loops);
555        }
556
557        return newsetup;
558
559        fail:
560                if (newsetup->miscellaneous)
561                        free(newsetup->miscellaneous);
562                if (newsetup->instruments)
563                        free(newsetup->instruments);
564                if (newsetup->tracks)
565                        free(newsetup->tracks);
566                if (newsetup)
567                        free(newsetup);
568
569        return AF_NULL_FILESETUP;
570}
571
572/*
573        Do all the non-file-format dependent things necessary to "convert"
574        a filesetup into a filehandle.
575
576        This function assumes that the track count, instrument count,
577        etc. of given filesetup is okay for the file format.
578
579        Called from write.init and raw read.init unit functions.
580
581        This function does NOT SET ALL THE FIELDS of the filesetup.
582        You must be careful when writing a unit to set the fields
583        you are supposed to (described below).
584
585        These fields are not set here, so are somebody else's problem:
586        - handle: valid, fd, access, filename, fileFormat, seekok (set in afOpenFile)
587        - handle: formatSpecific (UNIT MUST SET! (set to NULL if no data))
588
589        - track: virtual format v, modulesdirty, nmodules, module, chunk,
590        (buffers), totalvframes, nextvframe, channelmatrix, frames2ignore
591        (these are handled by _AFinitmodules and _AFsetupmodules)
592
593        - track: totalfframes, nextfframe, fpos_first_frame,
594        fpos_next_frame, data_size (UNIT MUST SET!)
595
596        - mark: fpos_position (UNIT MUST SET!)
597*/
598
599status _af_filesetup_make_handle (AFfilesetup setup, AFfilehandle handle)
600{
601        int     i;
602
603        handle->valid = _AF_VALID_FILEHANDLE;
604
605        if ((handle->trackCount = setup->trackCount) == 0)
606                handle->tracks = NULL;
607        else
608        {
609                handle->tracks = _af_calloc(handle->trackCount, sizeof (_Track));
610                if (handle->tracks == NULL)
611                        return AF_FAIL;
612
613                for (i=0; i<handle->trackCount; i++)
614                {
615                        _Track          *track = &handle->tracks[i];
616                        _TrackSetup     *tracksetup = &setup->tracks[i];
617
618                        track->id = tracksetup->id;
619
620                        track->f = tracksetup->f;
621                        track->channelMatrix = NULL;
622
623                        /* XXXmpruett copy compression stuff too */
624
625                        if ((track->markerCount = tracksetup->markerCount) == 0)
626                                track->markers = NULL;
627                        else
628                        {
629                                int     j;
630
631                                track->markers = _af_marker_new(track->markerCount);
632                                if (track->markers == NULL)
633                                        return AF_FAIL;
634                                for (j=0; j<track->markerCount; j++)
635                                {
636                                        track->markers[j].id = tracksetup->markers[j].id;
637                                        track->markers[j].name =
638                                                _af_strdup(tracksetup->markers[j].name);
639                                        if (track->markers[j].name == NULL)
640                                                return AF_FAIL;
641
642                                        track->markers[j].comment =
643                                                _af_strdup(tracksetup->markers[j].comment);
644                                        if (track->markers[j].comment == NULL)
645                                                return AF_FAIL;
646                                        track->markers[j].position = 0;
647                                }
648                        }
649
650                        track->hasAESData = tracksetup->aesDataSet;
651
652                        track->ms.modulesdirty = AF_TRUE;
653                        track->ms.nmodules = 0;
654                        track->ms.chunk = NULL;
655                        track->ms.module = NULL;
656                        track->ms.buffer = NULL;
657
658                        track->ms.filemodinst.valid = AF_FALSE;
659                        track->ms.filemod_rebufferinst.valid = AF_FALSE;
660                        track->ms.rateconvertinst.valid = AF_FALSE;
661                        track->ms.rateconvert_rebufferinst.valid = AF_FALSE;
662                }
663        }
664
665        /* Copy instrument data. */
666        if ((handle->instrumentCount = setup->instrumentCount) == 0)
667                handle->instruments = NULL;
668        else
669        {
670                handle->instruments = _af_calloc(handle->instrumentCount,
671                        sizeof (_Instrument));
672                if (handle->instruments == NULL)
673                        return AF_FAIL;
674
675                for (i=0; i<handle->instrumentCount; i++)
676                {
677                        int     instParamCount;
678
679                        handle->instruments[i].id = setup->instruments[i].id;
680
681                        /* Copy loops. */
682                        if ((handle->instruments[i].loopCount =
683                                setup->instruments[i].loopCount) == 0)
684                                handle->instruments[i].loops = NULL;
685                        else
686                        {
687                                int     j;
688
689                                handle->instruments[i].loops = _af_calloc(handle->instruments[i].loopCount, sizeof (_Loop));
690                                if (handle->instruments[i].loops == NULL)
691                                        return AF_FAIL;
692                                for (j=0; j<handle->instruments[i].loopCount; j++)
693                                {
694                                        _Loop   *loop;
695                                        loop = &handle->instruments[i].loops[j];
696                                        loop->id = setup->instruments[i].loops[j].id;
697                                        loop->mode = AF_LOOP_MODE_NOLOOP;
698                                        loop->count = 0;
699                                        loop->trackid = AF_DEFAULT_TRACK;
700                                        loop->beginMarker = 1 + (2*j);
701                                        loop->endMarker = 2 + (2*j);
702                                }
703                        }
704
705                        /* Copy instrument parameters. */
706                        if ((instParamCount = _af_units[setup->fileFormat].instrumentParameterCount) == 0)
707                                handle->instruments[i].values = NULL;
708                        else
709                        {
710                                int     j;
711                                handle->instruments[i].values = _af_calloc(instParamCount, sizeof (AFPVu));
712                                if (handle->instruments[i].values == NULL)
713                                        return AF_FAIL;
714                                for (j=0; j<instParamCount; j++)
715                                {
716                                        handle->instruments[i].values[j] =
717                                                _af_units[setup->fileFormat].instrumentParameters[j].defaultValue;
718                                }
719                        }
720                }
721        }
722
723        /* Copy miscellaneous information. */
724
725        if ((handle->miscellaneousCount = setup->miscellaneousCount) == 0)
726                handle->miscellaneous = NULL;
727        else
728        {
729                handle->miscellaneous = _af_calloc(handle->miscellaneousCount,
730                        sizeof (_Miscellaneous));
731                if (handle->miscellaneous == NULL)
732                        return AF_FAIL;
733                for (i=0; i<handle->miscellaneousCount; i++)
734                {
735                        handle->miscellaneous[i].id = setup->miscellaneous[i].id;
736                        handle->miscellaneous[i].type = setup->miscellaneous[i].type;
737                        handle->miscellaneous[i].size = setup->miscellaneous[i].size;
738                        handle->miscellaneous[i].position = 0;
739                        handle->miscellaneous[i].buffer = NULL;
740                }
741        }
742
743        return AF_SUCCEED;
744}
Note: See TracBrowser for help on using the repository browser.