OSDN Git Service

introduced event mode for mouse and key input, added JoystickInput (thus added jinput...
[mikumikustudio/MikuMikuStudio.git] / src / com / jmex / sound / openAL / SoundSystem.java
1 /*
2  * Copyright (c) 2003-2005 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 /**
34  * Created on Apr 22, 2005
35  */
36 package com.jmex.sound.openAL;
37
38 import java.net.URL;
39 import java.util.logging.Level;
40
41 import org.lwjgl.openal.AL;
42
43 import com.jme.math.Vector3f;
44 import com.jme.renderer.Camera;
45 import com.jme.util.LoggingSystem;
46 import com.jmex.sound.openAL.objects.Listener;
47 import com.jmex.sound.openAL.objects.MusicStream;
48 import com.jmex.sound.openAL.objects.Sample3D;
49 import com.jmex.sound.openAL.objects.util.StreamPlayer;
50 import com.jmex.sound.openAL.objects.util.dsp.Equalizer;
51 import com.jmex.sound.openAL.scene.Configuration;
52 import com.jmex.sound.openAL.scene.SoundNode;
53
54 public class SoundSystem {
55     
56     private static Listener listener;
57     private static Camera camera;
58     
59     public static final int OUTPUT_DEFAULT=0;
60     //WINDOZE
61     public static final int OUTPUT_DSOUND =1;
62     public static final int OUTPUT_WINMM =2;
63     public static final int OUTPUT_ASIO =3;
64     //LINUZ
65     public static final int OUTPUT_OSS =5;
66     public static final int OUTPUT_ESD =6;
67     public static final int OUTPUT_ALSA =7;
68     //MAC
69     public static final int OUTPUT_MAC = 8;
70     
71     private static int OS_DETECTED;
72     private static final int OS_LINUX=1;
73     private static final int OS_WINDOWS=2;
74     private static final int OS_MAC = 3;
75     
76     private static SoundNode[] nodes;
77     private static Sample3D[] sample3D;
78     private static MusicStream[] stream;
79     
80     static{
81         
82             LoggingSystem.getLogger().log(Level.INFO,"DETECT OPERATING SYSTEM");
83             detectOS();
84             LoggingSystem.getLogger().log(Level.INFO,"CREATE OPENAL");
85             initializeOpenAL();            
86             LoggingSystem.getLogger().log(Level.INFO,"CREATE LISTENER");
87             listener=new Listener();
88     }
89     
90     /**
91      *
92      */
93     private static void initializeOpenAL() {
94         try {
95             AL.create();
96             LoggingSystem.getLogger().log(Level.INFO, "OpenAL initalized!");
97         } catch (Exception e) {
98             LoggingSystem.getLogger().log(Level.SEVERE,
99                     "Failed to Initialize OpenAL...");
100             e.printStackTrace();
101         }
102     }
103     
104     private static void detectOS() {
105         String osName=System.getProperty("os.name");
106         osName=osName.toUpperCase();
107         if(osName.startsWith("LINUX")) OS_DETECTED=OS_LINUX;
108         if(osName.startsWith("WINDOWS")) OS_DETECTED=OS_WINDOWS;
109         if(osName.startsWith("MAC")) OS_DETECTED=OS_MAC;        
110     }
111     
112     
113     /**
114      * init the sound system by setting it's listener's position to the cameras position
115      * 
116      * @param cam
117      * @param outputMethod
118      */
119     public static void init(Camera cam, int outputMethod){
120         camera=cam;
121         if(outputMethod==OUTPUT_DEFAULT){
122             outputMethod=OS_DETECTED;
123         }
124         switch(outputMethod){
125             case OS_LINUX : 
126                 break;
127             case OS_WINDOWS : 
128                 break;
129             case OS_MAC : 
130                 break;
131             
132         }
133         
134     }
135     
136     /**
137      * Get the "ears" of the sound system
138      * @return
139      */
140     public static Camera getCamera(){
141         return camera;
142     }
143     
144     /**
145      * Set the "ears" of the sound system
146      * @param c
147      */
148     public static void setCamera(Camera c){
149         camera=c;
150         updateListener();
151     }
152     
153     
154     private static void updateListener(){     
155         if(camera !=null){
156             listener.setPosition(camera.getLocation());            
157         }
158         float[] orientation = listener.getOrientation();
159         Vector3f dir=null;
160         Vector3f up=null;
161         if(camera !=null){
162          dir = camera.getDirection();
163          up = camera.getUp();
164         }else if(dir==null){
165             dir=new Vector3f(0, 0, -1);
166             up=new Vector3f(0, 1, 0);
167         }
168         orientation[0] = -dir.x;
169         orientation[1] = dir.y;
170         orientation[2] = dir.z;
171         orientation[3] = up.x;
172         orientation[4] = -up.y;
173         orientation[5] = up.z;
174         listener.update();
175         
176     }
177     
178     /**
179      * Updates the geometric states of all nodes in the scene
180      * @param time currently not used 
181      */
182     public static void update(float time){
183         if(nodes==null) return;
184         
185         for(int a=0; a<nodes.length; a++){
186             nodes[a].updateWorldData(time);
187         } 
188         updateListener();
189         
190     }
191     
192     /**
193      * Updates the geometric states of the given node in the scene
194      * @param nodeName the node to update
195      * @param time currently not used 
196      */
197     public static void update(int nodeName, float time){
198         if(nodes==null) return;
199         if(nodeName<0 || nodeName>=nodes.length) return;
200         nodes[nodeName].updateWorldData(time);
201         updateListener();
202         
203     }
204     
205     
206     /**
207      * Draws all nodes in the scene
208      * @param time currently not used 
209      */
210     public static void draw(){
211         if(nodes==null) return;
212         for(int a=0; a<nodes.length; a++){
213             nodes[a].draw();
214         }   
215         
216     }
217     
218     /**
219      * Draws the given node in the scene
220      * @param nodeName the node to update
221      * @param time currently not used 
222      */
223     public static void draw(int nodeName){
224         if(nodes==null) return;
225         if(nodeName<0 || nodeName>=nodes.length) return;
226         nodes[nodeName].draw();
227     }
228     
229     /**
230      * Creates a node ans return an integer as it's identifier.
231      * @return the node identifier
232      */
233     public static int createSoundNode(){
234         if(nodes==null){
235             nodes=new SoundNode[1];
236             nodes[0]=new SoundNode();
237             return 0;
238         }else{
239             SoundNode[] tmp=new SoundNode[nodes.length];
240             System.arraycopy(nodes, 0, tmp, 0, tmp.length);
241             nodes=new SoundNode[tmp.length+1];
242             System.arraycopy(tmp, 0, nodes, 0, tmp.length);
243             nodes[tmp.length]=new SoundNode();
244             return tmp.length;
245         }
246     }
247     
248     /**
249      * Creates a 3D sample and returns an identifier for it
250      * @param file the sample file name
251      * @return the 3D sample identifier
252      */
253     public static int create3DSample(URL url){
254         if(sample3D==null){
255             sample3D=new Sample3D[1];
256             sample3D[0]=new Sample3D(listener, url);
257             return 0;
258         }else{
259             Sample3D[] tmp=new Sample3D[sample3D.length];
260             System.arraycopy(sample3D, 0, tmp, 0, tmp.length);
261             sample3D=new Sample3D[tmp.length+1];
262             System.arraycopy(tmp, 0, sample3D, 0, tmp.length);
263             sample3D[tmp.length]=new Sample3D(listener, url);
264             return tmp.length;
265         }
266     }
267     
268     
269     /**
270      * Creates a Music stream and returns an identifier for it
271      * @param file streaming file name
272      * @param loadIntoMemory
273      * @return the stream identifier
274      */
275     public static int createStream(String file, boolean loadIntoMemory){
276         if(stream==null){
277             stream=new MusicStream[1];
278             stream[0]=new MusicStream(file, loadIntoMemory);
279             return 0;
280         }else{
281             MusicStream[] tmp=new MusicStream[stream.length];
282             System.arraycopy(stream, 0, tmp, 0, tmp.length);
283             stream=new MusicStream[tmp.length+1];
284             System.arraycopy(tmp, 0, stream, 0, tmp.length);
285             stream[tmp.length]=new MusicStream(file, loadIntoMemory);
286             return tmp.length;
287         }
288     }
289    
290     /**
291      * Checks if a stream is opened. If it is, this can be used to know
292      * that the file is really a audio file  
293      * @param streamName
294      * @return true if the stream is opened
295      */
296     public static boolean isStreamOpened(int streamName){
297         if(stream==null){
298             return false;
299         }else if(streamName<0 || streamName>=stream.length){
300             return false; 
301         }else{
302             return stream[streamName].isOpened();
303         }
304     }
305     
306     /**
307      * Make a stream loop
308      * @param streamName
309      * 
310      */
311     public static void setStreamLooping(int streamName, boolean loop){
312         if(stream==null){
313             return ;
314         }else if(streamName<0 || streamName>=stream.length){
315             return ; 
316         }else{
317             stream[streamName].loop(loop);
318         }
319     }
320     
321     
322     /**
323      * Get the length of the given stream in milliseconds
324      * @param streamName
325      * @return the stream length in millis
326      */
327     public static float getStreamLength(int streamName){
328         if(stream==null){
329             return -1;
330         }else if(streamName<0 || streamName>=stream.length){
331             return -1; 
332         }else{
333             return stream[streamName].length();
334         }
335     }
336     
337     public static boolean playStream(int streamName){
338         if(stream==null){
339             return false;
340         }else if(streamName<0 || streamName>=stream.length){
341             return false; 
342         }else{
343             return stream[streamName].play();
344         }
345     }
346     
347     
348     
349     
350     public static boolean pauseStream(int streamName){
351         if(stream==null){
352             return false;
353         }else if(streamName<0 || streamName>=stream.length){
354             return false; 
355         }else{
356             return stream[streamName].pause();
357         }
358     }
359     
360     public static void stopStream(int streamName){
361         if(stream==null){
362             return ;
363         }else if(streamName<0 || streamName>=stream.length){
364             return ; 
365         }else{
366             stream[streamName].stop();
367         }
368     }
369     
370     /**
371      * Sets the spatial position of a given sample
372      * @param sample the sample identifier
373      * @param x the x position of the sample
374      * @param y the y position of the sample
375      * @param z the z position of the sample
376      */
377     public static void setSamplePosition(int sample, float x, float y, float z){
378         if(sample3D==null){
379             return;
380         }else if(sample<0 || sample>=sample3D.length){
381             return; 
382         }else{
383             sample3D[sample].setPosition(x, y, z);
384         }
385     }
386     
387     /**
388      * Sets the velocity of a given sample
389      * @param sample the sample identifier
390      * @param x the x velocity of the sample
391      * @param y the y velocity of the sample
392      * @param z the z velocity of the sample
393      */    
394     public static void setSampleVelocity(int sample, float x, float y, float z){
395         if(sample3D==null){
396             return;
397         }else if(sample<0 || sample>=sample3D.length){
398             return; 
399         }else{
400             sample3D[sample].setVelocity(x, y, z);
401         }
402     }
403     
404     /**
405      * Set the FX configuration of the given sample
406      * @param sample sample the sample identifier
407      * @param conf the config
408      */
409     public static void setSampleConfig(int sample, Configuration conf){
410         if(sample3D==null){
411             return;
412         }else if(sample<0 || sample>=sample3D.length){
413             return; 
414         }else{
415             sample3D[sample].setConfiguration(conf); 
416         }
417     }
418     
419     
420     /**
421      * Binds an event to the given sample. The event number sould be a unique id.
422      * Binding an event to sample will make it play only if the event is fired 
423      * on the container node
424      * @param sample the sample to which the event will be bound
425      * @param event the unique event number
426      */
427     public static void bindEventToSample(int sample, int event){
428         if(sample3D==null){
429             return;
430         }else if(sample<0 || sample>=sample3D.length){
431             return; 
432         }else{
433             sample3D[sample].bindEvent(event);
434         }
435     }
436     
437     /**
438      * Fires an event on all nodes
439      * @param eventName the event to fire
440      */
441     public static void onEvent(int eventName){
442         if(nodes==null) return;        
443         for(int a=0; a<nodes.length; a++){
444             nodes[a].onEvent(eventName);
445         } 
446         
447     }
448     
449     /**
450      * 
451      * @param nodeName
452      * @param eventName
453      */
454     public static void onEvent(int nodeName, int eventName){
455         if(nodes==null) return;
456         if(nodeName<0 || nodeName>=nodes.length) return;
457         nodes[nodeName].onEvent(eventName);
458         
459         
460     }
461     
462     /**
463      * Set the FX configuration of the given stream
464      * @param sample stream the sample identifier
465      * @param conf the config
466      */
467     public static void setStreamConfig(int streamName, Configuration conf){
468         if(stream==null){
469             return;
470         }else if(streamName<0 || streamName>=stream.length){
471             return; 
472         }else{
473             stream[streamName].setConfiguration(conf);
474         }
475     }
476
477     
478     /**
479      * Sets the units from which the sample will stop playing
480      * @param sample the sample identifier
481      * @param dist the distance unit from which the sample will stop playing
482      */
483     public static void setSampleMaxAudibleDistance(int sample, int dist){
484         if(sample3D==null){
485             return;
486         }else if(sample<0 || sample>=sample3D.length){
487             return; 
488         }else{
489             sample3D[sample].setMaxAudibleDistance(dist);
490         }
491     }
492     
493     
494     public static void setSampleMinAudibleDistance(int sample, int dist){
495         if(sample3D==null){
496             return;
497         }else if(sample<0 || sample>=sample3D.length){
498             return; 
499         }else{
500             sample3D[sample].setMinDistance(dist);
501         }
502     }
503     
504     
505     /**
506      * Adds a sample to the given node identifier
507      * @param destNode
508      * @param sample
509      */
510     public static void addSampleToNode(int sample, int destNode){
511         if(nodes==null){
512             return;
513         }else if(sample3D==null){
514             return;
515         }else if(destNode<0 || destNode>=nodes.length){
516             return;            
517         }else if(sample<0 || sample>=sample3D.length){
518             return;            
519         }else{
520             nodes[destNode].attachChild(sample3D[sample]);
521         }        
522     }
523
524     public static void setRolloffFactor(float rolloff){
525         for ( int i = 0; i < sample3D.length; i++ ) {
526             setSampleRolloffFactor( i, rolloff );
527         }
528     }
529
530     public static void setSampleRolloffFactor(int sample, float rolloff){
531         if(sample3D==null){
532             return;
533         }else if(sample<0 || sample>=sample3D.length){
534             return;
535         }else{
536             sample3D[sample].setRolloffFactor( rolloff );
537         }
538     } 
539     
540     /**
541      * Set the volume of the given sample
542      * @param sample
543      * @param volume
544      */
545     public static void setSampleVolume(int sample, float volume){
546         if(sample3D==null){
547             return;
548         }else if(sample<0 || sample>=sample3D.length){
549             return; 
550         }else{
551             sample3D[sample].setVolume(volume);
552         }
553     }
554     
555     /** 
556      * Sets the volume of all samples attached to a given node. 
557      * 
558      * @param node We change the volume of this nodes children. 
559      * @param volume The volume to set. Should be a value between 0 - 1. 
560      */ 
561     public static void setNodeVolume(int node, float volume) { 
562         if(nodes==null) return;
563         if(node<0 || node>=nodes.length) return;
564         for (int i = 0; i < nodes[node].getQuantity(); i++) { 
565           ((Sample3D)nodes[node].getChild(i)).setVolume(volume); 
566         } 
567     } 
568
569
570     
571     public static void setEqualizer(Equalizer e){
572         StreamPlayer.getInstance().setEqualizer(e);
573     }
574     
575     
576     
577     
578     
579
580
581 }