5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package com.sun.media.sound;
26
27 import java.io.File;
28 import java.io.FileInputStream;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.OutputStream;
32 import java.net.URL;
33 import java.util.ArrayList;
34 import java.util.Arrays;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.Map;
38
39 import javax.sound.midi.Instrument;
40 import javax.sound.midi.Patch;
41 import javax.sound.midi.Soundbank;
42 import javax.sound.midi.SoundbankResource;
43
44 /**
64 // Sound ROM Version
65 int romVersionMajor = -1;
66 int romVersionMinor = -1;
67 // Date of Creation of the Bank
68 String creationDate = null;
69 // Sound Designers and Engineers for the Bank
70 String engineers = null;
71 // Product for which the Bank was intended
72 String product = null;
73 // Copyright message
74 String copyright = null;
75 // Comments
76 String comments = null;
77 // The SoundFont tools used to create and alter the bank
78 String tools = null;
79 // The Sample Data loaded from the SoundFont
80 private ModelByteBuffer sampleData = null;
81 private ModelByteBuffer sampleData24 = null;
82 private File sampleFile = null;
83 private boolean largeFormat = false;
84 private final List<SF2Instrument> instruments = new ArrayList<SF2Instrument>();
85 private final List<SF2Layer> layers = new ArrayList<SF2Layer>();
86 private final List<SF2Sample> samples = new ArrayList<SF2Sample>();
87
88 public SF2Soundbank() {
89 }
90
91 public SF2Soundbank(URL url) throws IOException {
92
93 InputStream is = url.openStream();
94 try {
95 readSoundbank(is);
96 } finally {
97 is.close();
98 }
99 }
100
101 public SF2Soundbank(File file) throws IOException {
102 largeFormat = true;
103 sampleFile = file;
104 InputStream is = new FileInputStream(file);
105 try {
106 readSoundbank(is);
207 chunk.readFully(sampleData24, read, 65536);
208 read += 65536;
209 } else {
210 chunk.readFully(sampleData24, read, avail - read);
211 read = avail;
212 }
213
214 }
215 this.sampleData24 = new ModelByteBuffer(sampleData24);
216 } else {
217 this.sampleData24 = new ModelByteBuffer(sampleFile,
218 chunk.getFilePointer(), chunk.available());
219 }
220
221 }
222 }
223 }
224
225 private void readPdtaChunk(RIFFReader riff) throws IOException {
226
227 List<SF2Instrument> presets = new ArrayList<SF2Instrument>();
228 List<Integer> presets_bagNdx = new ArrayList<Integer>();
229 List<SF2InstrumentRegion> presets_splits_gen
230 = new ArrayList<SF2InstrumentRegion>();
231 List<SF2InstrumentRegion> presets_splits_mod
232 = new ArrayList<SF2InstrumentRegion>();
233
234 List<SF2Layer> instruments = new ArrayList<SF2Layer>();
235 List<Integer> instruments_bagNdx = new ArrayList<Integer>();
236 List<SF2LayerRegion> instruments_splits_gen
237 = new ArrayList<SF2LayerRegion>();
238 List<SF2LayerRegion> instruments_splits_mod
239 = new ArrayList<SF2LayerRegion>();
240
241 while (riff.hasNextChunk()) {
242 RIFFReader chunk = riff.nextChunk();
243 String format = chunk.getFormat();
244 if (format.equals("phdr")) {
245 // Preset Header / Instrument
246 if (chunk.available() % 38 != 0)
247 throw new RIFFInvalidDataException();
248 int count = chunk.available() / 38;
249 for (int i = 0; i < count; i++) {
250 SF2Instrument preset = new SF2Instrument(this);
251 preset.name = chunk.readString(20);
252 preset.preset = chunk.readUnsignedShort();
253 preset.bank = chunk.readUnsignedShort();
254 presets_bagNdx.add(chunk.readUnsignedShort());
255 preset.library = chunk.readUnsignedInt();
256 preset.genre = chunk.readUnsignedInt();
257 preset.morphology = chunk.readUnsignedInt();
258 presets.add(preset);
259 if (i != count - 1)
813 if (startLoop < start)
814 startLoop = start;
815 if (endLoop > end)
816 endLoop = end;
817 shdr_chunk.writeUnsignedInt(start);
818 shdr_chunk.writeUnsignedInt(end);
819 shdr_chunk.writeUnsignedInt(startLoop);
820 shdr_chunk.writeUnsignedInt(endLoop);
821 shdr_chunk.writeUnsignedInt(sample.sampleRate);
822 shdr_chunk.writeUnsignedByte(sample.originalPitch);
823 shdr_chunk.writeByte(sample.pitchCorrection);
824 shdr_chunk.writeUnsignedShort(sample.sampleLink);
825 shdr_chunk.writeUnsignedShort(sample.sampleType);
826 sample_pos += 32;
827 }
828 shdr_chunk.writeString("EOS", 20);
829 shdr_chunk.write(new byte[26]);
830
831 }
832
833 public String getName() {
834 return name;
835 }
836
837 public String getVersion() {
838 return major + "." + minor;
839 }
840
841 public String getVendor() {
842 return engineers;
843 }
844
845 public String getDescription() {
846 return comments;
847 }
848
849 public void setName(String s) {
850 name = s;
851 }
852
853 public void setVendor(String s) {
854 engineers = s;
855 }
856
857 public void setDescription(String s) {
858 comments = s;
859 }
860
861 public SoundbankResource[] getResources() {
862 SoundbankResource[] resources
863 = new SoundbankResource[layers.size() + samples.size()];
864 int j = 0;
865 for (int i = 0; i < layers.size(); i++)
866 resources[j++] = layers.get(i);
867 for (int i = 0; i < samples.size(); i++)
868 resources[j++] = samples.get(i);
869 return resources;
870 }
871
872 public SF2Instrument[] getInstruments() {
873 SF2Instrument[] inslist_array
874 = instruments.toArray(new SF2Instrument[instruments.size()]);
875 Arrays.sort(inslist_array, new ModelInstrumentComparator());
876 return inslist_array;
877 }
878
879 public SF2Layer[] getLayers() {
880 return layers.toArray(new SF2Layer[layers.size()]);
881 }
882
883 public SF2Sample[] getSamples() {
884 return samples.toArray(new SF2Sample[samples.size()]);
885 }
886
887 public Instrument getInstrument(Patch patch) {
888 int program = patch.getProgram();
889 int bank = patch.getBank();
890 boolean percussion = false;
891 if (patch instanceof ModelPatch)
892 percussion = ((ModelPatch)patch).isPercussion();
893 for (Instrument instrument : instruments) {
894 Patch patch2 = instrument.getPatch();
895 int program2 = patch2.getProgram();
896 int bank2 = patch2.getBank();
897 if (program == program2 && bank == bank2) {
898 boolean percussion2 = false;
899 if (patch2 instanceof ModelPatch)
900 percussion2 = ((ModelPatch) patch2).isPercussion();
901 if (percussion == percussion2)
902 return instrument;
903 }
904 }
905 return null;
906 }
955
956 public String getTools() {
957 return tools;
958 }
959
960 public void setTools(String tools) {
961 this.tools = tools;
962 }
963
964 public void addResource(SoundbankResource resource) {
965 if (resource instanceof SF2Instrument)
966 instruments.add((SF2Instrument)resource);
967 if (resource instanceof SF2Layer)
968 layers.add((SF2Layer)resource);
969 if (resource instanceof SF2Sample)
970 samples.add((SF2Sample)resource);
971 }
972
973 public void removeResource(SoundbankResource resource) {
974 if (resource instanceof SF2Instrument)
975 instruments.remove((SF2Instrument)resource);
976 if (resource instanceof SF2Layer)
977 layers.remove((SF2Layer)resource);
978 if (resource instanceof SF2Sample)
979 samples.remove((SF2Sample)resource);
980 }
981
982 public void addInstrument(SF2Instrument resource) {
983 instruments.add(resource);
984 }
985
986 public void removeInstrument(SF2Instrument resource) {
987 instruments.remove(resource);
988 }
989 }
|
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.media.sound;
27
28 import java.io.File;
29 import java.io.FileInputStream;
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.OutputStream;
33 import java.net.URL;
34 import java.util.ArrayList;
35 import java.util.Arrays;
36 import java.util.Iterator;
37 import java.util.List;
38 import java.util.Map;
39
40 import javax.sound.midi.Instrument;
41 import javax.sound.midi.Patch;
42 import javax.sound.midi.Soundbank;
43 import javax.sound.midi.SoundbankResource;
44
45 /**
65 // Sound ROM Version
66 int romVersionMajor = -1;
67 int romVersionMinor = -1;
68 // Date of Creation of the Bank
69 String creationDate = null;
70 // Sound Designers and Engineers for the Bank
71 String engineers = null;
72 // Product for which the Bank was intended
73 String product = null;
74 // Copyright message
75 String copyright = null;
76 // Comments
77 String comments = null;
78 // The SoundFont tools used to create and alter the bank
79 String tools = null;
80 // The Sample Data loaded from the SoundFont
81 private ModelByteBuffer sampleData = null;
82 private ModelByteBuffer sampleData24 = null;
83 private File sampleFile = null;
84 private boolean largeFormat = false;
85 private final List<SF2Instrument> instruments = new ArrayList<>();
86 private final List<SF2Layer> layers = new ArrayList<>();
87 private final List<SF2Sample> samples = new ArrayList<>();
88
89 public SF2Soundbank() {
90 }
91
92 public SF2Soundbank(URL url) throws IOException {
93
94 InputStream is = url.openStream();
95 try {
96 readSoundbank(is);
97 } finally {
98 is.close();
99 }
100 }
101
102 public SF2Soundbank(File file) throws IOException {
103 largeFormat = true;
104 sampleFile = file;
105 InputStream is = new FileInputStream(file);
106 try {
107 readSoundbank(is);
208 chunk.readFully(sampleData24, read, 65536);
209 read += 65536;
210 } else {
211 chunk.readFully(sampleData24, read, avail - read);
212 read = avail;
213 }
214
215 }
216 this.sampleData24 = new ModelByteBuffer(sampleData24);
217 } else {
218 this.sampleData24 = new ModelByteBuffer(sampleFile,
219 chunk.getFilePointer(), chunk.available());
220 }
221
222 }
223 }
224 }
225
226 private void readPdtaChunk(RIFFReader riff) throws IOException {
227
228 List<SF2Instrument> presets = new ArrayList<>();
229 List<Integer> presets_bagNdx = new ArrayList<>();
230 List<SF2InstrumentRegion> presets_splits_gen = new ArrayList<>();
231 List<SF2InstrumentRegion> presets_splits_mod = new ArrayList<>();
232
233 List<SF2Layer> instruments = new ArrayList<>();
234 List<Integer> instruments_bagNdx = new ArrayList<>();
235 List<SF2LayerRegion> instruments_splits_gen = new ArrayList<>();
236 List<SF2LayerRegion> instruments_splits_mod = new ArrayList<>();
237
238 while (riff.hasNextChunk()) {
239 RIFFReader chunk = riff.nextChunk();
240 String format = chunk.getFormat();
241 if (format.equals("phdr")) {
242 // Preset Header / Instrument
243 if (chunk.available() % 38 != 0)
244 throw new RIFFInvalidDataException();
245 int count = chunk.available() / 38;
246 for (int i = 0; i < count; i++) {
247 SF2Instrument preset = new SF2Instrument(this);
248 preset.name = chunk.readString(20);
249 preset.preset = chunk.readUnsignedShort();
250 preset.bank = chunk.readUnsignedShort();
251 presets_bagNdx.add(chunk.readUnsignedShort());
252 preset.library = chunk.readUnsignedInt();
253 preset.genre = chunk.readUnsignedInt();
254 preset.morphology = chunk.readUnsignedInt();
255 presets.add(preset);
256 if (i != count - 1)
810 if (startLoop < start)
811 startLoop = start;
812 if (endLoop > end)
813 endLoop = end;
814 shdr_chunk.writeUnsignedInt(start);
815 shdr_chunk.writeUnsignedInt(end);
816 shdr_chunk.writeUnsignedInt(startLoop);
817 shdr_chunk.writeUnsignedInt(endLoop);
818 shdr_chunk.writeUnsignedInt(sample.sampleRate);
819 shdr_chunk.writeUnsignedByte(sample.originalPitch);
820 shdr_chunk.writeByte(sample.pitchCorrection);
821 shdr_chunk.writeUnsignedShort(sample.sampleLink);
822 shdr_chunk.writeUnsignedShort(sample.sampleType);
823 sample_pos += 32;
824 }
825 shdr_chunk.writeString("EOS", 20);
826 shdr_chunk.write(new byte[26]);
827
828 }
829
830 @Override
831 public String getName() {
832 return name;
833 }
834
835 @Override
836 public String getVersion() {
837 return major + "." + minor;
838 }
839
840 @Override
841 public String getVendor() {
842 return engineers;
843 }
844
845 @Override
846 public String getDescription() {
847 return comments;
848 }
849
850 public void setName(String s) {
851 name = s;
852 }
853
854 public void setVendor(String s) {
855 engineers = s;
856 }
857
858 public void setDescription(String s) {
859 comments = s;
860 }
861
862 @Override
863 public SoundbankResource[] getResources() {
864 SoundbankResource[] resources
865 = new SoundbankResource[layers.size() + samples.size()];
866 int j = 0;
867 for (int i = 0; i < layers.size(); i++)
868 resources[j++] = layers.get(i);
869 for (int i = 0; i < samples.size(); i++)
870 resources[j++] = samples.get(i);
871 return resources;
872 }
873
874 @Override
875 public SF2Instrument[] getInstruments() {
876 SF2Instrument[] inslist_array
877 = instruments.toArray(new SF2Instrument[instruments.size()]);
878 Arrays.sort(inslist_array, new ModelInstrumentComparator());
879 return inslist_array;
880 }
881
882 public SF2Layer[] getLayers() {
883 return layers.toArray(new SF2Layer[layers.size()]);
884 }
885
886 public SF2Sample[] getSamples() {
887 return samples.toArray(new SF2Sample[samples.size()]);
888 }
889
890 @Override
891 public Instrument getInstrument(Patch patch) {
892 int program = patch.getProgram();
893 int bank = patch.getBank();
894 boolean percussion = false;
895 if (patch instanceof ModelPatch)
896 percussion = ((ModelPatch)patch).isPercussion();
897 for (Instrument instrument : instruments) {
898 Patch patch2 = instrument.getPatch();
899 int program2 = patch2.getProgram();
900 int bank2 = patch2.getBank();
901 if (program == program2 && bank == bank2) {
902 boolean percussion2 = false;
903 if (patch2 instanceof ModelPatch)
904 percussion2 = ((ModelPatch) patch2).isPercussion();
905 if (percussion == percussion2)
906 return instrument;
907 }
908 }
909 return null;
910 }
959
960 public String getTools() {
961 return tools;
962 }
963
964 public void setTools(String tools) {
965 this.tools = tools;
966 }
967
968 public void addResource(SoundbankResource resource) {
969 if (resource instanceof SF2Instrument)
970 instruments.add((SF2Instrument)resource);
971 if (resource instanceof SF2Layer)
972 layers.add((SF2Layer)resource);
973 if (resource instanceof SF2Sample)
974 samples.add((SF2Sample)resource);
975 }
976
977 public void removeResource(SoundbankResource resource) {
978 if (resource instanceof SF2Instrument)
979 instruments.remove(resource);
980 if (resource instanceof SF2Layer)
981 layers.remove(resource);
982 if (resource instanceof SF2Sample)
983 samples.remove(resource);
984 }
985
986 public void addInstrument(SF2Instrument resource) {
987 instruments.add(resource);
988 }
989
990 public void removeInstrument(SF2Instrument resource) {
991 instruments.remove(resource);
992 }
993 }
|