23 * questions. |
23 * questions. |
24 */ |
24 */ |
25 |
25 |
26 package com.sun.media.sound; |
26 package com.sun.media.sound; |
27 |
27 |
|
28 import java.io.BufferedInputStream; |
28 import java.io.File; |
29 import java.io.File; |
|
30 import java.io.FileInputStream; |
|
31 import java.io.FileOutputStream; |
29 import java.io.IOException; |
32 import java.io.IOException; |
30 import java.io.InputStream; |
33 import java.io.InputStream; |
|
34 import java.io.OutputStream; |
31 import java.lang.ref.WeakReference; |
35 import java.lang.ref.WeakReference; |
32 import java.security.AccessControlException; |
36 import java.security.AccessController; |
|
37 import java.security.PrivilegedAction; |
33 import java.util.ArrayList; |
38 import java.util.ArrayList; |
34 import java.util.Arrays; |
39 import java.util.Arrays; |
35 import java.util.HashMap; |
40 import java.util.HashMap; |
36 import java.util.List; |
41 import java.util.List; |
37 import java.util.Map; |
42 import java.util.Map; |
|
43 import java.util.Properties; |
|
44 import java.util.StringTokenizer; |
|
45 import java.util.prefs.BackingStoreException; |
|
46 import java.util.prefs.Preferences; |
38 |
47 |
39 import javax.sound.midi.Instrument; |
48 import javax.sound.midi.Instrument; |
40 import javax.sound.midi.MidiChannel; |
49 import javax.sound.midi.MidiChannel; |
41 import javax.sound.midi.MidiDevice; |
50 import javax.sound.midi.MidiDevice; |
42 import javax.sound.midi.MidiSystem; |
51 import javax.sound.midi.MidiSystem; |
598 } |
611 } |
599 if (!isOpen()) |
612 if (!isOpen()) |
600 return false; |
613 return false; |
601 |
614 |
602 synchronized (control_mutex) { |
615 synchronized (control_mutex) { |
603 if (!loadedlist.containsValue(to) && !availlist.containsValue(to)) |
616 if (!loadedlist.containsValue(to)) |
604 throw new IllegalArgumentException("Instrument to is not loaded."); |
617 throw new IllegalArgumentException("Instrument to is not loaded."); |
605 unloadInstrument(from); |
618 unloadInstrument(from); |
606 ModelMappedInstrument mfrom = new ModelMappedInstrument( |
619 ModelMappedInstrument mfrom = new ModelMappedInstrument( |
607 (ModelInstrument)to, from.getPatch()); |
620 (ModelInstrument)to, from.getPatch()); |
608 return loadInstrument(mfrom); |
621 return loadInstrument(mfrom); |
609 } |
622 } |
610 } |
623 } |
611 |
624 |
612 public synchronized Soundbank getDefaultSoundbank() { |
625 public Soundbank getDefaultSoundbank() { |
613 if (defaultSoundBank == null) { |
626 synchronized (SoftSynthesizer.class) { |
614 try { |
627 if (defaultSoundBank != null) |
615 File javahome = new File(System.getProperties().getProperty( |
628 return defaultSoundBank; |
616 "java.home")); |
629 |
617 File libaudio = new File(new File(javahome, "lib"), "audio"); |
630 List<PrivilegedAction<InputStream>> actions = |
618 |
631 new ArrayList<PrivilegedAction<InputStream>>(); |
619 if (libaudio.exists()) { |
632 |
620 File foundfile = null; |
633 actions.add(new PrivilegedAction<InputStream>() { |
621 File[] files = libaudio.listFiles(); |
634 public InputStream run() { |
622 if (files != null) { |
635 File javahome = new File(System.getProperties() |
623 for (int i = 0; i < files.length; i++) { |
636 .getProperty("java.home")); |
624 File file = files[i]; |
637 File libaudio = new File(new File(javahome, "lib"), "audio"); |
625 if (file.isFile()) { |
638 if (libaudio.exists()) { |
626 String lname = file.getName().toLowerCase(); |
639 File foundfile = null; |
627 if (lname.endsWith(".sf2") || |
640 File[] files = libaudio.listFiles(); |
628 lname.endsWith(".dls")) { |
641 if (files != null) { |
629 if (foundfile == null || (file.length() > |
642 for (int i = 0; i < files.length; i++) { |
630 foundfile.length())) { |
643 File file = files[i]; |
631 foundfile = file; |
644 if (file.isFile()) { |
|
645 String lname = file.getName().toLowerCase(); |
|
646 if (lname.endsWith(".sf2") |
|
647 || lname.endsWith(".dls")) { |
|
648 if (foundfile == null |
|
649 || (file.length() > foundfile |
|
650 .length())) { |
|
651 foundfile = file; |
|
652 } |
632 } |
653 } |
633 } |
654 } |
634 } |
655 } |
635 } |
656 } |
636 } |
657 if (foundfile != null) { |
637 if (foundfile != null) { |
658 try { |
638 try { |
659 return new FileInputStream(foundfile); |
639 Soundbank sbk = MidiSystem.getSoundbank(foundfile); |
660 } catch (IOException e) { |
640 defaultSoundBank = sbk; |
661 } |
641 return defaultSoundBank; |
|
642 } catch (Exception e) { |
|
643 //e.printStackTrace(); |
|
644 } |
662 } |
645 } |
663 } |
646 } |
664 return null; |
647 |
665 } |
648 if (System.getProperties().getProperty("os.name") |
666 }); |
649 .startsWith("Windows")) { |
667 |
650 File gm_dls = new File(System.getenv("SystemRoot") |
668 actions.add(new PrivilegedAction<InputStream>() { |
651 + "\\system32\\drivers\\gm.dls"); |
669 public InputStream run() { |
652 if (gm_dls.exists()) { |
670 if (System.getProperties().getProperty("os.name") |
653 try { |
671 .startsWith("Windows")) { |
654 Soundbank sbk = MidiSystem.getSoundbank(gm_dls); |
672 File gm_dls = new File(System.getenv("SystemRoot") |
655 defaultSoundBank = sbk; |
673 + "\\system32\\drivers\\gm.dls"); |
656 return defaultSoundBank; |
674 if (gm_dls.exists()) { |
657 } catch (Exception e) { |
675 try { |
658 //e.printStackTrace(); |
676 return new FileInputStream(gm_dls); |
|
677 } catch (IOException e) { |
|
678 } |
659 } |
679 } |
660 } |
680 } |
661 } |
681 return null; |
662 } catch (AccessControlException e) { |
682 } |
663 } catch (Exception e) { |
683 }); |
664 //e.printStackTrace(); |
684 |
665 } |
685 actions.add(new PrivilegedAction<InputStream>() { |
666 |
686 public InputStream run() { |
667 File userhome = null; |
687 /* |
668 File emg_soundbank_file = null; |
688 * Try to load saved generated soundbank |
669 |
689 */ |
670 /* |
690 File userhome = new File(System.getProperty("user.home"), |
671 * Try to load saved generated soundbank |
691 ".gervill"); |
672 */ |
692 File emg_soundbank_file = new File(userhome, |
|
693 "soundbank-emg.sf2"); |
|
694 if (emg_soundbank_file.exists()) { |
|
695 try { |
|
696 return new FileInputStream(emg_soundbank_file); |
|
697 } catch (IOException e) { |
|
698 } |
|
699 } |
|
700 return null; |
|
701 } |
|
702 }); |
|
703 |
|
704 for (PrivilegedAction<InputStream> action : actions) { |
|
705 try { |
|
706 InputStream is = AccessController.doPrivileged(action); |
|
707 if(is == null) continue; |
|
708 Soundbank sbk; |
|
709 try { |
|
710 sbk = MidiSystem.getSoundbank(new BufferedInputStream(is)); |
|
711 } finally { |
|
712 is.close(); |
|
713 } |
|
714 if (sbk != null) { |
|
715 defaultSoundBank = sbk; |
|
716 return defaultSoundBank; |
|
717 } |
|
718 } catch (Exception e) { |
|
719 } |
|
720 } |
|
721 |
673 try { |
722 try { |
674 userhome = new File(System.getProperty("user.home"), |
|
675 ".gervill"); |
|
676 emg_soundbank_file = new File(userhome, "soundbank-emg.sf2"); |
|
677 Soundbank sbk = MidiSystem.getSoundbank(emg_soundbank_file); |
|
678 defaultSoundBank = sbk; |
|
679 return defaultSoundBank; |
|
680 } catch (AccessControlException e) { |
|
681 } catch (Exception e) { |
|
682 //e.printStackTrace(); |
|
683 } |
|
684 |
|
685 try { |
|
686 |
|
687 /* |
723 /* |
688 * Generate emergency soundbank |
724 * Generate emergency soundbank |
689 */ |
725 */ |
690 defaultSoundBank = EmergencySoundbank.createSoundbank(); |
726 defaultSoundBank = EmergencySoundbank.createSoundbank(); |
691 |
727 } catch (Exception e) { |
|
728 } |
|
729 |
|
730 if (defaultSoundBank != null) { |
692 /* |
731 /* |
693 * Save generated soundbank to disk for faster future use. |
732 * Save generated soundbank to disk for faster future use. |
694 */ |
733 */ |
695 if(defaultSoundBank != null) |
734 OutputStream out = AccessController |
696 { |
735 .doPrivileged(new PrivilegedAction<OutputStream>() { |
697 if(!userhome.exists()) userhome.mkdirs(); |
736 public OutputStream run() { |
698 if(!emg_soundbank_file.exists()) |
737 try { |
699 ((SF2Soundbank)defaultSoundBank).save(emg_soundbank_file); |
738 File userhome = new File(System |
700 } |
739 .getProperty("user.home"), |
701 } catch (Exception e) { |
740 ".gervill"); |
702 //e.printStackTrace(); |
741 if (!userhome.exists()) |
703 } |
742 userhome.mkdirs(); |
704 |
743 File emg_soundbank_file = new File( |
|
744 userhome, "soundbank-emg.sf2"); |
|
745 if (emg_soundbank_file.exists()) |
|
746 return null; |
|
747 return new FileOutputStream( |
|
748 emg_soundbank_file); |
|
749 } catch (IOException e) { |
|
750 } catch (SecurityException e) { |
|
751 } |
|
752 return null; |
|
753 } |
|
754 }); |
|
755 if (out != null) { |
|
756 try { |
|
757 ((SF2Soundbank) defaultSoundBank).save(out); |
|
758 out.close(); |
|
759 } catch (IOException e) { |
|
760 } |
|
761 } |
|
762 } |
705 } |
763 } |
706 return defaultSoundBank; |
764 return defaultSoundBank; |
707 } |
765 } |
708 |
766 |
709 public Instrument[] getAvailableInstruments() { |
767 public Instrument[] getAvailableInstruments() { |
710 if (!isOpen()) { |
768 Soundbank defsbk = getDefaultSoundbank(); |
711 Soundbank defsbk = getDefaultSoundbank(); |
769 if (defsbk == null) |
712 if (defsbk == null) |
770 return new Instrument[0]; |
713 return new Instrument[0]; |
771 Instrument[] inslist_array = defsbk.getInstruments(); |
714 return defsbk.getInstruments(); |
772 Arrays.sort(inslist_array, new ModelInstrumentComparator()); |
715 } |
773 return inslist_array; |
716 |
|
717 synchronized (control_mutex) { |
|
718 ModelInstrument[] inslist_array = |
|
719 new ModelInstrument[availlist.values().size()]; |
|
720 availlist.values().toArray(inslist_array); |
|
721 Arrays.sort(inslist_array, new ModelInstrumentComparator()); |
|
722 return inslist_array; |
|
723 } |
|
724 } |
774 } |
725 |
775 |
726 public Instrument[] getLoadedInstruments() { |
776 public Instrument[] getLoadedInstruments() { |
727 if (!isOpen()) |
777 if (!isOpen()) |
728 return new Instrument[0]; |
778 return new Instrument[0]; |
859 |
934 |
860 item = new AudioSynthesizerPropertyInfo("light reverb", o?reverb_light:true); |
935 item = new AudioSynthesizerPropertyInfo("light reverb", o?reverb_light:true); |
861 item.description = "Turn light reverb mode on or off"; |
936 item.description = "Turn light reverb mode on or off"; |
862 list.add(item); |
937 list.add(item); |
863 |
938 |
|
939 item = new AudioSynthesizerPropertyInfo("load default soundbank", o?load_default_soundbank:true); |
|
940 item.description = "Enabled/disable loading default soundbank"; |
|
941 list.add(item); |
|
942 |
864 AudioSynthesizerPropertyInfo[] items; |
943 AudioSynthesizerPropertyInfo[] items; |
865 items = list.toArray(new AudioSynthesizerPropertyInfo[list.size()]); |
944 items = list.toArray(new AudioSynthesizerPropertyInfo[list.size()]); |
866 |
945 |
867 if (info != null) |
946 Properties storedProperties = getStoredProperties(); |
868 for (AudioSynthesizerPropertyInfo item2: items) { |
947 |
869 Object v = info.get(item2.name); |
948 for (AudioSynthesizerPropertyInfo item2 : items) { |
|
949 Object v = (info == null) ? null : info.get(item2.name); |
|
950 v = (v != null) ? v : storedProperties.getProperty(item2.name); |
|
951 if (v != null) { |
870 Class c = (item2.valueClass); |
952 Class c = (item2.valueClass); |
871 if (v != null) |
953 if (c.isInstance(v)) |
872 if (c.isInstance(v)) |
954 item2.value = v; |
873 item2.value = v; |
955 else if (v instanceof String) { |
874 } |
956 String s = (String) v; |
|
957 if (c == Boolean.class) { |
|
958 if (s.equalsIgnoreCase("true")) |
|
959 item2.value = Boolean.TRUE; |
|
960 if (s.equalsIgnoreCase("false")) |
|
961 item2.value = Boolean.FALSE; |
|
962 } else if (c == AudioFormat.class) { |
|
963 int channels = 2; |
|
964 boolean signed = true; |
|
965 boolean bigendian = false; |
|
966 int bits = 16; |
|
967 float sampleRate = 44100f; |
|
968 try { |
|
969 StringTokenizer st = new StringTokenizer(s, ", "); |
|
970 String prevToken = ""; |
|
971 while (st.hasMoreTokens()) { |
|
972 String token = st.nextToken().toLowerCase(); |
|
973 if (token.equals("mono")) |
|
974 channels = 1; |
|
975 if (token.startsWith("channel")) |
|
976 channels = Integer.parseInt(prevToken); |
|
977 if (token.contains("unsigned")) |
|
978 signed = false; |
|
979 if (token.equals("big-endian")) |
|
980 bigendian = true; |
|
981 if (token.equals("bit")) |
|
982 bits = Integer.parseInt(prevToken); |
|
983 if (token.equals("hz")) |
|
984 sampleRate = Float.parseFloat(prevToken); |
|
985 prevToken = token; |
|
986 } |
|
987 item2.value = new AudioFormat(sampleRate, bits, |
|
988 channels, signed, bigendian); |
|
989 } catch (NumberFormatException e) { |
|
990 } |
|
991 |
|
992 } else |
|
993 try { |
|
994 if (c == Byte.class) |
|
995 item2.value = Byte.valueOf(s); |
|
996 else if (c == Short.class) |
|
997 item2.value = Short.valueOf(s); |
|
998 else if (c == Integer.class) |
|
999 item2.value = Integer.valueOf(s); |
|
1000 else if (c == Long.class) |
|
1001 item2.value = Long.valueOf(s); |
|
1002 else if (c == Float.class) |
|
1003 item2.value = Float.valueOf(s); |
|
1004 else if (c == Double.class) |
|
1005 item2.value = Double.valueOf(s); |
|
1006 } catch (NumberFormatException e) { |
|
1007 } |
|
1008 } else if (v instanceof Number) { |
|
1009 Number n = (Number) v; |
|
1010 if (c == Byte.class) |
|
1011 item2.value = Byte.valueOf(n.byteValue()); |
|
1012 if (c == Short.class) |
|
1013 item2.value = Short.valueOf(n.shortValue()); |
|
1014 if (c == Integer.class) |
|
1015 item2.value = Integer.valueOf(n.intValue()); |
|
1016 if (c == Long.class) |
|
1017 item2.value = Long.valueOf(n.longValue()); |
|
1018 if (c == Float.class) |
|
1019 item2.value = Float.valueOf(n.floatValue()); |
|
1020 if (c == Double.class) |
|
1021 item2.value = Double.valueOf(n.doubleValue()); |
|
1022 } |
|
1023 } |
|
1024 } |
875 |
1025 |
876 return items; |
1026 return items; |
877 } |
1027 } |
878 |
1028 |
879 public void open() throws MidiUnavailableException { |
1029 public void open() throws MidiUnavailableException { |