1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright (c) 1993-2001 by Sun Microsystems, Inc. 24*7c478bd9Sstevel@tonic-gate * All rights reserved. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <AudioExtent.h> 30*7c478bd9Sstevel@tonic-gate #include <AudioList.h> 31*7c478bd9Sstevel@tonic-gate #include <AudioDebug.h> 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate // class AudioList methods 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate 36*7c478bd9Sstevel@tonic-gate // class AudioListEntry Constructor 37*7c478bd9Sstevel@tonic-gate AudioList::AudioListEntry:: 38*7c478bd9Sstevel@tonic-gate AudioListEntry( 39*7c478bd9Sstevel@tonic-gate Audio* obj): // audio object to point to 40*7c478bd9Sstevel@tonic-gate aptr(0), next(0), prev(0) 41*7c478bd9Sstevel@tonic-gate { 42*7c478bd9Sstevel@tonic-gate // A NULL object is only valid in dummy entries, such as list heads 43*7c478bd9Sstevel@tonic-gate newptr(obj); 44*7c478bd9Sstevel@tonic-gate } 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate // class AudioListEntry Destructor 47*7c478bd9Sstevel@tonic-gate AudioList::AudioListEntry:: 48*7c478bd9Sstevel@tonic-gate ~AudioListEntry() 49*7c478bd9Sstevel@tonic-gate { 50*7c478bd9Sstevel@tonic-gate newptr(0); 51*7c478bd9Sstevel@tonic-gate if (next != 0) { 52*7c478bd9Sstevel@tonic-gate next->prev = prev; 53*7c478bd9Sstevel@tonic-gate } 54*7c478bd9Sstevel@tonic-gate if (prev != 0) { 55*7c478bd9Sstevel@tonic-gate prev->next = next; 56*7c478bd9Sstevel@tonic-gate } 57*7c478bd9Sstevel@tonic-gate } 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate // Set a new extent pointer in an AudioListEntry 60*7c478bd9Sstevel@tonic-gate void AudioList::AudioListEntry:: 61*7c478bd9Sstevel@tonic-gate newptr( 62*7c478bd9Sstevel@tonic-gate Audio* newa) // new object 63*7c478bd9Sstevel@tonic-gate { 64*7c478bd9Sstevel@tonic-gate if (aptr != 0) 65*7c478bd9Sstevel@tonic-gate aptr->Dereference(); 66*7c478bd9Sstevel@tonic-gate aptr = newa; 67*7c478bd9Sstevel@tonic-gate if (aptr != 0) 68*7c478bd9Sstevel@tonic-gate aptr->Reference(); 69*7c478bd9Sstevel@tonic-gate } 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate // Link object into list 72*7c478bd9Sstevel@tonic-gate // Link in a new AudioListEntry 73*7c478bd9Sstevel@tonic-gate void AudioList::AudioListEntry:: 74*7c478bd9Sstevel@tonic-gate link( 75*7c478bd9Sstevel@tonic-gate AudioListEntry* after) // link after this one 76*7c478bd9Sstevel@tonic-gate { 77*7c478bd9Sstevel@tonic-gate // Link object into list 78*7c478bd9Sstevel@tonic-gate prev = after; 79*7c478bd9Sstevel@tonic-gate next = after->next; 80*7c478bd9Sstevel@tonic-gate after->next = this; 81*7c478bd9Sstevel@tonic-gate if (next != 0) 82*7c478bd9Sstevel@tonic-gate next->prev = this; 83*7c478bd9Sstevel@tonic-gate } 84*7c478bd9Sstevel@tonic-gate 85*7c478bd9Sstevel@tonic-gate // Split an AudioListEntry at the specified offset 86*7c478bd9Sstevel@tonic-gate void AudioList::AudioListEntry:: 87*7c478bd9Sstevel@tonic-gate split( 88*7c478bd9Sstevel@tonic-gate Double pos) // split offset 89*7c478bd9Sstevel@tonic-gate { 90*7c478bd9Sstevel@tonic-gate AudioExtent* e1; 91*7c478bd9Sstevel@tonic-gate AudioExtent* e2; 92*7c478bd9Sstevel@tonic-gate AudioListEntry* newp; 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate // Create two extents referencing this object 95*7c478bd9Sstevel@tonic-gate e1 = new AudioExtent(aptr, 0., pos); 96*7c478bd9Sstevel@tonic-gate e2 = new AudioExtent(aptr, pos, AUDIO_UNKNOWN_TIME); 97*7c478bd9Sstevel@tonic-gate 98*7c478bd9Sstevel@tonic-gate // Set the current entry to the first extent and append the second 99*7c478bd9Sstevel@tonic-gate newptr(e1); 100*7c478bd9Sstevel@tonic-gate newp = new AudioListEntry(e2); 101*7c478bd9Sstevel@tonic-gate newp->link(this); 102*7c478bd9Sstevel@tonic-gate } 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate // class AudioList Constructor 106*7c478bd9Sstevel@tonic-gate AudioList:: 107*7c478bd9Sstevel@tonic-gate AudioList( 108*7c478bd9Sstevel@tonic-gate const char *local_name): // name string 109*7c478bd9Sstevel@tonic-gate Audio(local_name), head(0) 110*7c478bd9Sstevel@tonic-gate { 111*7c478bd9Sstevel@tonic-gate } 112*7c478bd9Sstevel@tonic-gate 113*7c478bd9Sstevel@tonic-gate // class AudioList Destructor 114*7c478bd9Sstevel@tonic-gate AudioList:: 115*7c478bd9Sstevel@tonic-gate ~AudioList() 116*7c478bd9Sstevel@tonic-gate { 117*7c478bd9Sstevel@tonic-gate // Delete all entries in the list 118*7c478bd9Sstevel@tonic-gate while (first() != 0) 119*7c478bd9Sstevel@tonic-gate delete first(); 120*7c478bd9Sstevel@tonic-gate } 121*7c478bd9Sstevel@tonic-gate 122*7c478bd9Sstevel@tonic-gate // Get the first entry in the list 123*7c478bd9Sstevel@tonic-gate AudioList::AudioListEntry* AudioList:: 124*7c478bd9Sstevel@tonic-gate first() const 125*7c478bd9Sstevel@tonic-gate { 126*7c478bd9Sstevel@tonic-gate return (head.next); 127*7c478bd9Sstevel@tonic-gate } 128*7c478bd9Sstevel@tonic-gate 129*7c478bd9Sstevel@tonic-gate // Get the extent and offset corresponding to a given position 130*7c478bd9Sstevel@tonic-gate // Return FALSE if no extents in list or position is beyond eof 131*7c478bd9Sstevel@tonic-gate Boolean AudioList:: 132*7c478bd9Sstevel@tonic-gate getposition( 133*7c478bd9Sstevel@tonic-gate Double& pos, // target position (updated) 134*7c478bd9Sstevel@tonic-gate AudioListEntry*& ep) const // returned extent pointer 135*7c478bd9Sstevel@tonic-gate { 136*7c478bd9Sstevel@tonic-gate Double length; 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate // Position must be specified 139*7c478bd9Sstevel@tonic-gate if (Undefined(pos)) 140*7c478bd9Sstevel@tonic-gate return (FALSE); 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate // Get the first extent in the list 143*7c478bd9Sstevel@tonic-gate ep = first(); 144*7c478bd9Sstevel@tonic-gate while (ep != 0) { 145*7c478bd9Sstevel@tonic-gate // Get length of extent 146*7c478bd9Sstevel@tonic-gate length = ep->aptr->GetLength(); 147*7c478bd9Sstevel@tonic-gate if (Undefined(length)) { 148*7c478bd9Sstevel@tonic-gate // Can't determine sizes beyond this 149*7c478bd9Sstevel@tonic-gate return (TRUE); 150*7c478bd9Sstevel@tonic-gate } 151*7c478bd9Sstevel@tonic-gate // If the remaining offset is inside the current extent 152*7c478bd9Sstevel@tonic-gate if (length > pos) 153*7c478bd9Sstevel@tonic-gate return (TRUE); 154*7c478bd9Sstevel@tonic-gate 155*7c478bd9Sstevel@tonic-gate // Move on to the next extent 156*7c478bd9Sstevel@tonic-gate pos -= length; 157*7c478bd9Sstevel@tonic-gate ep = ep->next; 158*7c478bd9Sstevel@tonic-gate } 159*7c478bd9Sstevel@tonic-gate return (FALSE); 160*7c478bd9Sstevel@tonic-gate } 161*7c478bd9Sstevel@tonic-gate 162*7c478bd9Sstevel@tonic-gate // Get the total length of the audio list 163*7c478bd9Sstevel@tonic-gate Double AudioList:: 164*7c478bd9Sstevel@tonic-gate GetLength() const 165*7c478bd9Sstevel@tonic-gate { 166*7c478bd9Sstevel@tonic-gate AudioListEntry* ep; 167*7c478bd9Sstevel@tonic-gate Double sum; 168*7c478bd9Sstevel@tonic-gate Double x; 169*7c478bd9Sstevel@tonic-gate 170*7c478bd9Sstevel@tonic-gate for (sum = 0., ep = first(); ep != 0; ep = ep->next) { 171*7c478bd9Sstevel@tonic-gate // Accumulate times for each extent 172*7c478bd9Sstevel@tonic-gate // Indeterminate extents screw up the calculation 173*7c478bd9Sstevel@tonic-gate x = ep->aptr->GetLength(); 174*7c478bd9Sstevel@tonic-gate if (Undefined(x)) 175*7c478bd9Sstevel@tonic-gate return (x); 176*7c478bd9Sstevel@tonic-gate sum += x; 177*7c478bd9Sstevel@tonic-gate } 178*7c478bd9Sstevel@tonic-gate return (sum); 179*7c478bd9Sstevel@tonic-gate } 180*7c478bd9Sstevel@tonic-gate 181*7c478bd9Sstevel@tonic-gate // Construct a name for the list 182*7c478bd9Sstevel@tonic-gate char *AudioList:: 183*7c478bd9Sstevel@tonic-gate GetName() const 184*7c478bd9Sstevel@tonic-gate { 185*7c478bd9Sstevel@tonic-gate // XXX - construct a better name 186*7c478bd9Sstevel@tonic-gate return (Audio::GetName()); 187*7c478bd9Sstevel@tonic-gate } 188*7c478bd9Sstevel@tonic-gate 189*7c478bd9Sstevel@tonic-gate // Get the audio header for the current read position 190*7c478bd9Sstevel@tonic-gate AudioHdr AudioList:: 191*7c478bd9Sstevel@tonic-gate GetHeader() 192*7c478bd9Sstevel@tonic-gate { 193*7c478bd9Sstevel@tonic-gate return (GetHeader(ReadPosition())); 194*7c478bd9Sstevel@tonic-gate } 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate // Get the audio header for the given position 197*7c478bd9Sstevel@tonic-gate AudioHdr AudioList:: 198*7c478bd9Sstevel@tonic-gate GetHeader( 199*7c478bd9Sstevel@tonic-gate Double pos) // position 200*7c478bd9Sstevel@tonic-gate { 201*7c478bd9Sstevel@tonic-gate AudioListEntry* ep; 202*7c478bd9Sstevel@tonic-gate 203*7c478bd9Sstevel@tonic-gate // Get the extent pointer for the given position 204*7c478bd9Sstevel@tonic-gate if (!getposition(pos, ep)) { 205*7c478bd9Sstevel@tonic-gate AudioHdr h; 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate if (pos != 0.) { 208*7c478bd9Sstevel@tonic-gate PrintMsg(_MGET_( 209*7c478bd9Sstevel@tonic-gate "AudioHdr:GetHeader()...position is beyond eof"), 210*7c478bd9Sstevel@tonic-gate Warning); 211*7c478bd9Sstevel@tonic-gate return (h); 212*7c478bd9Sstevel@tonic-gate } 213*7c478bd9Sstevel@tonic-gate if ((ep = first()) != 0) 214*7c478bd9Sstevel@tonic-gate return (ep->aptr->GetHeader()); 215*7c478bd9Sstevel@tonic-gate return (h); 216*7c478bd9Sstevel@tonic-gate } 217*7c478bd9Sstevel@tonic-gate // Get the header for the proper offset in the extent 218*7c478bd9Sstevel@tonic-gate return (ep->aptr->GetDHeader(pos)); 219*7c478bd9Sstevel@tonic-gate } 220*7c478bd9Sstevel@tonic-gate 221*7c478bd9Sstevel@tonic-gate // Copy data from list into specified buffer. 222*7c478bd9Sstevel@tonic-gate // No data format translation takes place. 223*7c478bd9Sstevel@tonic-gate // The object's read position is not updated. 224*7c478bd9Sstevel@tonic-gate // 225*7c478bd9Sstevel@tonic-gate // Since list could contain extents of differing encodings, 226*7c478bd9Sstevel@tonic-gate // clients should always use GetHeader() in combination with ReadData() 227*7c478bd9Sstevel@tonic-gate AudioError AudioList:: 228*7c478bd9Sstevel@tonic-gate ReadData( 229*7c478bd9Sstevel@tonic-gate void* buf, // destination buffer address 230*7c478bd9Sstevel@tonic-gate size_t& len, // buffer size (updated) 231*7c478bd9Sstevel@tonic-gate Double& pos) // start position (updated) 232*7c478bd9Sstevel@tonic-gate { 233*7c478bd9Sstevel@tonic-gate AudioListEntry* ep; 234*7c478bd9Sstevel@tonic-gate size_t cnt; 235*7c478bd9Sstevel@tonic-gate Double off; 236*7c478bd9Sstevel@tonic-gate Double newpos; 237*7c478bd9Sstevel@tonic-gate AudioError err; 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate // Save buffer size 240*7c478bd9Sstevel@tonic-gate cnt = len; 241*7c478bd9Sstevel@tonic-gate 242*7c478bd9Sstevel@tonic-gate // Position must be valid 243*7c478bd9Sstevel@tonic-gate if (Undefined(pos) || (pos < 0.) || ((int)cnt < 0)) 244*7c478bd9Sstevel@tonic-gate return (RaiseError(AUDIO_ERR_BADARG)); 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate // Loop until data is returned or error 247*7c478bd9Sstevel@tonic-gate // XXX - THIS IS WRONG! THE HEADER COULD CHANGE! 248*7c478bd9Sstevel@tonic-gate do { 249*7c478bd9Sstevel@tonic-gate // Get the extent/offset for read position; clear return count 250*7c478bd9Sstevel@tonic-gate len = 0; 251*7c478bd9Sstevel@tonic-gate off = pos; 252*7c478bd9Sstevel@tonic-gate if (!getposition(off, ep)) { 253*7c478bd9Sstevel@tonic-gate err = AUDIO_EOF; 254*7c478bd9Sstevel@tonic-gate err.sys = AUDIO_COPY_INPUT_EOF; 255*7c478bd9Sstevel@tonic-gate return (err); 256*7c478bd9Sstevel@tonic-gate } 257*7c478bd9Sstevel@tonic-gate 258*7c478bd9Sstevel@tonic-gate // Save the offset and read some data 259*7c478bd9Sstevel@tonic-gate newpos = off; 260*7c478bd9Sstevel@tonic-gate len = cnt; 261*7c478bd9Sstevel@tonic-gate err = ep->aptr->ReadData(buf, len, newpos); 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate // If no eof on this list entry, or no more data, we're done 264*7c478bd9Sstevel@tonic-gate if ((err != AUDIO_EOF) || (err.sys != AUDIO_COPY_INPUT_EOF) || 265*7c478bd9Sstevel@tonic-gate (ep->next == 0)) { 266*7c478bd9Sstevel@tonic-gate break; 267*7c478bd9Sstevel@tonic-gate } 268*7c478bd9Sstevel@tonic-gate 269*7c478bd9Sstevel@tonic-gate // Advance to next list entry 270*7c478bd9Sstevel@tonic-gate // XXX - Is this problemmatic, too? 271*7c478bd9Sstevel@tonic-gate pos += ep->aptr->GetLength() - off; 272*7c478bd9Sstevel@tonic-gate } while (TRUE); 273*7c478bd9Sstevel@tonic-gate 274*7c478bd9Sstevel@tonic-gate // Update the byte count and position 275*7c478bd9Sstevel@tonic-gate pos += (newpos - off); // XXX - recalculate? 276*7c478bd9Sstevel@tonic-gate return (err); 277*7c478bd9Sstevel@tonic-gate } 278*7c478bd9Sstevel@tonic-gate 279*7c478bd9Sstevel@tonic-gate // Write to AudioList is (currently) prohibited 280*7c478bd9Sstevel@tonic-gate AudioError AudioList:: 281*7c478bd9Sstevel@tonic-gate WriteData( 282*7c478bd9Sstevel@tonic-gate void*, // destination buffer address 283*7c478bd9Sstevel@tonic-gate size_t& len, // buffer size (updated) 284*7c478bd9Sstevel@tonic-gate Double&) // start position (updated) 285*7c478bd9Sstevel@tonic-gate { 286*7c478bd9Sstevel@tonic-gate len = 0; 287*7c478bd9Sstevel@tonic-gate return (RaiseError(AUDIO_ERR_NOEFFECT)); 288*7c478bd9Sstevel@tonic-gate } 289*7c478bd9Sstevel@tonic-gate 290*7c478bd9Sstevel@tonic-gate // Insert an entry at the start 291*7c478bd9Sstevel@tonic-gate AudioError AudioList:: 292*7c478bd9Sstevel@tonic-gate Insert( 293*7c478bd9Sstevel@tonic-gate Audio* obj) // object to insert 294*7c478bd9Sstevel@tonic-gate { 295*7c478bd9Sstevel@tonic-gate Double pos; // insertion offset, in seconds 296*7c478bd9Sstevel@tonic-gate 297*7c478bd9Sstevel@tonic-gate return (Insert(obj, pos = 0.)); 298*7c478bd9Sstevel@tonic-gate } 299*7c478bd9Sstevel@tonic-gate 300*7c478bd9Sstevel@tonic-gate // Insert an entry at a specified position 301*7c478bd9Sstevel@tonic-gate AudioError AudioList:: 302*7c478bd9Sstevel@tonic-gate Insert( 303*7c478bd9Sstevel@tonic-gate Audio* obj, // object to insert 304*7c478bd9Sstevel@tonic-gate Double pos) // insertion offset, in seconds 305*7c478bd9Sstevel@tonic-gate { 306*7c478bd9Sstevel@tonic-gate AudioListEntry *ep; 307*7c478bd9Sstevel@tonic-gate AudioListEntry *prev; 308*7c478bd9Sstevel@tonic-gate 309*7c478bd9Sstevel@tonic-gate // Find the insertion point 310*7c478bd9Sstevel@tonic-gate if (first() == 0) { 311*7c478bd9Sstevel@tonic-gate prev = &head; // this is the first extent 312*7c478bd9Sstevel@tonic-gate } else { 313*7c478bd9Sstevel@tonic-gate if (!getposition(pos, prev)) { 314*7c478bd9Sstevel@tonic-gate if (pos == 0.) { 315*7c478bd9Sstevel@tonic-gate // Append extent to end of list 316*7c478bd9Sstevel@tonic-gate return (Append(obj)); 317*7c478bd9Sstevel@tonic-gate } else { 318*7c478bd9Sstevel@tonic-gate return (RaiseError(AUDIO_ERR_BADARG)); 319*7c478bd9Sstevel@tonic-gate } 320*7c478bd9Sstevel@tonic-gate } else if (pos != 0.) { 321*7c478bd9Sstevel@tonic-gate // The insertion is in an extent, split it in two 322*7c478bd9Sstevel@tonic-gate prev->split(pos); 323*7c478bd9Sstevel@tonic-gate } else { 324*7c478bd9Sstevel@tonic-gate // Insert before the current position 325*7c478bd9Sstevel@tonic-gate prev = prev->prev; 326*7c478bd9Sstevel@tonic-gate } 327*7c478bd9Sstevel@tonic-gate } 328*7c478bd9Sstevel@tonic-gate // Create object and link into list 329*7c478bd9Sstevel@tonic-gate ep = new AudioListEntry(obj); 330*7c478bd9Sstevel@tonic-gate ep->link(prev); 331*7c478bd9Sstevel@tonic-gate 332*7c478bd9Sstevel@tonic-gate return (AUDIO_SUCCESS); 333*7c478bd9Sstevel@tonic-gate } 334*7c478bd9Sstevel@tonic-gate 335*7c478bd9Sstevel@tonic-gate // Append an entry to a list 336*7c478bd9Sstevel@tonic-gate AudioError AudioList:: 337*7c478bd9Sstevel@tonic-gate Append( 338*7c478bd9Sstevel@tonic-gate Audio* obj) // object to append 339*7c478bd9Sstevel@tonic-gate { 340*7c478bd9Sstevel@tonic-gate AudioListEntry *ep; 341*7c478bd9Sstevel@tonic-gate AudioListEntry *prev; 342*7c478bd9Sstevel@tonic-gate 343*7c478bd9Sstevel@tonic-gate // Find the last extent in the list 344*7c478bd9Sstevel@tonic-gate for (prev = &head; prev->next != 0; prev = prev->next) 345*7c478bd9Sstevel@tonic-gate continue; 346*7c478bd9Sstevel@tonic-gate 347*7c478bd9Sstevel@tonic-gate // Create object and link into list 348*7c478bd9Sstevel@tonic-gate ep = new AudioListEntry(obj); 349*7c478bd9Sstevel@tonic-gate ep->link(prev); 350*7c478bd9Sstevel@tonic-gate return (AUDIO_SUCCESS); 351*7c478bd9Sstevel@tonic-gate } 352*7c478bd9Sstevel@tonic-gate 353*7c478bd9Sstevel@tonic-gate // Copy routine for lists 354*7c478bd9Sstevel@tonic-gate AudioError AudioList:: 355*7c478bd9Sstevel@tonic-gate AsyncCopy( 356*7c478bd9Sstevel@tonic-gate Audio* to, // audio object to copy to 357*7c478bd9Sstevel@tonic-gate Double& frompos, // input pos (updated) 358*7c478bd9Sstevel@tonic-gate Double& topos, // output pos (updated) 359*7c478bd9Sstevel@tonic-gate Double& limit) // amt to copy (updated) 360*7c478bd9Sstevel@tonic-gate { 361*7c478bd9Sstevel@tonic-gate AudioListEntry* ep; 362*7c478bd9Sstevel@tonic-gate Double svlim; 363*7c478bd9Sstevel@tonic-gate Double newpos; 364*7c478bd9Sstevel@tonic-gate Double off; 365*7c478bd9Sstevel@tonic-gate AudioError err; 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate svlim = limit; 368*7c478bd9Sstevel@tonic-gate // Loop until data is returned or error 369*7c478bd9Sstevel@tonic-gate // XXX - THIS IS WRONG! THE HEADER COULD CHANGE! 370*7c478bd9Sstevel@tonic-gate do { 371*7c478bd9Sstevel@tonic-gate // Get the extent and offset for the read position 372*7c478bd9Sstevel@tonic-gate off = frompos; 373*7c478bd9Sstevel@tonic-gate if (!getposition(off, ep)) { 374*7c478bd9Sstevel@tonic-gate // nothing written, limit should reflect this 375*7c478bd9Sstevel@tonic-gate limit = 0.0; 376*7c478bd9Sstevel@tonic-gate err = AUDIO_EOF; 377*7c478bd9Sstevel@tonic-gate err.sys = AUDIO_COPY_INPUT_EOF; 378*7c478bd9Sstevel@tonic-gate return (err); 379*7c478bd9Sstevel@tonic-gate } 380*7c478bd9Sstevel@tonic-gate 381*7c478bd9Sstevel@tonic-gate // Save the offset and do a copy 382*7c478bd9Sstevel@tonic-gate newpos = off; 383*7c478bd9Sstevel@tonic-gate limit = svlim; 384*7c478bd9Sstevel@tonic-gate err = ep->aptr->AsyncCopy(to, newpos, topos, limit); 385*7c478bd9Sstevel@tonic-gate 386*7c478bd9Sstevel@tonic-gate // If no eof on this list entry, or no more data, we're done 387*7c478bd9Sstevel@tonic-gate if ((err != AUDIO_EOF) || (err.sys != AUDIO_COPY_INPUT_EOF) || 388*7c478bd9Sstevel@tonic-gate (ep->next == 0)) { 389*7c478bd9Sstevel@tonic-gate break; 390*7c478bd9Sstevel@tonic-gate } 391*7c478bd9Sstevel@tonic-gate 392*7c478bd9Sstevel@tonic-gate // Advance to next list entry 393*7c478bd9Sstevel@tonic-gate // XXX - Is this problemmatic, too? 394*7c478bd9Sstevel@tonic-gate frompos += ep->aptr->GetLength() - off; 395*7c478bd9Sstevel@tonic-gate } while (TRUE); 396*7c478bd9Sstevel@tonic-gate 397*7c478bd9Sstevel@tonic-gate // Update the byte count and position 398*7c478bd9Sstevel@tonic-gate frompos += (newpos - off); // XXX - recalculate? 399*7c478bd9Sstevel@tonic-gate return (err); 400*7c478bd9Sstevel@tonic-gate } 401