9 Replies Latest reply: Aug 29, 2011 7:43 PM by 885295 RSS

    Java soundbank - certain patches won't play or have wrong sound???

    843802
      I currently have some code which loops through patch selection of the Java Midi Synthesizer. I can select certain patches just fine (Harmonica, Clean Guitar, etc) but some of them (Grungey Guitar, UFOs) don't make any noise, and some don't sound right, for example: "Click" sounds like an organ. I have updated the soundbank file from Sun.com, and made sure that it was the only .gm file in lib/audio/. What's wrong?

      Edited by: BLuFeNiX on Mar 19, 2010 9:10 AM
        • 1. Re: Java soundbank - certain patches won't play or have wrong sound???
          843802
          UPDATE: The problem persists on different machines, running different OS's. The original was on a Windows XP machine at my school, and I just tested it on my home computer, running Ubuntu 9.10

          The problem is (as far as I can tell) exactly the same. Meaning the same instruments are affected in the same way.

          Does anyone have ANY ideas??? I'll take blind suggestions... Considering how strange this problem seems, anything might lead to the right answer...
          • 2. Re: Java soundbank - certain patches won't play or have wrong sound???
            DarrylBurke
            1. To get better help sooner, post a [_SSCCE_|http://mindprod.com/jgloss/sscce.html] that clearly demonstrates your problem.

            2. Use code tags to post codes -- [code]CODE[/code] will display as
            CODE
            Or click the CODE button and paste your code between the {code} tags that appear.

            3. This topic might receive better responses in the Java Sound forum. Would you like me to move it there?

            db
            • 3. Re: Java soundbank - certain patches won't play or have wrong sound???
              843802
              DarrylBurke wrote:
              3. This topic might receive better responses in the Java Sound forum. Would you like me to move it there?
              Yes, please.


              Here is the code I am using:

              OpenInstrument.java
              import javax.sound.midi.Instrument;
              import javax.sound.midi.MidiChannel;
              import javax.sound.midi.MidiSystem;
              import javax.sound.midi.Patch;
              import javax.sound.midi.Soundbank;
              import javax.sound.midi.Synthesizer;
              
              public class OpenInstrument {
                   
                   Synthesizer synth;
                   MidiChannel channels[];
                   Soundbank bank;
                   Instrument instrs[];
                   Instrument myInstrument;
                   Patch myPatch;
                   
                   OpenInstrument() {
                        try
                              {
                                      // Locate the default synthesizer
                                      synth = MidiSystem.getSynthesizer();
                                      // Open the synthesizer
                                      synth.open();
                                      // Get the available Midi channels - there are usually 16
                                      channels = synth.getChannels();
                                      // Get the synth's soundbank where all the sounds are stored
                                      bank = synth.getDefaultSoundbank();
                                    // Load all the available instruments
                                      synth.loadAllInstruments(bank); 
                                    // Get a list of the available instruments
                                      instrs = synth.getLoadedInstruments();
                              }
                        catch (Exception exc)
                        {
                             exc.printStackTrace();
                        }
                   }
                   
                   public void PrintInstrumentList() {
                        for (int i = 0; i < instrs.length; i++) {
                                    System.out.println(i + ") " + instrs.getName());
              }
                   }
                   
                   public void SetInstrument(int instrumentNum, int channelNum) {
                        myInstrument = instrs[instrumentNum];          
                        // Get the information describing the instrument - the
              // patch contains the soundbank and program number
              myPatch = myInstrument.getPatch();
                        // Set a channel to use the guitar instrument
              channels[1].programChange(myPatch.getBank(),myPatch.getProgram());
                   }
                   
                   public void PlayChord() {
                        try {
                             // Play a chord on channel 1
                             int delay = 1000;
                             channels[1].noteOn(40, 127); //E
                             Thread.sleep(delay);
                             channels[1].noteOn(47, 127); //B
                             Thread.sleep(delay);
                             channels[1].noteOn(52, 127); //E
                             Thread.sleep(delay);
                             channels[1].noteOn(55, 127); //G
                             Thread.sleep(delay);
                             channels[1].noteOn(59, 127); //B
                             Thread.sleep(delay);
                             channels[1].noteOn(64, 127); //E
                             // Give the notes some time to play
                             Thread.sleep(3000);
                             // Turn the notes off
                             channels[1].allNotesOff();
                   }
                        catch (Exception exc)
                        {
                             exc.printStackTrace();
                        }
                   }
                   
                   public void close() {
                        // Close the synthesizer device
              synth.close();
                   }
                   
              }
              *test.java*
              import java.util.Scanner;

              public class test {

                   public static void main(String[] args) {
                        
                        OpenInstrument myInstrument = new OpenInstrument();
                        
                        myInstrument.PrintInstrumentList();
                        int userChoice = 0;
                        while(userChoice >= 0){
                             System.out.print("\nEnter the number of the instrument you wish to use:");
                             Scanner sc = new Scanner(System.in);
                             userChoice = sc.nextInt();
                             myInstrument.SetInstrument(userChoice, 1);
                             System.out.print("Playing Chord... ");
                             myInstrument.PlayChord();
                             System.out.print("Done.\n");
                        }
                        myInstrument.close();

                   }

              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
              • 4. This Thread is now moved
                DarrylBurke
                Note: This thread was originally posted in the [New To Java|http://forums.sun.com/forum.jspa?forumID=54] forum, but moved to this forum for closer topic alignment.
                • 5. Re: Java soundbank - certain patches won't play or have wrong sound???
                  DarrylBurke
                  I don't do MIDI, so I'm probably doing something wrong too. I wrapped a GUI around your code and my observations are:

                  -- Bank 2 instruments are producing no sound
                  -- Bank 3 instruments are producing the same sound as the corresponding Bank 1 instrument

                  -- Bank 1 instruments are actually producing the sound of the corresponding Bank 2 instrument.

                  Run the program and clink any cell in the table (including the blank cells)
                  import java.awt.Component;
                  import java.awt.Point;
                  import java.awt.event.MouseAdapter;
                  import java.awt.event.MouseEvent;
                  import java.awt.event.WindowAdapter;
                  import java.awt.event.WindowEvent;
                  import java.util.Vector;
                  import javax.sound.midi.*;
                  import javax.swing.*;
                  import javax.swing.table.DefaultTableCellRenderer;
                  
                  public class MidiTest {
                  
                    private Synthesizer synth;
                    private MidiChannel channel;
                    private Instrument instruments[];
                  
                    public static void main(String[] args) {
                      SwingUtilities.invokeLater(new Runnable() {
                  
                        @Override
                        public void run() {
                          new MidiTest().makeUI();
                        }
                      });
                    }
                  
                    public void makeUI() {
                      if (!setUpMidi()) {
                        System.out.println("Failed to initialize MIDI!");
                        System.exit(0);
                      }
                  
                      JFrame frame = new JFrame();
                      frame.add(new JScrollPane(getTable()));
                      frame.setSize(500, 500);
                      frame.setLocationRelativeTo(null);
                  
                      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                      frame.addWindowListener(new WindowAdapter() {
                  
                        @Override
                        public void windowClosing(WindowEvent e) {
                          synth.close();
                        }
                      });
                      frame.setVisible(true);
                    }
                  
                    private JTable getTable() {
                      Vector<Vector<Object>> data = new Vector<Vector<Object>>();
                      Vector<Object> headers = new Vector<Object>();
                      for (Instrument instrument : instruments) {
                        Patch patch = instrument.getPatch();
                        int column = patch.getBank();
                        if (headers.size() < column + 1) {
                          for (int i = headers.size(); i < column; i++) {
                            headers.add("xxx");
                            for (Vector rowVector : data) {
                              rowVector.add(null);
                            }
                          }
                          headers.insertElementAt("Bank " + column, column);
                        }
                        int row = patch.getProgram();
                        if (data.size() < row + 1) {
                          for (int i = data.size(); i <= row + 1; i++) {
                            Vector<Object> rowVector = new Vector<Object>();
                            for (int j = 0; j <= column + 1; j++) {
                              rowVector.add(null);
                            }
                            data.add(rowVector);
                          }
                        }
                        Vector rowData = data.get(row);
                        rowData.insertElementAt(instrument, column);
                      }
                  
                      final JTable table = new JTable(data, headers) {
                  
                        @Override
                        public boolean isCellEditable(int row, int column) {
                          return false;
                        }
                      };
                      table.addMouseListener(new MouseAdapter() {
                  
                        @Override
                        public void mouseClicked(MouseEvent e) {
                          Point point = e.getPoint();
                          int row = table.rowAtPoint(point);
                          int column = table.columnAtPoint(point);
                          Instrument instrument = (Instrument) table.getValueAt(row, column);
                  
                          if (instrument == null) {
                            play(column, row);
                          } else {
                            play(instrument);
                          }
                        }
                      });
                  
                      table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() {
                  
                        @Override
                        public Component getTableCellRendererComponent(JTable table, Object value,
                                boolean isSelected, boolean hasFocus, int row, int column) {
                          super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
                          setText(value == null ? "" : ((Instrument) value).getName());
                          return this;
                        }
                      });
                      return table;
                    }
                  
                    private boolean setUpMidi() {
                      try {
                        synth = MidiSystem.getSynthesizer();
                        synth.open();
                        channel = synth.getChannels()[0];
                        synth.loadAllInstruments(synth.getDefaultSoundbank());
                        instruments = synth.getLoadedInstruments();
                        return true;
                      } catch (MidiUnavailableException ex) {
                        ex.printStackTrace();
                      }
                      return false;
                    }
                  
                    private void play(Instrument instrument) {
                      setInstrument(instrument);
                      playChord();
                    }
                  
                    private void play(int bank, int program) {
                      setInstrument(bank, program);
                      playChord();
                    }
                  
                    private void setInstrument(Instrument instrument) {
                      Patch patch = instrument.getPatch();
                      channel.programChange(patch.getBank(), patch.getProgram());
                      System.out.printf("%25s  Bank: %d  Program: %3d\n",
                              instrument.getName(), patch.getBank(), patch.getProgram());
                    }
                  
                    private void setInstrument(int bank, int program) {
                      channel.programChange(bank, program);
                      System.out.printf("%25s  Bank: %d  Program: %3d\n",
                              "", bank, program);
                    }
                  
                    private void playChord() {
                      new Thread(new Runnable() {
                  
                        @Override
                        public void run() {
                          try {
                            int delay = 150;
                            channel.noteOn(40, 64);
                            Thread.sleep(delay);
                            channel.noteOn(47, 64);
                            Thread.sleep(delay);
                            channel.noteOn(52, 64);
                            Thread.sleep(delay);
                            channel.noteOn(56, 64);
                            Thread.sleep(1000);
                            channel.allNotesOff();
                          } catch (InterruptedException ex) {
                            ex.printStackTrace();
                          }
                        }
                      }).start();
                    }
                  }
                  Hopefully some MIDI guru will throw light on this.

                  db
                  • 6. Re: Java soundbank - certain patches won't play or have wrong sound???
                    843802
                    I agree with your observations. Thank you.

                    Anyone else have any thoughts?
                    • 7. Re: Java soundbank - certain patches won't play or have wrong sound???
                      captfoss
                      I'm not a MIDI guru but I think I'm about the closest thing this forum has to one...

                      All I can do is point you to some soundbank examples...
                      [http://www.jsresources.org/examples/LoadSoundbank.html]
                      [http://www.jsresources.org/examples/DisplaySoundbank.html]

                      And point you to the Soundbank FAQ
                      [http://www.jsresources.org/faq_midi.html#sec_soundbank]

                      And point you to the manual...
                      [http://java.sun.com/j2se/1.5.0/docs/guide/sound/programmer_guide/chapter12.html#121793]

                      My biggest concern would be that the soundbank you're trying to use could be crap... I'd recommend finding some other soundbanks and trying them. And check to make sure your code works in a similar manner as the example code.
                      • 8. Re: Java soundbank - certain patches won't play or have wrong sound???
                        843802
                        [http://www.jsresources.org/faq_midi.html#bank_2]

                        It seems as though this is a problem that has yet to be addressed (see link)
                        • 9. Re: Java soundbank - certain patches won't play or have wrong sound???
                          885295
                          The following Java code is a workaround for the problem:

                          MidiChannel[] channels = synth.getChannels();
                          synth.loadInstrument( instrument );
                          Patch p = instrument.getPatch();
                          int bank = p.getBank(), program = p.getProgram();
                          program |= (bank&1)<<7; bank >>>= 1; // correction:
                          channels[channel].programChange(bank, program); // (BBBBBB, BPPPPPPP)

                          After correction all instruments seems to play correctly.
                          The problem seems to come from the Java API which may have a bit shifting of 8 instead of 7 for the bank number.