OSDN Git Service

43b272046f30d71ed66f3bb1d78d00906c2fc94c
[mikumikustudio/MikuMikuStudio.git] / src / com / jmex / audio / util / AudioLoader.java
1 /*
2  * Copyright (c) 2003-2009 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.jmex.audio.util;
34
35 import java.io.ByteArrayOutputStream;
36 import java.io.IOException;
37 import java.net.URL;
38 import java.nio.ByteBuffer;
39 import java.nio.ByteOrder;
40 import java.nio.ShortBuffer;
41 import java.util.logging.Logger;
42
43 import com.jme.util.geom.BufferUtils;
44 import com.jmex.audio.AudioBuffer;
45 import com.jmex.audio.AudioTrack.Format;
46 import com.jmex.audio.stream.AudioInputStream;
47 import com.jmex.audio.stream.OggInputStream;
48 import com.jmex.audio.stream.WavInputStream;
49
50 /**
51  * Utility class for loading audio files.  For use by the underlying AudioSystem code.
52  * @author Joshua Slack
53  * @version $Id: AudioLoader.java,v 1.5 2007/09/21 11:08:04 irrisor Exp $
54  */
55 public class AudioLoader {
56     private static final Logger logger = Logger.getLogger(AudioLoader.class
57             .getName());
58
59     public static void fillBuffer(AudioBuffer buffer, URL file) throws IOException {
60         if (file == null) return;
61         Format type = AudioInputStream.sniffFormat(file.openStream());
62         if (Format.WAV.equals(type)) {
63             loadWAV(buffer, file);
64         } else if (Format.OGG.equals(type)) {
65             loadOGG(buffer, file);
66         } else {
67             throw new IllegalArgumentException("Given url is not a recognized audio type. Must be OGG or RIFF/WAV: "+file);
68         }
69     }
70
71     private static void loadOGG(AudioBuffer buffer, URL file) throws IOException {
72         OggInputStream oggInput = new OggInputStream(file, -1);
73         ByteBuffer data = read( oggInput );
74         
75         int channels = oggInput.getChannelCount();
76         int bitRate = oggInput.getBitRate();
77         int depth = oggInput.getDepth();
78         int bytes = data.limit();
79         float time = bytes / (bitRate * channels * depth * .125f);
80         buffer.setup(data, channels, bitRate, time, depth);
81         logger.info("ogg loaded - time: " + time + "  channels: " + channels
82                 + "  rate: " + bitRate + " depth: " + depth + " bytes: "
83                 + bytes);
84
85         // cleanup
86         data.clear();
87         oggInput.close();
88     }
89
90     private static void loadWAV(AudioBuffer buffer, URL file) throws IOException {
91         WavInputStream wavInput = new WavInputStream(file);
92         ByteBuffer data = read( wavInput );
93
94         if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) {
95             ShortBuffer tmp2 = data.duplicate().order(
96                     ByteOrder.LITTLE_ENDIAN).asShortBuffer();
97             while (tmp2.hasRemaining())
98                 data.putShort(tmp2.get());
99             data.rewind();
100         }
101         int channels = wavInput.getChannelCount();
102         int bitRate = wavInput.getBitRate();
103         int depth = wavInput.getDepth();
104         int bytes = data.limit();
105         float time = bytes / (bitRate * channels * depth * .125f);
106         buffer.setup(data, channels, bitRate, time, depth);
107         logger.info("wav loaded - time: " + time + "  channels: " + channels
108                 + "  rate: " + bitRate + " depth: " + depth + " bytes: "
109                 + bytes);
110         
111         // cleanup
112         data.clear();
113         wavInput.close();
114     }
115
116     private static ByteBuffer read( AudioInputStream input ) throws IOException {
117         ByteArrayOutputStream byteOut = new ByteArrayOutputStream(1024 * 256);
118         byte copyBuffer[] = new byte[1024 * 4];
119         int bytesRead;
120         do {
121             bytesRead = input.read( copyBuffer, 0, copyBuffer.length );
122             if ( bytesRead > 0 )
123             {
124                 byteOut.write( copyBuffer, 0, bytesRead );
125             }
126         } while ( bytesRead > 0 );
127         int bytes = byteOut.size();
128         ByteBuffer data = BufferUtils.createByteBufferOnHeap(bytes);
129         data.put(byteOut.toByteArray());
130         data.flip();
131         return data;
132     }
133
134 }