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 <stdio.h> 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate // class AudioExtent methods 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate // class AudioExtent Constructor 36*7c478bd9Sstevel@tonic-gate AudioExtent:: 37*7c478bd9Sstevel@tonic-gate AudioExtent( 38*7c478bd9Sstevel@tonic-gate Audio* obj, // audio object to point to 39*7c478bd9Sstevel@tonic-gate double s, // start time 40*7c478bd9Sstevel@tonic-gate double e): // end time 41*7c478bd9Sstevel@tonic-gate Audio("[extent]"), ref(obj) 42*7c478bd9Sstevel@tonic-gate { 43*7c478bd9Sstevel@tonic-gate ref->Reference(); // reference audio object 44*7c478bd9Sstevel@tonic-gate SetStart(s); // set start/end times 45*7c478bd9Sstevel@tonic-gate SetEnd(e); 46*7c478bd9Sstevel@tonic-gate } 47*7c478bd9Sstevel@tonic-gate 48*7c478bd9Sstevel@tonic-gate // class AudioExtent Destructor 49*7c478bd9Sstevel@tonic-gate AudioExtent:: 50*7c478bd9Sstevel@tonic-gate ~AudioExtent() 51*7c478bd9Sstevel@tonic-gate { 52*7c478bd9Sstevel@tonic-gate ref->Dereference(); // clear audio object reference 53*7c478bd9Sstevel@tonic-gate } 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate // Get referenced object 56*7c478bd9Sstevel@tonic-gate Audio* AudioExtent:: 57*7c478bd9Sstevel@tonic-gate GetRef() const 58*7c478bd9Sstevel@tonic-gate { 59*7c478bd9Sstevel@tonic-gate return (ref); 60*7c478bd9Sstevel@tonic-gate } 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate // Set referenced object 63*7c478bd9Sstevel@tonic-gate void AudioExtent:: 64*7c478bd9Sstevel@tonic-gate SetRef( 65*7c478bd9Sstevel@tonic-gate Audio* r) // new audio object 66*7c478bd9Sstevel@tonic-gate { 67*7c478bd9Sstevel@tonic-gate if (ref == r) // object is not changing 68*7c478bd9Sstevel@tonic-gate return; 69*7c478bd9Sstevel@tonic-gate ref->Dereference(); // dereference previous object 70*7c478bd9Sstevel@tonic-gate if (r != 0) { 71*7c478bd9Sstevel@tonic-gate ref = r; 72*7c478bd9Sstevel@tonic-gate ref->Reference(); // reference new object 73*7c478bd9Sstevel@tonic-gate } else { 74*7c478bd9Sstevel@tonic-gate PrintMsg(_MGET_("AudioExtent:...NULL Audio object reference"), 75*7c478bd9Sstevel@tonic-gate Fatal); 76*7c478bd9Sstevel@tonic-gate } 77*7c478bd9Sstevel@tonic-gate } 78*7c478bd9Sstevel@tonic-gate 79*7c478bd9Sstevel@tonic-gate // Get start time 80*7c478bd9Sstevel@tonic-gate Double AudioExtent:: 81*7c478bd9Sstevel@tonic-gate GetStart() const 82*7c478bd9Sstevel@tonic-gate { 83*7c478bd9Sstevel@tonic-gate return (start); 84*7c478bd9Sstevel@tonic-gate } 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate // Set start time 87*7c478bd9Sstevel@tonic-gate void AudioExtent:: 88*7c478bd9Sstevel@tonic-gate SetStart( 89*7c478bd9Sstevel@tonic-gate Double s) // start time, in seconds 90*7c478bd9Sstevel@tonic-gate { 91*7c478bd9Sstevel@tonic-gate if (Undefined(s) || (s < 0.)) 92*7c478bd9Sstevel@tonic-gate start = 0.; 93*7c478bd9Sstevel@tonic-gate else 94*7c478bd9Sstevel@tonic-gate start = s; 95*7c478bd9Sstevel@tonic-gate } 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate // Get end time 98*7c478bd9Sstevel@tonic-gate Double AudioExtent:: 99*7c478bd9Sstevel@tonic-gate GetEnd() const 100*7c478bd9Sstevel@tonic-gate { 101*7c478bd9Sstevel@tonic-gate // If determinate endpoint, return it 102*7c478bd9Sstevel@tonic-gate if (!Undefined(end)) 103*7c478bd9Sstevel@tonic-gate return (end); 104*7c478bd9Sstevel@tonic-gate // Otherwise, return the endpoint of the underlying object 105*7c478bd9Sstevel@tonic-gate return (ref->GetLength()); 106*7c478bd9Sstevel@tonic-gate } 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate // Set end time 109*7c478bd9Sstevel@tonic-gate void AudioExtent:: 110*7c478bd9Sstevel@tonic-gate SetEnd( 111*7c478bd9Sstevel@tonic-gate Double e) // end time, in seconds 112*7c478bd9Sstevel@tonic-gate { 113*7c478bd9Sstevel@tonic-gate Double len; 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate // If known endpoint and object has known size, do not exceed size 116*7c478bd9Sstevel@tonic-gate if (!Undefined(e)) { 117*7c478bd9Sstevel@tonic-gate len = ref->GetLength(); 118*7c478bd9Sstevel@tonic-gate if (!Undefined(len) && (e > len)) 119*7c478bd9Sstevel@tonic-gate e = len; 120*7c478bd9Sstevel@tonic-gate } 121*7c478bd9Sstevel@tonic-gate end = e; 122*7c478bd9Sstevel@tonic-gate } 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate // Get the length of an audio extent 125*7c478bd9Sstevel@tonic-gate Double AudioExtent:: 126*7c478bd9Sstevel@tonic-gate GetLength() const 127*7c478bd9Sstevel@tonic-gate { 128*7c478bd9Sstevel@tonic-gate Double x; 129*7c478bd9Sstevel@tonic-gate 130*7c478bd9Sstevel@tonic-gate // If extent end is indeterminate, use the end of the target object 131*7c478bd9Sstevel@tonic-gate x = GetEnd(); 132*7c478bd9Sstevel@tonic-gate // If the object length is indeterminate, then the length is 133*7c478bd9Sstevel@tonic-gate if (Undefined(x)) 134*7c478bd9Sstevel@tonic-gate return (x); 135*7c478bd9Sstevel@tonic-gate return (x - start); 136*7c478bd9Sstevel@tonic-gate } 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate // Construct a name for the list 139*7c478bd9Sstevel@tonic-gate char *AudioExtent:: 140*7c478bd9Sstevel@tonic-gate GetName() const 141*7c478bd9Sstevel@tonic-gate { 142*7c478bd9Sstevel@tonic-gate // XXX - construct a better name 143*7c478bd9Sstevel@tonic-gate return (ref->GetName()); 144*7c478bd9Sstevel@tonic-gate } 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gate // Get the audio header for the current read position 147*7c478bd9Sstevel@tonic-gate AudioHdr AudioExtent:: 148*7c478bd9Sstevel@tonic-gate GetHeader() 149*7c478bd9Sstevel@tonic-gate { 150*7c478bd9Sstevel@tonic-gate return (ref->GetDHeader(ReadPosition() + start)); 151*7c478bd9Sstevel@tonic-gate } 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate // Get the audio header for the given position 154*7c478bd9Sstevel@tonic-gate AudioHdr AudioExtent:: 155*7c478bd9Sstevel@tonic-gate GetHeader( 156*7c478bd9Sstevel@tonic-gate Double pos) // position 157*7c478bd9Sstevel@tonic-gate { 158*7c478bd9Sstevel@tonic-gate return (ref->GetDHeader(pos + start)); 159*7c478bd9Sstevel@tonic-gate } 160*7c478bd9Sstevel@tonic-gate 161*7c478bd9Sstevel@tonic-gate // Copy data from extent into specified buffer. 162*7c478bd9Sstevel@tonic-gate // No data format translation takes place. 163*7c478bd9Sstevel@tonic-gate // The object's read position is not updated. 164*7c478bd9Sstevel@tonic-gate // 165*7c478bd9Sstevel@tonic-gate // Since the extent could refer to a list of extents of differing encodings, 166*7c478bd9Sstevel@tonic-gate // clients should always use GetHeader() in combination with ReadData() 167*7c478bd9Sstevel@tonic-gate AudioError AudioExtent:: 168*7c478bd9Sstevel@tonic-gate ReadData( 169*7c478bd9Sstevel@tonic-gate void* buf, // destination buffer address 170*7c478bd9Sstevel@tonic-gate size_t& len, // buffer size (updated) 171*7c478bd9Sstevel@tonic-gate Double& pos) // start position (updated) 172*7c478bd9Sstevel@tonic-gate { 173*7c478bd9Sstevel@tonic-gate size_t cnt; 174*7c478bd9Sstevel@tonic-gate off_t buflen; 175*7c478bd9Sstevel@tonic-gate Double off; 176*7c478bd9Sstevel@tonic-gate Double newpos; 177*7c478bd9Sstevel@tonic-gate AudioError err; 178*7c478bd9Sstevel@tonic-gate 179*7c478bd9Sstevel@tonic-gate // Save buffer size and zero transfer count 180*7c478bd9Sstevel@tonic-gate cnt = len; 181*7c478bd9Sstevel@tonic-gate len = 0; 182*7c478bd9Sstevel@tonic-gate 183*7c478bd9Sstevel@tonic-gate // Position must be valid 184*7c478bd9Sstevel@tonic-gate if (Undefined(pos) || (pos < 0.) || ((int)cnt < 0)) 185*7c478bd9Sstevel@tonic-gate return (RaiseError(AUDIO_ERR_BADARG)); 186*7c478bd9Sstevel@tonic-gate 187*7c478bd9Sstevel@tonic-gate // If the end is determinate, check start position and length 188*7c478bd9Sstevel@tonic-gate off = pos + start; 189*7c478bd9Sstevel@tonic-gate newpos = GetEnd(); 190*7c478bd9Sstevel@tonic-gate if (!Undefined(newpos)) { 191*7c478bd9Sstevel@tonic-gate // If starting beyond eof, give up now 192*7c478bd9Sstevel@tonic-gate if (off >= newpos) { 193*7c478bd9Sstevel@tonic-gate err = AUDIO_EOF; 194*7c478bd9Sstevel@tonic-gate err.sys = AUDIO_COPY_INPUT_EOF; 195*7c478bd9Sstevel@tonic-gate return (err); 196*7c478bd9Sstevel@tonic-gate } 197*7c478bd9Sstevel@tonic-gate 198*7c478bd9Sstevel@tonic-gate // If the read would extend beyond end-of-extent, shorten it 199*7c478bd9Sstevel@tonic-gate buflen = GetHeader(pos).Time_to_Bytes((Double)(newpos - off)); 200*7c478bd9Sstevel@tonic-gate if (buflen == 0) { 201*7c478bd9Sstevel@tonic-gate err = AUDIO_EOF; 202*7c478bd9Sstevel@tonic-gate err.sys = AUDIO_COPY_INPUT_EOF; 203*7c478bd9Sstevel@tonic-gate return (err); 204*7c478bd9Sstevel@tonic-gate } 205*7c478bd9Sstevel@tonic-gate if (buflen < cnt) 206*7c478bd9Sstevel@tonic-gate cnt = (size_t)buflen; 207*7c478bd9Sstevel@tonic-gate } 208*7c478bd9Sstevel@tonic-gate // Zero-length reads are easy 209*7c478bd9Sstevel@tonic-gate if (cnt == 0) { 210*7c478bd9Sstevel@tonic-gate err = AUDIO_SUCCESS; 211*7c478bd9Sstevel@tonic-gate err.sys = AUDIO_COPY_ZERO_LIMIT; 212*7c478bd9Sstevel@tonic-gate return (err); 213*7c478bd9Sstevel@tonic-gate } 214*7c478bd9Sstevel@tonic-gate 215*7c478bd9Sstevel@tonic-gate // Save the offset, read data, and update the returned position 216*7c478bd9Sstevel@tonic-gate newpos = off; 217*7c478bd9Sstevel@tonic-gate len = cnt; 218*7c478bd9Sstevel@tonic-gate err = ref->ReadData(buf, len, newpos); 219*7c478bd9Sstevel@tonic-gate pos = (newpos - start); // XXX - calculate bytes and convert? 220*7c478bd9Sstevel@tonic-gate return (err); 221*7c478bd9Sstevel@tonic-gate } 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate // Write to AudioExtent is (currently) prohibited 224*7c478bd9Sstevel@tonic-gate AudioError AudioExtent:: 225*7c478bd9Sstevel@tonic-gate WriteData( 226*7c478bd9Sstevel@tonic-gate void*, // destination buffer address 227*7c478bd9Sstevel@tonic-gate size_t& len, // buffer size (updated) 228*7c478bd9Sstevel@tonic-gate Double&) // start position (updated) 229*7c478bd9Sstevel@tonic-gate { 230*7c478bd9Sstevel@tonic-gate len = 0; 231*7c478bd9Sstevel@tonic-gate return (RaiseError(AUDIO_ERR_NOEFFECT)); 232*7c478bd9Sstevel@tonic-gate } 233