Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8054441
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 5, 20262026-06-05T08:09:10+00:00 2026-06-05T08:09:10+00:00

I’ve recently run into a strange bug with playing midis in a game I’m

  • 0

I’ve recently run into a strange bug with playing midis in a game I’m developing. I thought my midi code was working fine since it used to play midis without sounding weird. Now whenever it plays midis, they sound all tinny, echo-y, and loud.

I haven’t touched my midi player code for a very long time, so I’m wondering if it’s possible that a recent Java update has exposed a bug that has been in my code all along. Or perhaps there’s some sort of midi bug in my version of Java that I’m not aware of?

The midis sound fine whenever I play them outside of my game.

I’m running Java 6, update 31, build 1.6.0_31-b05. Here’s a SSCCE that reproduces the problem (it reproduces it on my JVM at least):

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import javax.sound.midi.*;
import java.net.URL;

public class MidiSSCCE extends JFrame
{

    public MidiSSCCE()
    {
        super("Sound problem SSCCE");
        this.setSize(200,100);

        // instantiate main window panel

        JPanel screenP = new SSCCEPanel(this);
        this.add(screenP);

        // finishing touches on Game window

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);

        System.out.println("Game Window successfully created!!!");
    }

    public static void main(String[] args)
    {
        MidiSSCCE gui = new MidiSSCCE();        
    }
}


/**
*   SSCCEPanel is the JPanel that manages the example's timer, painting, and logic. 
**/

class SSCCEPanel extends JPanel
{
    public Frame parentFrame;
    private Timer timer;
    public int logicLoops;
    public double prevFPS;
    boolean timerReady;

    // The MidiPlayer object is used by the example to play the midi.

    public MidiPlayer midiPlayer;

    public SSCCEPanel(Frame parent)
    {
        super(true);
        parentFrame = parent;
        this.setFocusable(true);

        Toolkit.getDefaultToolkit().sync();
        logicLoops = 0;

        midiPlayer = new MidiPlayer();

        TimerListener timerListener = new TimerListener();
        prevFPS = 0;
        timerReady = true;
        timer = new Timer(0,timerListener);
        this.setFPS(60);
        timer.start();
    }

    /** 
    *   setFPS()
    *   Preconditions: fps is a quantity of frames per second
    *   Postconditions: Sets the timer's refresh rate so that it 
    *       fires fps times per second.
    **/

    public void setFPS(int fps)
    {
        int mspf = (int) (1000.0 /fps + 0.5);
        timer.setDelay(mspf);
    }


    /**
    *   This is the JPanel's timer listener. It runs the example's logic and repaint
    *   methods each time it gets a timer signal.
    **/

    private class TimerListener implements ActionListener
    {
        long startTime = System.currentTimeMillis();
        long lastTime = this.startTime;
        int ticks = 0;

        public void actionPerformed(ActionEvent e)
        {
            Object source = e.getSource();
            if(source == timer)
            {
                // perform a loop through the game's logic and repaint.

                synchronized(this)
                {
                    if(timerReady)
                    {
                        timerReady = false;
                        runSSCCELogic();
                        repaint();
                        timerReady = true;
                    }
                }

                // Logic for Frames per Second counter

                this.ticks++;

                long currentTime = System.currentTimeMillis();

                if(currentTime - startTime >= 500) 
                {
                    prevFPS =  1000.0 * ticks/(1.0*currentTime - startTime);
                    System.out.println(prevFPS);
                    startTime = currentTime;
                    ticks = 0;
                }

                lastTime = currentTime;
            }
        }
    }


    /**
    *   repaints the SSCCE.
    *   This just shows the current FPS.
    **/

    public void paintComponent(Graphics g)
    {
            super.paintComponent(g);

            Graphics2D g2D = (Graphics2D) g;
            double roundedFPS = Math.round(prevFPS*10)/10.0;

            g2D.setColor(new Color(0x000000));
            g2D.drawString("FPS: " + roundedFPS, 20,20);
            g.dispose();
    }

    /**
    *   runSSCCEELogic()
    *   This is where the run-time logic for the SSCCE example is. 
    *   All it does is load and play a midi called "mymidi.mid" which is located in the same directory.
    **/

    public void runSSCCELogic()
    {
        if(logicLoops == 1)
        {
            midiPlayer.load("http://www.vgmusic.com/music/computer/microsoft/windows/touhou_6_stage3_boss.mid");
            midiPlayer.play(true);
        }

        logicLoops++;
    }
}



/**
*   MidiPlayer
*   A class that allows midi files to be loaded and played. 
**/

class MidiPlayer
{
    private Sequence seq;
    private Sequencer seqr;
    private Synthesizer synth;
    private Receiver receiver;
    private File midiFile;
    private String midiID;
    private boolean loaded;
    private boolean usingHardwareSoundbank;

    // CONSTRUCTORS

    public MidiPlayer()
    {
        loaded = false;
        try
        {
            seqr = MidiSystem.getSequencer();
            synth = MidiSystem.getSynthesizer();
        }
        catch(Exception e)
        {
            System.out.println("MIDI error: It appears your system doesn't have a MIDI device or your device is not working.");
        }
    }

    /**
    *   MidiPlayer(String fileName)
    *   Constructor that also loads an initial midi file.
    *   Preconditions: fileName is the name of the midi file to be loaded. 
    *   Postconditions: The MidiPlayer is created and loaded with the midi specified by fileName.
    **/

    public MidiPlayer(String fileName)
    {
        this();
        load(fileName);
    }


    // DATA METHODS

    /**
    *   load(String fileName)
    *   loads a midi file into this MidiPlayer.
    *   Preconditions: fileName is the name of the midi file to be loaded.
    *   Postconditions: fileName is loaded and is ready to be played.
    **/

    public void load(String fileName)
    {
        this.unload();
        try
        {
            URL midiURL =  new URL(fileName);
        //  midiFile = new File(fileName);
            seq = MidiSystem.getSequence(midiURL);

            seqr.open();
            synth.open();

            System.out.println("MidiDeviceInfo: ");
            for(MidiDevice.Info info : MidiSystem.getMidiDeviceInfo())
            {
                System.out.println("\t" + info);
            }
            System.out.println();

            if(synth.getDefaultSoundbank() == null)
            {
                receiver = MidiSystem.getReceiver();
                usingHardwareSoundbank = true;
                System.out.println("using hardware soundbank");
            }
            else
            {
                receiver = synth.getReceiver();
                usingHardwareSoundbank = false;
                System.out.println("using default software soundbank:" + synth.getDefaultSoundbank());
            }
            seqr.getTransmitter().setReceiver(receiver);

            seqr.setSequence(seq);
            loaded = true;
        }
        catch(IOException ioe)
        {
            System.out.println("MIDI error: Problem occured while reading " + midiFile.getName() + ".");
        }
        catch(InvalidMidiDataException imde)
        {
            System.out.println("MIDI error: " + midiFile.getName() + " is not a valid MIDI file or is unreadable.");
        }
        catch(Exception e)
        {
            System.out.println("MIDI error: Unexplained error occured while loading midi.");
        }
    }

    /**
    *   unload()
    *   Unloads the current midi from the MidiPlayer and releases its resources from memory.
    **/

    public void unload()
    {
        this.stop();
        seqr.close();
        midiFile = null;
        loaded = false;
    }

    // OTHER METHODS

    /**
    *   setMidiID(String id)
    *   associates a String ID with the current midi.
    *   Preconditions: id is the ID we are associating with the current midi.
    **/

    public void setMidiID(String id)
    {
        midiID = id;
    }

    /**
    *   getMidiID(String id)
    *
    **/

    public String getMidiID()
    {
        return new String(midiID);
    }

    /**
    *   play(boolean reset)
    *   plays the currently loaded midi.
    *   Preconditions: reset tells our midi whether or nor to begin playing from the start of the midi file's current loop start point.
    *   Postconditions: If reset is true, then the loaded midi begins playing from its loop start point (default 0). 
    *       If reset is false, then the loaded midi resumes playing from its current position.
    **/

    public void play(boolean reset)
    {
        if(reset)
            seqr.setTickPosition(seqr.getLoopStartPoint());
        seqr.start();
    }

    /**
    *   stop()
    *   Pauses the current midi if it was playing.
    **/

    public void stop()
    {
        if(seqr.isOpen())
            seqr.stop();
    }

    /**
    *   isRunning()
    *   Returns true if the current midi is playing. Returns false otherwise.
    **/

    public boolean isRunning()
    {
        return seqr.isRunning();
    }


    /**
    *   loop(int times)
    *   Sets the current midi to loop from start to finish a specific number of times.
    *   Preconditions: times is the number of times we want our midi to loop.
    *   Postconditions: The current midi is set to loop times times. 
    *       If times = -1, the current midi will be set to loop infinitely.
    **/

    public void loop(int times)
    {
        loop(times,0,-1);
    }

    /**
    *   loop(int times)
    *   Sets the current midi to loop from a specified start point to a specified end point a specific number of times.
    *   Preconditions: times is the number of times we want our midi to loop.
    *       start is our loop's start point in ticks.
    *       end is our loop's end point in ticks.
    *   Postconditions: The current midi is set to loop from tick start to tick end times times. 
    *       If times = -1, the current midi will be set to loop infinitely.
    **/

    public void loop(int times, long start, long end)
    {
        if(start < 0)
            start = 0;
        if(end > seqr.getSequence().getTickLength() || end <= 0)
            end = seqr.getSequence().getTickLength();

        if(start >= end && end != -1)
            start = end-1;

        seqr.setLoopStartPoint(start);
        seqr.setLoopEndPoint(end);

        if(times == -1)
            seqr.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);
        else
            seqr.setLoopCount(times);

    }


    public void setVolume(double vol)
    {
        try 
        {
            if(usingHardwareSoundbank)
            {
                ShortMessage volumeMessage = new ShortMessage();
                for ( int i = 0; i < 16; i++ ) 
                {
                    volumeMessage.setMessage( ShortMessage.CONTROL_CHANGE, i, 7, (int)(vol*127) );
                    receiver.send( volumeMessage, -1 );
                }
            }
            else
            {
                MidiChannel[] channels = synth.getChannels();
                for( int c = 0; channels != null && c < channels.length; c++ )
                {
                  channels[c].controlChange( 7, (int)( vol*127) );
                }
            }
        } 
        catch ( Exception e ) 
        {
            e.printStackTrace();
        }
    }

}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-05T08:09:11+00:00Added an answer on June 5, 2026 at 8:09 am

    I made a change to my MidiPlayer code that seems to have resolved the problem for me. I moved the code where it loads the soundbank and the transmitter’s receiver to the constructor instead of in the method where it loads a midi. It no longer sounds really loud and tinny.

      package gameEngine;
    
      import javax.sound.midi.*;
      import java.io.File;
      import java.io.IOException;
      import java.net.URL;
    
      /**
      * MidiPlayer
      * author: Stephen Lindberg
      * Last modified: Oct 14, 2011
      * 
      * A class that allows midi files to be loaded and played.
      **/
    
      public class MidiPlayer
      {
         private Sequence seq;
         private Sequencer seqr;
         private Synthesizer synth;
         private Receiver receiver;
         private File midiFile;
         private String midiID;
         private boolean loaded;
         private boolean usingHardwareSoundbank;
         private float defaultTempo;
    
         // CONSTRUCTORS
    
         public MidiPlayer()
         {
            loaded = false;
            try
            {
               seqr = MidiSystem.getSequencer();
               synth = MidiSystem.getSynthesizer();
    
               // print the user's midi device info
               System.out.println("Setting up Midi Player...");
               System.out.println("MidiDeviceInfo: ");
               for(MidiDevice.Info info : MidiSystem.getMidiDeviceInfo())
               {
                  System.out.println("\t" + info.getName() + ": " +info.getDescription());
               }
               System.out.println();
    
               // obtain the receiver. This will be used for changing volume.
    
               Soundbank soundbank = synth.getDefaultSoundbank();
               if(soundbank == null)
               {
                  receiver = MidiSystem.getReceiver();
                  usingHardwareSoundbank = true;
                  System.out.println("using hardware soundbank");
               }
               else
               {
                  synth.loadAllInstruments(soundbank);
                  receiver = synth.getReceiver();
                  usingHardwareSoundbank = false;
                  System.out.println("using default software soundbank:" + soundbank);
               }
               seqr.getTransmitter().setReceiver(receiver);
    
            }
            catch(Exception e)
            {
               System.out.println("MIDI error: It appears your system doesn't have a MIDI device or your device is not working.");
            }
         }
    
         /**
         *  MidiPlayer(String fileName)
         *  Constructor that also loads an initial midi file.
         *  Preconditions: fileName is the name of the midi file to be loaded. 
         *  Postconditions: The MidiPlayer is created and loaded with the midi specified by fileName.
         **/
    
         public MidiPlayer(String fileName)
         {
            this();
            load(fileName);
         }
    
    
         // DATA METHODS
    
         /**
         *  load(String fileName)
         *  loads a midi file into this MidiPlayer.
         *  Preconditions: fileName is the name of the midi file to be loaded.
         *  Postconditions: fileName is loaded and is ready to be played.
         **/
    
         public void load(String fileName)
         {
            this.unload();
            try
            {
               URL midiURL =  getClass().getClassLoader().getResource(fileName);
               seq = MidiSystem.getSequence(midiURL);
    
               seqr.open();
               synth.open();
    
               // load our sequence into the sequencer.
    
               seqr.setSequence(seq);
               loaded = true;
               defaultTempo = seqr.getTempoInBPM();
            }
            catch(IOException ioe)
            {
               System.out.println("MIDI error: Problem occured while reading " + midiFile.getName() + ".");
            }
            catch(InvalidMidiDataException imde)
            {
               System.out.println("MIDI error: " + midiFile.getName() + " is not a valid MIDI file or is unreadable.");
            }
            catch(Exception e)
            {
               System.out.println("MIDI error: Unexplained error occured while loading midi.");
            }
         }
    
         /**
         *  unload()
         *  Unloads the current midi from the MidiPlayer and releases its resources from memory.
         **/
    
         public void unload()
         {
            this.stop();
            seqr.close();
            synth.close();
            midiFile = null;
            loaded = false;
         }
    
         // OTHER METHODS
    
         /**
         *  setMidiID(String id)
         *  associates a String ID with the current midi.
         *  Preconditions: id is the ID we are associating with the current midi.
         **/
    
         public void setMidiID(String id)
         {
            midiID = id;
         }
    
         /**
         *  getMidiID(String id)
         *
         **/
    
         public String getMidiID()
         {
            return new String(midiID);
         }
    
         /**
         *  play(boolean reset)
         *  plays the currently loaded midi.
         *  Preconditions: reset tells our midi whether or nor to begin playing from the start of the midi file's current loop start point.
         *  Postconditions: If reset is true, then the loaded midi begins playing from its loop start point (default 0). 
         *      If reset is false, then the loaded midi resumes playing from its current position.
         **/
    
         public void play(boolean reset)
         {
            if(reset)
               seqr.setTickPosition(seqr.getLoopStartPoint());
            seqr.start();
         }
    
         /**
         *  stop()
         *  Pauses the current midi if it was playing.
         **/
    
         public void stop()
         {
            if(seqr.isOpen())
               seqr.stop();
         }
    
         /**
         *  isRunning()
         *  Returns true if the current midi is playing. Returns false otherwise.
         **/
    
         public boolean isRunning()
         {
            return seqr.isRunning();
         }
    
    
    
         /**
         *  getTempo()
         *  Returns the current tempo of the MidiPlayer in BPM (Beats per Minute).
         **/
    
         public float getTempo()
         {
            return seqr.getTempoInBPM();
         }
    
         /**
         *  loop(int times)
         *  Sets the current midi to loop from start to finish a specific number of times.
         *  Preconditions: times is the number of times we want our midi to loop.
         *  Postconditions: The current midi is set to loop times times. 
         *      If times = -1, the current midi will be set to loop infinitely.
         **/
    
         public void loop(int times)
         {
            loop(times,0,-1);
         }
    
         /**
         *  loop(int times)
         *  Sets the current midi to loop from a specified start point to a specified end point a specific number of times.
         *  Preconditions: times is the number of times we want our midi to loop.
         *      start is our loop's start point in ticks.
         *      end is our loop's end point in ticks.
         *  Postconditions: The current midi is set to loop from tick start to tick end times times. 
         *      If times = -1, the current midi will be set to loop infinitely.
         **/
    
         public void loop(int times, long start, long end)
         {
            if(start < 0)
               start = 0;
            if(end > seqr.getSequence().getTickLength() || end <= 0)
               end = seqr.getSequence().getTickLength();
    
            if(start >= end && end != -1)
               start = end-1;
    
            seqr.setLoopStartPoint(start);
            seqr.setLoopEndPoint(end);
    
            if(times == -1)
               seqr.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);
            else
               seqr.setLoopCount(times);
    
         }
    
         /**
         *  resetTempo()
         *  Resets the MidiPlayer's tempo the the initial tempo of its current midi.
         **/
    
         public void resetTempo()
         {
            this.changeTempo(this.defaultTempo);
         }
    
         /**
         *  changeTempo(float bpm)
         *  Changes the MidiPlayer's current tempo.
         *  Preconditions: bpm is the MidiPlayer's new tempo in BPM (Beats per Minute).
         *  Postconditions: The MidiPlayer's current tempo is set to bpm BPM.
         **/
    
         public void changeTempo(float bpm)
         {
            double lengthCoeff = bpm/seqr.getTempoInBPM();
    
            seqr.setLoopStartPoint((long) (seqr.getLoopStartPoint()*lengthCoeff));
            seqr.setLoopEndPoint((long) (seqr.getLoopEndPoint()*lengthCoeff));
    
            seqr.setTempoInBPM(bpm);
         }
    
    
         public void setVolume(double vol)
         {
            System.out.println("Midi volume change request: " + vol);
    
            try 
            {
               if(usingHardwareSoundbank)
               {
                  ShortMessage volumeMessage = new ShortMessage();
                  for ( int i = 0; i < 16; i++ ) 
                  {
                     volumeMessage.setMessage( ShortMessage.CONTROL_CHANGE, i, 7, (int)(vol*127) );
                     receiver.send( volumeMessage, -1 );
                  }
               }
               else
               {
                  MidiChannel[] channels = synth.getChannels();
    
                  for( int c = 0; c < channels.length; c++ )
                  {
                     if(channels[c] != null) {
                        channels[c].controlChange( 7, (int)( vol*127) );
                     }
                  }
               }
            } 
            catch ( Exception e ) 
            {
               e.printStackTrace();
            }
         }
    
      }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

link Im having trouble converting the html entites into html characters, (&# 8217;) i
I ran into a problem. Wrote the following code snippet: teksti = teksti.Trim() teksti
I have a jquery bug and I've been looking for hours now, I can't
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
this is what i have right now Drawing an RSS feed into the php,
I have this code to decode numeric html entities to the UTF8 equivalent character.
I have a French site that I want to parse, but am running into
I would like to run a str_replace or preg_replace which looks for certain words
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I have this code: - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock { NSString *someString = [[NSString

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.