This discussion is archived
9 Replies Latest reply: Aug 29, 2011 5:43 PM by 885295 RSS

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

843802 Newbie
Currently Being Moderated
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 Newbie
    Currently Being Moderated
    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 Guru Moderator
    Currently Being Moderated
    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 Newbie
    Currently Being Moderated
    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 Guru Moderator
    Currently Being Moderated
    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 Guru Moderator
    Currently Being Moderated
    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 Newbie
    Currently Being Moderated
    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 Pro
    Currently Being Moderated
    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 Newbie
    Currently Being Moderated
    [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 Newbie
    Currently Being Moderated
    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.