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 Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 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 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301 USA
20 */
21
22 /*
23 Marker.cpp
24
25 This file contains routines for dealing with loop markers.
26 */
27
28 #include "config.h"
29 #include "Marker.h"
30
31 #include <string.h>
32 #include <stdlib.h>
33 #include <assert.h>
34
35 #include "FileHandle.h"
36 #include "Setup.h"
37 #include "Track.h"
38 #include "afinternal.h"
39 #include "audiofile.h"
40 #include "util.h"
41
afInitMarkIDs(AFfilesetup setup,int trackid,const int * markids,int nmarks)42 void afInitMarkIDs(AFfilesetup setup, int trackid, const int *markids, int nmarks)
43 {
44 if (!_af_filesetup_ok(setup))
45 return;
46
47 TrackSetup *track = setup->getTrack(trackid);
48 if (!track)
49 return;
50
51 if (track->markers != NULL)
52 {
53 for (int i=0; i<track->markerCount; i++)
54 {
55 if (track->markers[i].name != NULL)
56 free(track->markers[i].name);
57 if (track->markers[i].comment != NULL)
58 free(track->markers[i].comment);
59 }
60 free(track->markers);
61 }
62
63 track->markers = (MarkerSetup *) _af_calloc(nmarks, sizeof (struct MarkerSetup));
64 track->markerCount = nmarks;
65
66 for (int i=0; i<nmarks; i++)
67 {
68 track->markers[i].id = markids[i];
69 track->markers[i].name = _af_strdup("");
70 track->markers[i].comment = _af_strdup("");
71 }
72
73 track->markersSet = true;
74 }
75
afInitMarkName(AFfilesetup setup,int trackid,int markid,const char * namestr)76 void afInitMarkName(AFfilesetup setup, int trackid, int markid,
77 const char *namestr)
78 {
79 int markno;
80 int length;
81
82 if (!_af_filesetup_ok(setup))
83 return;
84
85 TrackSetup *track = setup->getTrack(trackid);
86 if (!track)
87 return;
88
89 for (markno=0; markno<track->markerCount; markno++)
90 {
91 if (track->markers[markno].id == markid)
92 break;
93 }
94
95 if (markno == track->markerCount)
96 {
97 _af_error(AF_BAD_MARKID, "no marker id %d for file setup", markid);
98 return;
99 }
100
101 length = strlen(namestr);
102 if (length > 255)
103 {
104 _af_error(AF_BAD_STRLEN,
105 "warning: marker name truncated to 255 characters");
106 length = 255;
107 }
108
109 if (track->markers[markno].name)
110 free(track->markers[markno].name);
111 if ((track->markers[markno].name = (char *) _af_malloc(length+1)) == NULL)
112 return;
113 strncpy(track->markers[markno].name, namestr, length);
114 /*
115 The null terminator is not set by strncpy if
116 strlen(namestr) > length. Set it here.
117 */
118 track->markers[markno].name[length] = '\0';
119 }
120
afInitMarkComment(AFfilesetup setup,int trackid,int markid,const char * commstr)121 void afInitMarkComment(AFfilesetup setup, int trackid, int markid,
122 const char *commstr)
123 {
124 int markno;
125 int length;
126
127 if (!_af_filesetup_ok(setup))
128 return;
129
130 TrackSetup *track = setup->getTrack(trackid);
131 if (!track)
132 return;
133
134 for (markno=0; markno<track->markerCount; markno++)
135 {
136 if (track->markers[markno].id == markid)
137 break;
138 }
139
140 if (markno == track->markerCount)
141 {
142 _af_error(AF_BAD_MARKID, "no marker id %d for file setup", markid);
143 return;
144 }
145
146 length = strlen(commstr);
147
148 if (track->markers[markno].comment)
149 free(track->markers[markno].comment);
150 if ((track->markers[markno].comment = (char *) _af_malloc(length+1)) == NULL)
151 return;
152 strcpy(track->markers[markno].comment, commstr);
153 }
154
afGetMarkName(AFfilehandle file,int trackid,int markid)155 char *afGetMarkName (AFfilehandle file, int trackid, int markid)
156 {
157 if (!_af_filehandle_ok(file))
158 return NULL;
159
160 Track *track = file->getTrack(trackid);
161 if (!track)
162 return NULL;
163
164 Marker *marker = track->getMarker(markid);
165 if (!marker)
166 return NULL;
167
168 return marker->name;
169 }
170
afGetMarkComment(AFfilehandle file,int trackid,int markid)171 char *afGetMarkComment (AFfilehandle file, int trackid, int markid)
172 {
173 if (!_af_filehandle_ok(file))
174 return NULL;
175
176 Track *track = file->getTrack(trackid);
177 if (!track)
178 return NULL;
179
180 Marker *marker = track->getMarker(markid);
181 if (!marker)
182 return NULL;
183
184 return marker->comment;
185 }
186
afSetMarkPosition(AFfilehandle file,int trackid,int markid,AFframecount position)187 void afSetMarkPosition (AFfilehandle file, int trackid, int markid,
188 AFframecount position)
189 {
190 if (!_af_filehandle_ok(file))
191 return;
192
193 if (!file->checkCanWrite())
194 return;
195
196 Track *track = file->getTrack(trackid);
197 if (!track)
198 return;
199
200 Marker *marker = track->getMarker(markid);
201 if (!marker)
202 return;
203
204 if (position < 0)
205 {
206 _af_error(AF_BAD_MARKPOS, "invalid marker position %jd",
207 static_cast<intmax_t>(position));
208 position = 0;
209 }
210
211 marker->position = position;
212 }
213
afGetMarkIDs(AFfilehandle file,int trackid,int markids[])214 int afGetMarkIDs (AFfilehandle file, int trackid, int markids[])
215 {
216 if (!_af_filehandle_ok(file))
217 return -1;
218
219 Track *track = file->getTrack(trackid);
220 if (!track)
221 return -1;
222
223 if (markids != NULL)
224 {
225 for (int i=0; i<track->markerCount; i++)
226 {
227 markids[i] = track->markers[i].id;
228 }
229 }
230
231 return track->markerCount;
232 }
233
afGetMarkPosition(AFfilehandle file,int trackid,int markid)234 AFframecount afGetMarkPosition (AFfilehandle file, int trackid, int markid)
235 {
236 if (!_af_filehandle_ok(file))
237 return 0L;
238
239 Track *track = file->getTrack(trackid);
240 if (!track)
241 return 0L;
242
243 Marker *marker = track->getMarker(markid);
244 if (!marker)
245 return 0L;
246
247 return marker->position;
248 }
249
_af_marker_new(int count)250 Marker *_af_marker_new (int count)
251 {
252 Marker *markers = (Marker *) _af_calloc(count, sizeof (Marker));
253 if (markers == NULL)
254 return NULL;
255
256 return markers;
257 }
258