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 36AudioExtent:: 37AudioExtent( 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 49AudioExtent:: 50~AudioExtent() 51{ 52 ref->Dereference(); // clear audio object reference 53} 54 55// Get referenced object 56Audio* AudioExtent:: 57GetRef() const 58{ 59 return (ref); 60} 61 62// Set referenced object 63void AudioExtent:: 64SetRef( 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 80Double AudioExtent:: 81GetStart() const 82{ 83 return (start); 84} 85 86// Set start time 87void AudioExtent:: 88SetStart( 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 98Double AudioExtent:: 99GetEnd() 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 109void AudioExtent:: 110SetEnd( 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 125Double AudioExtent:: 126GetLength() 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 139char *AudioExtent:: 140GetName() const 141{ 142 // XXX - construct a better name 143 return (ref->GetName()); 144} 145 146// Get the audio header for the current read position 147AudioHdr AudioExtent:: 148GetHeader() 149{ 150 return (ref->GetDHeader(ReadPosition() + start)); 151} 152 153// Get the audio header for the given position 154AudioHdr AudioExtent:: 155GetHeader( 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() 167AudioError AudioExtent:: 168ReadData( 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 224AudioError AudioExtent:: 225WriteData( 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