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

Revision 17099, 7.0 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        loop.c
24
25        All routines that operate on loops.
26*/
27
28#include "audiofile.h"
29#include "afinternal.h"
30#include "util.h"
31#include "setup.h"
32#include "instrument.h"
33
34void afInitLoopIDs (AFfilesetup setup, int instid, int *loopids, int nloops)
35{
36        int instno;
37
38        if (!_af_filesetup_ok(setup))
39                return;
40
41        if (!_af_unique_ids(loopids, nloops, "loop", AF_BAD_LOOPID))
42                return;
43
44        if ((instno = _af_setup_instrument_index_from_id(setup, instid)) == -1)
45                return;
46
47        _af_setup_free_loops(setup, instno);
48
49        setup->instruments[instno].loopCount = nloops;
50        setup->instruments[instno].loopSet = AF_TRUE;
51
52        if (nloops == 0)
53                setup->instruments[instno].loops = NULL;
54        else
55        {
56                int i;
57
58                if ((setup->instruments[instno].loops = _af_calloc(nloops, sizeof (_LoopSetup))) == NULL)
59                        return;
60
61                for (i=0; i < nloops; i++)
62                        setup->instruments[instno].loops[i].id = loopids[i];
63        }
64}
65
66int afGetLoopIDs (AFfilehandle file, int instid, int *loopids)
67{
68        int instno;
69        int i;
70
71        if (!_af_filehandle_ok(file))
72                return AF_FAIL;
73
74        if ((instno = _af_handle_instrument_index_from_id(file, instid)) == -1)
75                return AF_FAIL;
76
77        if (loopids)
78                for (i=0; i < file->instruments[instno].loopCount; i++)
79                        loopids[i] = file->instruments[instno].loops[i].id;
80
81        return file->instruments[instno].loopCount;
82}
83
84int _af_handle_loop_index_from_id (AFfilehandle file, int instno, int loopid)
85{
86        int     i;
87        for (i=0; i<file->instruments[instno].loopCount; i++)
88                if (file->instruments[instno].loops[i].id == loopid)
89                        return i;
90
91        _af_error(AF_BAD_LOOPID, "no loop with id %d for instrument %d",
92                loopid, file->instruments[instno].id);
93
94        return -1;
95}
96
97/*
98        getLoop returns pointer to requested loop if it exists, and if
99        mustWrite is true, only if handle is writable.
100*/
101
102_Loop *getLoop (AFfilehandle handle, int instid, int loopid, bool mustWrite)
103{
104        int     loopno, instno;
105
106        if (!_af_filehandle_ok(handle))
107                return NULL;
108
109        if (mustWrite && !_af_filehandle_can_write(handle))
110                return NULL;
111
112        if ((instno = _af_handle_instrument_index_from_id(handle, instid)) == -1)
113                return NULL;
114
115        if ((loopno = _af_handle_loop_index_from_id(handle, instno, loopid)) == -1)
116                return NULL;
117
118        return &handle->instruments[instno].loops[loopno];
119}
120
121/*
122        Set loop mode (as in AF_LOOP_MODE_...).
123*/
124void afSetLoopMode (AFfilehandle file, int instid, int loopid, int mode)
125{
126        _Loop   *loop = getLoop(file, instid, loopid, AF_TRUE);
127
128        if (!loop)
129                return;
130
131        if (mode != AF_LOOP_MODE_NOLOOP &&
132                mode != AF_LOOP_MODE_FORW &&
133                mode != AF_LOOP_MODE_FORWBAKW)
134        {
135                _af_error(AF_BAD_LOOPMODE, "unrecognized loop mode %d", mode);
136                return;
137        }
138
139        loop->mode = mode;
140}
141
142/*
143        Get loop mode (as in AF_LOOP_MODE_...).
144*/
145int afGetLoopMode (AFfilehandle file, int instid, int loopid)
146{
147        _Loop   *loop = getLoop(file, instid, loopid, AF_FALSE);
148
149        if (loop == NULL)
150                return -1;
151
152        return loop->mode;
153}
154
155/*
156        Set loop count.
157*/
158int afSetLoopCount (AFfilehandle file, int instid, int loopid, int count)
159{
160        _Loop   *loop = getLoop(file, instid, loopid, AF_TRUE);
161
162        if (loop == NULL)
163                return AF_FAIL;
164
165        if (count < 1)
166        {
167                _af_error(AF_BAD_LOOPCOUNT, "invalid loop count: %d", count);
168                return AF_FAIL;
169        }
170
171        loop->count = count;
172        return AF_SUCCEED;
173}
174
175/*
176        Get loop count.
177*/
178int afGetLoopCount(AFfilehandle file, int instid, int loopid)
179{
180        _Loop   *loop = getLoop(file, instid, loopid, AF_FALSE);
181
182        if (loop == NULL)
183                return -1;
184
185        return loop->count;
186}
187
188/*
189        Set loop start marker id in the file structure
190*/
191void
192afSetLoopStart(AFfilehandle file, int instid, int loopid, int markid)
193{
194        _Loop   *loop = getLoop(file, instid, loopid, AF_TRUE);
195
196        if (!loop)
197                return;
198
199        loop->beginMarker = markid;
200}
201
202/*
203        Get loop start marker id.
204*/
205int afGetLoopStart (AFfilehandle file, int instid, int loopid)
206{
207        _Loop   *loop = getLoop(file, instid, loopid, AF_FALSE);
208
209        if (loop == NULL)
210                return -1;
211
212        return loop->beginMarker;
213}
214
215/*
216        Set loop start frame in the file structure.
217*/
218int afSetLoopStartFrame (AFfilehandle file, int instid, int loopid, AFframecount startFrame)
219{
220        int     trackid, beginMarker;
221        _Loop   *loop = getLoop(file, instid, loopid, AF_TRUE);
222
223        if (loop == NULL)
224                return -1;
225
226        if (startFrame < 0)
227        {
228                _af_error(AF_BAD_FRAME, "loop start frame must not be negative");
229                return AF_FAIL;
230        }
231
232        trackid = loop->trackid;
233        beginMarker = loop->beginMarker;
234
235        afSetMarkPosition(file, trackid, beginMarker, startFrame);
236        return AF_SUCCEED;
237}
238
239/*
240        Get loop start frame.
241*/
242AFframecount afGetLoopStartFrame (AFfilehandle file, int instid, int loopid)
243{
244        int     trackid, beginMarker;
245        _Loop   *loop = getLoop(file, instid, loopid, AF_FALSE);
246
247        if (loop == NULL)
248                return -1;
249
250        trackid = loop->trackid;
251        beginMarker = loop->beginMarker;
252
253        return afGetMarkPosition(file, trackid, beginMarker);
254}
255
256/*
257        Set loop track id.
258*/
259void afSetLoopTrack (AFfilehandle file, int instid, int loopid, int track)
260{
261        _Loop *loop = getLoop(file, instid, loopid, AF_TRUE);
262
263        if (!loop) return;
264
265        loop->trackid = track;
266}
267
268/*
269        Get loop track.
270*/
271int afGetLoopTrack (AFfilehandle file, int instid, int loopid)
272{
273        _Loop   *loop = getLoop(file, instid, loopid, AF_FALSE);
274
275        if (loop == NULL)
276                return -1;
277
278        return loop->trackid;
279}
280
281/*
282        Set loop end frame marker id.
283*/
284void afSetLoopEnd (AFfilehandle file, int instid, int loopid, int markid)
285{
286        _Loop   *loop = getLoop(file, instid, loopid, AF_TRUE);
287
288        if (!loop)
289                return;
290
291        loop->endMarker = markid;
292}
293
294/*
295        Get loop end frame marker id.
296*/
297int afGetLoopEnd (AFfilehandle file, int instid, int loopid)
298{
299        _Loop   *loop = getLoop(file, instid, loopid, AF_FALSE);
300
301        if (loop == NULL)
302                return -1;
303
304        return loop->endMarker;
305}
306
307/*
308        Set loop end frame.
309*/
310int afSetLoopEndFrame (AFfilehandle file, int instid, int loopid, AFframecount endFrame)
311{
312        int     trackid, endMarker;
313        _Loop   *loop = getLoop(file, instid, loopid, AF_TRUE);
314
315        if (loop == NULL)
316                return -1;
317
318        if (endFrame < 0)
319        {
320                _af_error(AF_BAD_FRAME, "loop end frame must not be negative");
321                return AF_FAIL;
322        }
323
324        trackid = loop->trackid;
325        endMarker = loop->endMarker;
326
327        afSetMarkPosition(file, trackid, endMarker, endFrame);
328        return AF_SUCCEED;
329}
330
331/*
332        Get loop end frame.
333*/
334
335AFframecount afGetLoopEndFrame (AFfilehandle file, int instid, int loopid)
336{
337        int     trackid, endMarker;
338        _Loop   *loop = getLoop(file, instid, loopid, AF_FALSE);
339
340        if (loop == NULL)
341                return -1;
342
343        trackid = loop->trackid;
344        endMarker = loop->endMarker;
345
346        return afGetMarkPosition(file, trackid, endMarker);
347}
Note: See TracBrowser for help on using the repository browser.