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