4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1993-2001 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <AudioExtent.h>
30 #include <AudioList.h>
31 #include <AudioDebug.h>
33 // class AudioList methods
36 // class AudioListEntry Constructor
37 AudioList::AudioListEntry::
39 Audio
* obj
): // audio object to point to
40 aptr(0), next(0), prev(0)
42 // A NULL object is only valid in dummy entries, such as list heads
46 // class AudioListEntry Destructor
47 AudioList::AudioListEntry::
59 // Set a new extent pointer in an AudioListEntry
60 void AudioList::AudioListEntry::
62 Audio
* newa
) // new object
71 // Link object into list
72 // Link in a new AudioListEntry
73 void AudioList::AudioListEntry::
75 AudioListEntry
* after
) // link after this one
77 // Link object into list
85 // Split an AudioListEntry at the specified offset
86 void AudioList::AudioListEntry::
88 Double pos
) // split offset
94 // Create two extents referencing this object
95 e1
= new AudioExtent(aptr
, 0., pos
);
96 e2
= new AudioExtent(aptr
, pos
, AUDIO_UNKNOWN_TIME
);
98 // Set the current entry to the first extent and append the second
100 newp
= new AudioListEntry(e2
);
105 // class AudioList Constructor
108 const char *local_name
): // name string
109 Audio(local_name
), head(0)
113 // class AudioList Destructor
117 // Delete all entries in the list
122 // Get the first entry in the list
123 AudioList::AudioListEntry
* AudioList::
129 // Get the extent and offset corresponding to a given position
130 // Return FALSE if no extents in list or position is beyond eof
133 Double
& pos
, // target position (updated)
134 AudioListEntry
*& ep
) const // returned extent pointer
138 // Position must be specified
142 // Get the first extent in the list
145 // Get length of extent
146 length
= ep
->aptr
->GetLength();
147 if (Undefined(length
)) {
148 // Can't determine sizes beyond this
151 // If the remaining offset is inside the current extent
155 // Move on to the next extent
162 // Get the total length of the audio list
170 for (sum
= 0., ep
= first(); ep
!= 0; ep
= ep
->next
) {
171 // Accumulate times for each extent
172 // Indeterminate extents screw up the calculation
173 x
= ep
->aptr
->GetLength();
181 // Construct a name for the list
185 // XXX - construct a better name
186 return (Audio::GetName());
189 // Get the audio header for the current read position
193 return (GetHeader(ReadPosition()));
196 // Get the audio header for the given position
199 Double pos
) // position
203 // Get the extent pointer for the given position
204 if (!getposition(pos
, ep
)) {
209 "AudioHdr:GetHeader()...position is beyond eof"),
213 if ((ep
= first()) != 0)
214 return (ep
->aptr
->GetHeader());
217 // Get the header for the proper offset in the extent
218 return (ep
->aptr
->GetDHeader(pos
));
221 // Copy data from list into specified buffer.
222 // No data format translation takes place.
223 // The object's read position is not updated.
225 // Since list could contain extents of differing encodings,
226 // clients should always use GetHeader() in combination with ReadData()
227 AudioError
AudioList::
229 void* buf
, // destination buffer address
230 size_t& len
, // buffer size (updated)
231 Double
& pos
) // start position (updated)
242 // Position must be valid
243 if (Undefined(pos
) || (pos
< 0.) || ((int)cnt
< 0))
244 return (RaiseError(AUDIO_ERR_BADARG
));
246 // Loop until data is returned or error
247 // XXX - THIS IS WRONG! THE HEADER COULD CHANGE!
249 // Get the extent/offset for read position; clear return count
252 if (!getposition(off
, ep
)) {
254 err
.sys
= AUDIO_COPY_INPUT_EOF
;
258 // Save the offset and read some data
261 err
= ep
->aptr
->ReadData(buf
, len
, newpos
);
263 // If no eof on this list entry, or no more data, we're done
264 if ((err
!= AUDIO_EOF
) || (err
.sys
!= AUDIO_COPY_INPUT_EOF
) ||
269 // Advance to next list entry
270 // XXX - Is this problemmatic, too?
271 pos
+= ep
->aptr
->GetLength() - off
;
274 // Update the byte count and position
275 pos
+= (newpos
- off
); // XXX - recalculate?
279 // Write to AudioList is (currently) prohibited
280 AudioError
AudioList::
282 void*, // destination buffer address
283 size_t& len
, // buffer size (updated)
284 Double
&) // start position (updated)
287 return (RaiseError(AUDIO_ERR_NOEFFECT
));
290 // Insert an entry at the start
291 AudioError
AudioList::
293 Audio
* obj
) // object to insert
295 Double pos
; // insertion offset, in seconds
297 return (Insert(obj
, pos
= 0.));
300 // Insert an entry at a specified position
301 AudioError
AudioList::
303 Audio
* obj
, // object to insert
304 Double pos
) // insertion offset, in seconds
307 AudioListEntry
*prev
;
309 // Find the insertion point
311 prev
= &head
; // this is the first extent
313 if (!getposition(pos
, prev
)) {
315 // Append extent to end of list
316 return (Append(obj
));
318 return (RaiseError(AUDIO_ERR_BADARG
));
320 } else if (pos
!= 0.) {
321 // The insertion is in an extent, split it in two
324 // Insert before the current position
328 // Create object and link into list
329 ep
= new AudioListEntry(obj
);
332 return (AUDIO_SUCCESS
);
335 // Append an entry to a list
336 AudioError
AudioList::
338 Audio
* obj
) // object to append
341 AudioListEntry
*prev
;
343 // Find the last extent in the list
344 for (prev
= &head
; prev
->next
!= 0; prev
= prev
->next
)
347 // Create object and link into list
348 ep
= new AudioListEntry(obj
);
350 return (AUDIO_SUCCESS
);
353 // Copy routine for lists
354 AudioError
AudioList::
356 Audio
* to
, // audio object to copy to
357 Double
& frompos
, // input pos (updated)
358 Double
& topos
, // output pos (updated)
359 Double
& limit
) // amt to copy (updated)
368 // Loop until data is returned or error
369 // XXX - THIS IS WRONG! THE HEADER COULD CHANGE!
371 // Get the extent and offset for the read position
373 if (!getposition(off
, ep
)) {
374 // nothing written, limit should reflect this
377 err
.sys
= AUDIO_COPY_INPUT_EOF
;
381 // Save the offset and do a copy
384 err
= ep
->aptr
->AsyncCopy(to
, newpos
, topos
, limit
);
386 // If no eof on this list entry, or no more data, we're done
387 if ((err
!= AUDIO_EOF
) || (err
.sys
!= AUDIO_COPY_INPUT_EOF
) ||
392 // Advance to next list entry
393 // XXX - Is this problemmatic, too?
394 frompos
+= ep
->aptr
->GetLength() - off
;
397 // Update the byte count and position
398 frompos
+= (newpos
- off
); // XXX - recalculate?