2012-06-09 10 views
5

मैं मिडीप्लेयर कक्षा में काम करने के लिए मिडी वॉल्यूम नियंत्रण प्राप्त करने की कोशिश कर रहा हूं, अब बहुत लंबे समय से। मैंने यहां स्टैक ओवरफ्लो और इंटरनेट पर इसे पूरा करने के लिए उदाहरणों की खोज की है, लेकिन कुछ भी मैं कोशिश नहीं करता हूं। वॉल्यूम वही रहता है! यह बदलता नहीं है जैसा मैं चाहता हूं।जावा मिडी वॉल्यूम नियंत्रण काम नहीं करेगा

मैं विंडोज 7.0 पर जावा 1.6.0_32 चला रहा हूं।

यहां!

import java.io.*; 
    import javax.sound.midi.*; 
    import java.net.URL; 

    public class MidiSSCCE { 
    public static void main(String[] args) 
    { 
     // creates the midi player and sets up its sequencer and synthesizer. 
     MidiPlayer midiP = new MidiPlayer();  
     double volume = 1.0; 

     // loads a midi from a url into the sequencer, but doesn't start playing it yet. 
     midiP.load("http://www.vgmusic.com/music/computer/microsoft/windows/touhou_6_stage3_boss.mid",true); 

     // set the midi to loop indefinitely. 
     midiP.loop(-1); 

     // start playing the midi. 
     midiP.play(true); 

     // while loop changes the volume of the midi while it is playing. 
     while(true) { 
      midiP.setVolume(volume); 
      try { Thread.sleep(300); } catch(Exception e) {} 
      volume -= 0.1; 
      if(volume < 0) volume += 1.0; 
     } 
    } 
    } 

    /** 
    * MidiPlayer 
    * author: Stephen Lindberg 
    * Last modified: Oct 14, 2011 
    * 
    * 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 { 
      // obtain the sequencer and synthesizer. 
      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 soundbank and receiver. 
      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: I just don't know what went wrong! 6_9"); 
     } 
    } 


    // 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, boolean isOnline) { 
     this.unload(); 
     try { 
      URL midiURL; 
      if(isOnline) midiURL = new URL(fileName); 
      else midiURL = getClass().getClassLoader().getResource(fileName); 

      seq = MidiSystem.getSequence(midiURL); 

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

      // load our sequence into the sequencer. 

      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: I just don't know what went wrong! 6_9"); 
     } 
    } 

    /** 
    * 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 


    /** 
    * 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) { 
     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(); 
     } 
    } 

    } 

मुझे कोई सफलता के साथ निम्नलिखित स्रोतों में उदाहरण की कोशिश की है:

http://www.java2s.com/Code/Java/Development-Class/SettingtheVolumeofPlayingMidiAudio.htm

How to controll the MIDI channel's volume

https://forums.oracle.com/forums/thread.jspa?messageID=5389030

MIDI Song with CC

एक SSCCE है

http://www.codezealot.org/archives/27

http://www.exampledepot.com/egs/javax.sound.midi/Volume.html

+0

यह अच्छा है। क्या आप "क्या काम नहीं करते" का वर्णन कर सकते हैं? (और शायद शीर्षक में सारांश डालें।) –

+0

मैं शीर्षक में "वॉल्यूम" रखना भूल गया। यह वॉल्यूम बदल रहा है जो मेरे लिए काम नहीं कर रहा है। ऐसा लगता है कि यह वास्तव में आपके लिए सही ढंग से काम कर रहा है? – Cazra

+0

क्या एमआईडीआई खेलना शुरू करने से पहले * वॉल्यूम बदलते हुए काम * किया जाता है? –

उत्तर

1
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)); 
      } 
     } 
     // Very important! 
     seqr.setSequence(seq); 
    } 
    catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 
+1

उसने कुछ बदल दिया ... लेकिन मात्रा नहीं। जब मैंने उस पंक्ति में जोड़ा, तो मिडी प्लेबैक के दौरान टेम्पो परिवर्तन अब प्रभावी नहीं होंगे .. – Cazra

3

मैं ध्वनि को नियंत्रित करने पर ये बहुत मुद्दों के साथ संघर्ष कर रहा हूँ और मैं मात्रा कि काम करता है बदलने के लिए एक कोड मिल गया है। अनजाने में मैं इसे समझने में असमर्थ था, लेकिन यहां आपके कोड में कुछ ऐसा है जो मैंने देखा है उससे अलग है। शायद यह आपकी मदद कर सकता है।

seqr = MidiSystem.getSequencer(false); 

शायद यह आप में मदद करता है के लिए लाइन

seqr = MidiSystem.getSequencer(); 

बदलने की कोशिश करें, मुझे विश्वास है कि "गलत" अनुक्रमक का उपयोग कर रिसीवर को सिंथेसाइज़र के लिए नहीं कनेक्ट करेगा, और, फिर जब आप रिसीवर को संदेश भेजने के लिए संदेश भेजें, यह काम करेगा।

संबंधित मुद्दे