soundwiedergabe mit schleife

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • soundwiedergabe mit schleife

    hiho

    Ich hab folgendes Problem:
    Ich möchte einen Sound (MIDI Format) in einer schleife wiedergeben.
    Das Programm soll also, sobald der Sound das erste Mal abgespielt wurde, diesen Vorgang so lange wiederhohlen, bis er vom Benutzer beendet wird.
    Nur kann ich bei einer MIDI Wiedergabe ja nicht jedes mal den Synthesizer neu starten, dass wird der ja x-mal hintereinander gestartet.

    Habt Ihr da ne Idee?

    mfg
    contest
    -- Ein Wettnewerb für Jugendliche Programmierer --
    Jeder Helfer ist willkommen ;)
  • ok hier der Code:

    Der Teil zum erstellen von Sequencer und co.

    Quellcode

    1. /**
    2. * Erstelle erforderliche Geräte, um MIDI-Files abzuspielen.
    3. */
    4. private void createSoundTools() throws Exception{
    5. //Sequencer und Synthesizer initialisieren
    6. sequencer = MidiSystem.getSequencer();
    7. Transmitter trans = sequencer.getTransmitter();
    8. synth = MidiSystem.getSynthesizer();
    9. Receiver rcvr = synth.getReceiver();
    10. //Beide öffnen und verbinden
    11. sequencer.open();
    12. synth.open();
    13. trans.setReceiver(rcvr);
    14. }
    15. /**
    16. * Spiele eine MIDI-Datei ab.
    17. * @param
    18. * name - Pfad der Datei
    19. */
    20. private void playMidiFile(String name) throws Exception{
    21. //Sequence lesen und abspielen
    22. Sequence seq = MidiSystem.getSequence(new File(name));
    23. sequencer.setSequence(seq);
    24. sequencer.setTempoInBPM(133);
    25. sequencer.start();
    26. }
    Alles anzeigen


    und der teil wo ich die Methode aufrufe:

    Quellcode

    1. menuItem = new JMenuItem("Musik an/aus");
    2. menuItem.addActionListener(new ActionListener(){
    3. public void actionPerformed(ActionEvent ev){
    4. if(sequencer.isRunning()){
    5. sequencer.stop();
    6. sequencer.close();
    7. synth.close();
    8. } else{
    9. try{
    10. playMidiFile("PingPong/midi/Mortal_Kombat.mid");
    11. }
    12. catch(Exception e){
    13. System.err.println(e.toString());
    14. }
    15. }
    16. }
    17. });
    18. music.add(menuItem);
    Alles anzeigen


    ich hoffe das reicht erst mal.

    mfg
    contest
    -- Ein Wettnewerb für Jugendliche Programmierer --
    Jeder Helfer ist willkommen ;)
  • Du kannst dem Synthesizer einen ControllerEventListener oder einen MetaEventListener hinzufügen. Ich weiß nicht welcher der Richtige ist, aber du kannst ja mal beide implementieren und dir die Events ausgeben lassen, die du bekommst. Vielleicht ist ja ein Event dabei, das ausgelöst wird, wenn das MIDI zu ende ist. Dann kannst du es dort neu starten.

    sequencer.stop(); und close() rufst du wie bisher nur dann auf, wenn du die Ausgabe stoppen willst.
  • Hi

    Also ich hab jetzt mal gegooglet, und nix gefunden, wie man solche Listener implementiert.
    Ich hab das jetzt mal mit ner Schleife versucht, aber die stoppt immer den restlichen Programmfluss.

    Kannst du da vllt mal ein bisschen Code postem?

    Hier ist die Schleife:

    Quellcode

    1. menuItem = new JMenuItem("Musik an/aus");
    2. menuItem.addActionListener(new ActionListener(){
    3. public void actionPerformed(ActionEvent ev){
    4. if(sequencer.isRunning()){
    5. soundOn = false;
    6. sequencer.stop();
    7. sequencer.close();
    8. synth.close();
    9. } else{
    10. soundOn = true;
    11. while(soundOn){
    12. if(sequencer.isRunning()){
    13. }
    14. else{
    15. try{
    16. playMidiFile("PingPong/midi/Mortal_Kombat.mid");
    17. }
    18. catch(Exception e){
    19. System.err.println(e.toString());
    20. }
    21. }
    22. }
    23. }
    24. }
    25. });
    26. music.add(menuItem);
    Alles anzeigen


    mfg
    contest
    -- Ein Wettnewerb für Jugendliche Programmierer --
    Jeder Helfer ist willkommen ;)
  • Hi,
    wenn du sequencer.isRunning() nutzen willst, dann musst du die while Schleife in einem Thread starten
    Siehe dazu: openbook.galileocomputing.de/javainsel8/javainsel_11_001.htm

    Allerdings bin ich sicher, dass dein Ziel besser als durch eine Endlosschleife realisiert werden kann.
    Hast du das Tutorial von Sun schon durch? java.sun.com/docs/books/tutorial/sound/playing.html
    Dort wird das monitoren einer Line beschrieben - in die Unterschieden zwischen Lines und Sequencers habe ich mich jedoch nicht eingelesen.
  • Listener:
    Du verwendest doch schon Listener (einen ActionListener dem du einem JMenuItem hinzufügst). Was ist dann das Problem einen Listener zum Synthesizer hinzuzufügen. In einer ersten Variante würde ich mir erst einmal mit System.out.println() ausgeben lassen, was du dort überhaupt an Informationen bekommst. Vielleicht bekommst du dort gar nichts, was du gebrauchen kannst. Aber einen Versuch ist es meiner Meinung nach wert.
  • Den Teil mal nachgebaut und die Listener getestet. Leider sind sie wohl nicht zu gebrauchen. Allerdings habe ich etwas anderes gefunden. An der Sequence gibt es die Methode getMicrosecondLength(). Da du also die Länge kennst, kannst du dir einen Thread programmieren, der nach Ablauf der Zeitspanne, die Sequence dem Sequencer neu übergibt. Natürlich sollte auch dieser Thread terminieren, wenn du den Sequencer angehalten hast.
  • Der MetaEventListener kann anscheinend nur nur ein paar Infos zu den entsprechenden Midi abfangen.

    Der ControllerEventListener kann auf eine ganze Reihe von Dingen reagieren (irgendwelches Musik-Zeug).
    java.sun.com/javase/6/docs/api…erEventListener,%20int[])
    Die zugehörigen Nummern, die man da übergeben muss findet man in der MIDI-Spezifikation.
    somascape.org/midi/tech/spec.html
    Leider gibte es keine passende Nummer (oder ich habe sie zumindest nicht gefunden) für das, was du willst.

    Threads sind einfacher als man denkt:
    boscheri.ch/computer/java/javainsel5/javainsel09_000.htm
  • Kann mir mal jemand ne kleine Stsrthilfe geben?
    Ich hab jetzt den Anfang von dem Galileo Computing durch. Ich hab auch schon die Soundwiedergabe in nen Thread gepackt, und kann den starten.
    Aber wie soll ich das machen, dass der Thread jetzt warten, und dann die Sequence wieder neu übergibt. Ohne dass dabei das restliche Programm stoppt. IM Moment ist das nämlich noch der Fall.

    Quellcode

    1. menuItem = new JMenuItem("Musik an/aus");
    2. menuItem.addActionListener(new ActionListener(){
    3. public void actionPerformed(ActionEvent ev){
    4. if(t1 == null){
    5. t1 = new Thread(sound);
    6. t1.setDaemon(true);
    7. t1.start();
    8. try{
    9. t1.sleep(5000);
    10. sound.playMidiFile("PingPong/midi/No_Limits.mid", 133);
    11. }
    12. catch(Exception e){
    13. System.err.println(e.toString());
    14. }
    15. }
    16. else{
    17. sound.deleteSoundTools();
    18. t1.interrupt();
    19. }
    20. }
    21. });
    22. music.add(menuItem);
    Alles anzeigen


    mfg
    contest
    -- Ein Wettnewerb für Jugendliche Programmierer --
    Jeder Helfer ist willkommen ;)
  • Da ich heute gut gelaunt bin hab ich dir mal ein lauffähiges Beispiel programmiert:

    Quellcode

    1. package test;
    2. import java.io.File;
    3. import java.io.IOException;
    4. import java.util.Date;
    5. import javax.sound.midi.InvalidMidiDataException;
    6. import javax.sound.midi.MidiSystem;
    7. import javax.sound.midi.MidiUnavailableException;
    8. import javax.sound.midi.Receiver;
    9. import javax.sound.midi.Sequence;
    10. import javax.sound.midi.Sequencer;
    11. import javax.sound.midi.Synthesizer;
    12. import javax.sound.midi.Transmitter;
    13. public class Test
    14. {
    15. private Sequencer sequencer = null;
    16. private Synthesizer synthesizer = null;
    17. Thread thread = null;
    18. public Test()
    19. {
    20. }
    21. public Sequencer getSequencer()
    22. {
    23. if (sequencer == null)
    24. {
    25. try
    26. {
    27. sequencer = MidiSystem.getSequencer();
    28. sequencer.setTempoInBPM(133);
    29. }
    30. catch (MidiUnavailableException e)
    31. {
    32. throw new RuntimeException(e);
    33. }
    34. }
    35. return sequencer;
    36. }
    37. public Synthesizer getSynthesizer()
    38. {
    39. if (synthesizer == null)
    40. {
    41. try
    42. {
    43. synthesizer = MidiSystem.getSynthesizer();
    44. Transmitter transmitter = getSequencer().getTransmitter();
    45. Receiver receiver = synthesizer.getReceiver();
    46. transmitter.setReceiver(receiver);
    47. }
    48. catch (MidiUnavailableException e)
    49. {
    50. throw new RuntimeException(e);
    51. }
    52. }
    53. return synthesizer;
    54. }
    55. public void start()
    56. {
    57. thread = new Thread(new SoundRunnable());
    58. thread.start();
    59. }
    60. public void stop()
    61. {
    62. thread.interrupt();
    63. }
    64. public class SoundRunnable implements Runnable
    65. {
    66. public void run()
    67. {
    68. try
    69. {
    70. Sequence seq = MidiSystem.getSequence(new File("test.mid"));
    71. while (true)
    72. {
    73. getSequencer().open();
    74. getSynthesizer().open();
    75. getSequencer().setSequence(seq);
    76. getSequencer().start();
    77. Thread.sleep((seq.getMicrosecondLength()/1000) + 10);
    78. getSequencer().stop();
    79. getSequencer().close();
    80. getSynthesizer().close();
    81. }
    82. }
    83. catch (InvalidMidiDataException e)
    84. {
    85. throw new RuntimeException(e);
    86. }
    87. catch (IOException e)
    88. {
    89. throw new RuntimeException(e);
    90. }
    91. catch (MidiUnavailableException e)
    92. {
    93. throw new RuntimeException(e);
    94. }
    95. catch (InterruptedException e)
    96. {
    97. }
    98. finally
    99. {
    100. getSequencer().stop();
    101. getSequencer().close();
    102. getSynthesizer().close();
    103. System.out.println("Thread stoped: " + new Date().getTime());
    104. }
    105. }
    106. }
    107. public static void main(String[] args) throws Exception
    108. {
    109. Test test = new Test();
    110. System.out.println("Application start: " + new Date().getTime());
    111. Thread.sleep(1000);
    112. System.out.println("Start: " + new Date().getTime());
    113. test.start();
    114. Thread.sleep(300000); // 5 minutes
    115. System.out.println("Stop: " + new Date().getTime());
    116. test.stop();
    117. Thread.sleep(1000);
    118. System.out.println("Application end: " + new Date().getTime());
    119. }
    120. }
    Alles anzeigen