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

Revision 17099, 5.2 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) 1998-2000, Michael Pruett <michael@68k.org>
4        Copyright (C) 2000, Silicon Graphics, Inc.
5
6        This library is free software; you can redistribute it and/or
7        modify it under the terms of the GNU Library General Public
8        License as published by the Free Software Foundation; either
9        version 2 of the License, or (at your option) any later version.
10
11        This library is distributed in the hope that it will be useful,
12        but WITHOUT ANY WARRANTY; without even the implied warranty of
13        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14        Library General Public License for more details.
15
16        You should have received a copy of the GNU Library General Public
17        License along with this library; if not, write to the
18        Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19        Boston, MA  02111-1307  USA.
20*/
21
22/*
23        data.c
24*/
25
26#ifdef HAVE_CONFIG_H
27#include <config.h>
28#endif
29
30#include <assert.h>
31#include <stdlib.h>
32#include <string.h>
33
34#include "audiofile.h"
35#include "afinternal.h"
36#include "util.h"
37#include "modules.h"
38
39int afWriteFrames (AFfilehandle file, int trackid, const void *samples,
40        int nvframes2write)
41{
42        _AFmoduleinst   *firstmod;
43        _AFchunk        *userc;
44        _Track          *track;
45        int             bytes_per_vframe;
46        AFframecount    vframe;
47
48        if (!_af_filehandle_ok(file))
49                return -1;
50
51        if (!_af_filehandle_can_write(file))
52                return -1;
53
54        if ((track = _af_filehandle_get_track(file, trackid)) == NULL)
55                return -1;
56
57        if (track->ms.modulesdirty)
58        {
59                if (_AFsetupmodules(file, track) != AF_SUCCEED)
60                        return -1;
61        }
62
63        /*if (file->seekok) {*/
64
65        if (af_fseek(file->fh, track->fpos_next_frame, SEEK_SET) < 0)
66        {
67                _af_error(AF_BAD_LSEEK, "unable to position write pointer at next frame");
68                return -1;
69        }
70
71        /* } */
72
73        bytes_per_vframe = _af_format_frame_size(&track->v, AF_TRUE);
74
75        firstmod = &track->ms.module[0];
76        userc = &track->ms.chunk[0];
77
78        track->filemodhappy = AF_TRUE;
79
80        vframe = 0;
81#ifdef UNLIMITED_CHUNK_NVFRAMES
82        /*
83                OPTIMIZATION: see the comment at the very end of
84                arrangemodules() in modules.c for an explanation of this:
85        */
86        if (!trk->ms.mustuseatomicnvframes)
87        {
88                userc->buf = (char *)buf;
89                userc->nframes = nvframes2write;
90
91                (*firstmod->mod->run_push)(firstmod);
92
93                /* Count this chunk if there was no i/o error. */
94                if (trk->filemodhappy)
95                        vframe += userc->nframes;
96        }
97        else
98#else
99        /* Optimization must be off. */
100        assert(track->ms.mustuseatomicnvframes);
101#endif
102        {
103                while (vframe < nvframes2write)
104                {
105                        userc->buf = (char *) samples + bytes_per_vframe * vframe;
106                        if (vframe <= nvframes2write - _AF_ATOMIC_NVFRAMES)
107                                userc->nframes = _AF_ATOMIC_NVFRAMES;
108                        else
109                                userc->nframes = nvframes2write - vframe;
110
111                        (*firstmod->mod->run_push)(firstmod);
112
113                        if (track->filemodhappy == AF_FALSE)
114                                break;
115
116                        vframe += userc->nframes;
117                }
118        }
119
120        track->nextvframe += vframe;
121        track->totalvframes += vframe;
122
123        return vframe;
124}
125
126int afReadFrames (AFfilehandle file, int trackid, void *samples,
127        int nvframeswanted)
128{
129        _Track  *track;
130        _AFmoduleinst   *firstmod;
131        _AFchunk        *userc;
132        AFframecount    nvframesleft, nvframes2read;
133        int             bytes_per_vframe;
134        AFframecount    vframe;
135
136        if (!_af_filehandle_ok(file))
137                return -1;
138
139        if (!_af_filehandle_can_read(file))
140                return -1;
141
142        if ((track = _af_filehandle_get_track(file, trackid)) == NULL)
143                return -1;
144
145        if (track->ms.modulesdirty)
146        {
147                if (_AFsetupmodules(file, track) != AF_SUCCEED)
148                        return -1;
149        }
150
151        /*if (file->seekok) {*/
152
153        if (af_fseek(file->fh, track->fpos_next_frame, SEEK_SET) < 0)
154        {
155                _af_error(AF_BAD_LSEEK, "unable to position read pointer at next frame");
156                return -1;
157        }
158
159        /* } */
160
161        if (track->totalvframes == -1)
162                nvframes2read = nvframeswanted;
163        else
164        {
165                nvframesleft = track->totalvframes - track->nextvframe;
166                nvframes2read = (nvframeswanted > nvframesleft) ?
167                        nvframesleft : nvframeswanted;
168        }
169        bytes_per_vframe = _af_format_frame_size(&track->v, AF_FALSE);
170
171        firstmod = &track->ms.module[track->ms.nmodules-1];
172        userc = &track->ms.chunk[track->ms.nmodules];
173
174        track->filemodhappy = AF_TRUE;
175
176        vframe = 0;
177
178        if (!track->ms.mustuseatomicnvframes)
179        {
180                assert(track->frames2ignore == 0);
181                userc->buf = samples;
182                userc->nframes = nvframes2read;
183
184                (*firstmod->mod->run_pull)(firstmod);
185                if (track->filemodhappy)
186                        vframe += userc->nframes;
187        }
188        else
189        {
190                bool    eof = AF_FALSE;
191
192                if (track->frames2ignore != 0)
193                {
194                        userc->nframes = track->frames2ignore;
195                        userc->buf = _af_malloc(track->frames2ignore * bytes_per_vframe);
196                        if (userc->buf == AF_NULL)
197                                return 0;
198
199                        (*firstmod->mod->run_pull)(firstmod);
200
201                        /* Have we hit EOF? */
202                        if (userc->nframes < track->frames2ignore)
203                                eof = AF_TRUE;
204
205                        track->frames2ignore = 0;
206
207                        free(userc->buf);
208                        userc->buf = NULL;
209                }
210
211                /*
212                        Now start reading useful frames, until EOF or
213                        premature EOF.
214                */
215
216                while (track->filemodhappy && !eof && vframe < nvframes2read)
217                {
218                        AFframecount    nvframes2pull;
219                        userc->buf = (char *) samples + bytes_per_vframe * vframe;
220
221                        if (vframe <= nvframes2read - _AF_ATOMIC_NVFRAMES)
222                                nvframes2pull = _AF_ATOMIC_NVFRAMES;
223                        else
224                                nvframes2pull = nvframes2read - vframe;
225
226                        userc->nframes = nvframes2pull;
227
228                        (*firstmod->mod->run_pull)(firstmod);
229
230                        if (track->filemodhappy)
231                        {
232                                vframe += userc->nframes;
233                                if (userc->nframes < nvframes2pull)
234                                        eof = AF_TRUE;
235                        }
236                }
237        }
238
239        track->nextvframe += vframe;
240
241        return vframe;
242}
Note: See TracBrowser for help on using the repository browser.