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