• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2009-2010 jMonkeyEngine
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  *   notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in the
14  *   documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17  *   may be used to endorse or promote products derived from this software
18  *   without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 package com.jme3.audio;
34 
35 import com.jme3.util.NativeObject;
36 import java.io.Closeable;
37 import java.io.IOException;
38 import java.io.InputStream;
39 import java.util.logging.Level;
40 import java.util.logging.Logger;
41 
42 /**
43  * <code>AudioStream</code> is an implementation of AudioData that
44  * acquires the audio from an InputStream. Audio can be streamed
45  * from network, hard drive etc. It is assumed the data coming
46  * from the input stream is uncompressed.
47  *
48  * @author Kirill Vainer
49  */
50 public class AudioStream extends AudioData implements Closeable{
51 
52     private final static Logger logger = Logger.getLogger(AudioStream.class.getName());
53     protected InputStream in;
54     protected float duration = -1f;
55     protected boolean open = false;
56     protected int[] ids;
57 
AudioStream()58     public AudioStream(){
59         super();
60     }
61 
AudioStream(int[] ids)62     protected AudioStream(int[] ids){
63         // Pass some dummy ID so handle
64         // doesn't get created.
65         super(-1);
66         // This is what gets destroyed in reality
67         this.ids = ids;
68     }
69 
updateData(InputStream in, float duration)70     public void updateData(InputStream in, float duration){
71         if (id != -1 || this.in != null)
72             throw new IllegalStateException("Data already set!");
73 
74         this.in = in;
75         this.duration = duration;
76         open = true;
77     }
78 
79     /**
80      * Reads samples from the stream. The format of the data
81      * depends on the getSampleRate(), getChannels(), getBitsPerSample()
82      * values.
83      *
84      * @param buf Buffer where to read the samples
85      * @param offset The offset in the buffer where to read samples
86      * @param length The length inside the buffer where to read samples
87      * @return number of bytes read.
88      */
readSamples(byte[] buf, int offset, int length)89     public int readSamples(byte[] buf, int offset, int length){
90         if (!open)
91             return -1;
92 
93         try{
94             return in.read(buf, offset, length);
95         }catch (IOException ex){
96             return -1;
97         }
98     }
99 
100     /**
101      * Reads samples from the stream.
102      *
103      * @see AudioStream#readSamples(byte[], int, int)
104      * @param buf Buffer where to read the samples
105      * @return number of bytes read.
106      */
readSamples(byte[] buf)107     public int readSamples(byte[] buf){
108         return readSamples(buf, 0, buf.length);
109     }
110 
getDuration()111     public float getDuration(){
112         return duration;
113     }
114 
115     @Override
getId()116     public int getId(){
117         throw new RuntimeException("Don't use getId() on streams");
118     }
119 
120     @Override
setId(int id)121     public void setId(int id){
122         throw new RuntimeException("Don't use setId() on streams");
123     }
124 
initIds(int count)125     public void initIds(int count){
126         ids = new int[count];
127     }
128 
getId(int index)129     public int getId(int index){
130         return ids[index];
131     }
132 
setId(int index, int id)133     public void setId(int index, int id){
134         ids[index] = id;
135     }
136 
getIds()137     public int[] getIds(){
138         return ids;
139     }
140 
setIds(int[] ids)141     public void setIds(int[] ids){
142         this.ids = ids;
143     }
144 
145     @Override
getDataType()146     public DataType getDataType() {
147         return DataType.Stream;
148     }
149 
150     @Override
resetObject()151     public void resetObject() {
152         id = -1;
153         ids = null;
154         setUpdateNeeded();
155     }
156 
157     @Override
deleteObject(Object rendererObject)158     public void deleteObject(Object rendererObject) {
159         // It seems that the audio renderer is already doing a good
160         // job at deleting audio streams when they finish playing.
161 //        ((AudioRenderer)rendererObject).deleteAudioData(this);
162     }
163 
164     @Override
createDestructableClone()165     public NativeObject createDestructableClone() {
166         return new AudioStream(ids);
167     }
168 
169     /**
170      * @return Whether the stream is open or not. Reading from a closed
171      * stream will always return eof.
172      */
isOpen()173     public boolean isOpen(){
174         return open;
175     }
176 
177     /**
178      * Closes the stream, releasing all data relating to it. Reading
179      * from the stream will return eof.
180      * @throws IOException
181      */
close()182     public void close() {
183         if (in != null && open){
184             try{
185                 in.close();
186             }catch (IOException ex){
187             }
188             open = false;
189         }else{
190             throw new RuntimeException("AudioStream is already closed!");
191         }
192     }
193 
194 
setTime(float time)195     public void setTime(float time){
196         if(in instanceof SeekableStream){
197             ((SeekableStream)in).setTime(time);
198         }else{
199             logger.log(Level.WARNING,"Cannot use setTime on a stream that is not seekable. You must load the file with the streamCache option set to true");
200         }
201     }
202 
203 
204 }
205