Java Многопоточный сбой звука - PullRequest
2 голосов
/ 04 февраля 2012

Я работаю над игровым проектом на Java, в котором мне нужно иметь возможность воспроизводить несколько звуков одновременно в режиме реального времени.Я реализовал звуковую систему, которая генерирует новые потоки для воспроизведения звуков SourceDataLine.

Игра отлично работает на моем компьютере, но для одного из моих тестеров звуковая система постоянно падает на него через случайные промежутки времени.Мы оба работаем с одной и той же версией java (jre 1.6.0_29) в Windows 7, и после нескольких раундов тестирования и поиска в Google я так и не смог понять, почему она всегда работает нормально для меня, но вылетаетна него.

Вот SSCCE, демонстрирующий ту часть моего кода, где возникает моя проблема.Важными битами являются классы SoundPlayer, Sound и SoundThread.Вам нужно будет включить два звуковых файла с именами shortSound.wav и longSound.wav в тот же каталог, в котором вы сохраните SSCCE.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.sound.sampled.*;
import java.util.HashMap;
import java.util.Collection;
import java.io.*;
import java.net.URL;
import java.util.LinkedList;

public class SoundSSCCE extends JFrame
{

    private JPanel screenP;
    private JPanel bgFraming;

    /**
    *   Constructor
    *   Preconditions: None.
    *   Postconditions: The window for the SSCCE is created.
    **/

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

        // instantiate main window panel

        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)
    {
        SoundSSCCE gui = new SoundSSCCE();      
    }
}




/**
*   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 SoundPlayer object is used by the example to play the sounds.

    public SoundPlayer soundPlayer;

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

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

        soundPlayer = new SoundPlayer();

        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 and the number of sounds currently playing.
    **/

    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);
            g2D.drawString("Sounds playing: " + soundPlayer.soundsPlaying(), 20,50);
            g.dispose();
    }

    /**
    *   runSSCCEELogic()
    *   This is where the run-time logic for the SSCCE example is. 
    *   All it will do is play sounds at regular narrowly-spaced intervals.
    *   The sounds are stored in the same directory as the SSCCE. Substitute any .wav
    *   file here in place of shortSound.wav and longerSound.wav.
    **/

    public void runSSCCELogic()
    {
        if(logicLoops % 4 == 0)
        {
            soundPlayer.play("shortSound.wav");
        }
        if(logicLoops% 40 == 0)
        {
            soundPlayer.play("longerSound.wav");
        }
        logicLoops++;
    }


}



/**
*   My game uses makes method calls to the SoundPlayer object whenever it
*   needs to play any sounds. This separates the main game code from the lower-level 
*   mucking-about with Sound object code. It also makes it easier for me to make changes to 
*   my Sound class without having to make changes any lines in my game where I play sounds.
**/


class SoundPlayer
{
    private HashMap<String,Sound> sounds;
    private double volume;
    private int soundsPlaying;

    public SoundPlayer()
    {
        sounds = new HashMap<String,Sound>();
        volume = 1.0;
        soundsPlaying = 0;
    }


    /**
    *   playSound(String path)
    *   creates and plays a Sound specified by path.
    *   Preconditions: path is the file path for the sound.
    *   Postconditions: The sound is loaded and begins playing. 
    *       This method returns a reference to that sound.
    **/

    public Sound play(String path)
    {       
        Sound newSound;

        if(volume == 0)
            return null;

        if(sounds.containsKey(path))
        {
            newSound = sounds.get(path);
        }
        else
        {
            newSound = new Sound(path);
            sounds.put(path,newSound);
        }

        newSound.play(volume);

        return newSound;
    }

    /**
    *   load(String path)
    *   preloads a sound to be play instances of at a later time
    *   Preconditions: path is the file path for the sound.
    *   Postconditions: The sound is loaded. This method returns 
    *       a reference to that sound.
    **/

    public Sound load(String path)
    {
        Sound newSound;

        if(sounds.containsKey(path))
        {
            newSound = sounds.get(path);
        }
        else
        {
            newSound = new Sound(path);
            sounds.put(path,newSound);
        }
        return newSound;
    }

    public int soundsPlaying()
    {
        int count = 0;

        Collection<Sound> soundsIterable = sounds.values();
        for(Sound sound : soundsIterable)
        {
            count += sound.instances;
        }
        return count;
    }

    public int soundsLoaded()
    {
        return sounds.size();
    }


    public void setVolume(double vol)
    {
        this.volume = vol;
    }

}


/**
*   Sound objects store the path to a given sound file and spawn new threads
*   to play instances of their sound when the SoundPlayer tells them to play.
**/

class Sound
{
    public String path;
    protected int instances;
    protected URL soundURL;

    public Sound(String name)
    {
        try
        {
            soundURL =  getClass().getClassLoader().getResource(name);
            instances = 0;
            path = name;
        }
        catch(Exception ex)
        {
            System.out.println("An error occured while loading the sound file: " + name);
            System.out.println(ex.getMessage());
            ex.printStackTrace();
        }
    }

    /**
    *   play(double volume)
    *   Preconditions: volume is between 0.0 and 1.0 inclusive, where 1.0 is 
    *       at full volume and 0.0 is silent.
    *   Postconditions: The Sound spawns a new thread to play an instance
    *       of itself.
    **/

    public void play(double volume)
    {
        try
        {
            SoundThread clip = new SoundThread(this);
            synchronized(this)
            {
                // increment the count of its instances. The SoundThread
                //  will automatically decrement the sound instance when it finishes. 

                instances++;
            }
            clip.setVolume(volume);
            clip.start();

        }
        catch(Exception e)
        {
            System.out.println("Sound error: Error playing sound");
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }
}


/**
*   SoundThread is a thread that Sound objects spawn to play instances 
*   of their sounds. This supports multiple sounds being played simultaneously. 
**/

class SoundThread extends Thread
{
    public SourceDataLine clip;
    public AudioInputStream stream;
    private int bufferSize = 50;
    private Sound parent;

    public SoundThread(Sound parentSound)
    {
        try
        {
            parent = parentSound;

            // obtains input stream from AudioSystem to read from the file.

            stream = AudioSystem.getAudioInputStream(parentSound.soundURL); 
            AudioFormat format = stream.getFormat();

            // obtains the sound file's line

            DataLine.Info info = new DataLine.Info(SourceDataLine.class, format); 

            // loads the line into the clip

            clip = (SourceDataLine) AudioSystem.getLine(info); 

            // opens the clip onto the stream

            clip.open(format); 
            System.out.println("Sound buffer size: " + clip.getBufferSize());
        }
        catch(Exception e)
        {
            System.out.println("error playing sound");
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }


    public void run()
    {
        try
        {
            // I start my sourceDataLine and begin reading data 
            // from the stream into its buffer.

            clip.start();
            int bytesRead = 0;
            byte[] soundData = new byte[bufferSize];

            // read data from the stream into the sourceDataLine until there
            // is no more data to read

            while(bytesRead != -1)
            {
                bytesRead = stream.read(soundData,0,bufferSize);
                if(bytesRead >= 0)
                {
                    clip.write(soundData, 0, bytesRead);
                }
                else
                {
                    // Here I drain and close the line and its stream when
                    //  the sound is finished playing (it has read all the bytes from its stream).
                    // My tester's log suggests that SourceDataLine.drain() is where it
                    // is crashing.

                    clip.drain();
                    clip.close();
                    stream.close();
                }
            }

            // decrement the count of the Sound's instances.

            synchronized(parent)
            {
                parent.instances--;
            }
        }
        catch(Exception e)
        {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }



    public void setVolume(double vol)
    {
        try
        {
            FloatControl volCtrl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
            if(vol > 1.0)
                vol = 1.0;
            if(vol < 0.0)
                vol = 0.0;

            // tricky, confusing sound math stuff.

            float dB = (float) (Math.log(vol) / Math.log(10.0) * 20.0);
            if(dB > volCtrl.getMaximum())
                dB = volCtrl.getMaximum();
            if(dB < volCtrl.getMinimum())
                dB = volCtrl.getMinimum();
            volCtrl.setValue(dB);
        }
        catch(Exception e)
        {
            System.out.println("set volume failed");
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }
}

Вот файл журнала, сгенерированный jre моего тестера, когда игра вылетает.

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000000000000, pid=5212, tid=5524
#
# JRE version: 6.0_29-b11
# Java VM: Java HotSpot(TM) 64-Bit Server VM (20.4-b02 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C  0x0000000000000000
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

---------------  T H R E A D  ---------------

Current thread (0x00000000097c4000):  JavaThread "Thread-651" [_thread_in_native, id=5524, stack(0x000000000ecf0000,0x000000000edf0000)]

siginfo: ExceptionCode=0xc0000005, ExceptionInformation=0x0000000000000008 0x0000000000000000

Registers:
RAX=0x0000000000000000, RBX=0x00000000148ef5b0, RCX=0x00000000097c41d0, RDX=0x0000000000000002
RSP=0x000000000edef4f8, RBP=0x000000000edef6e0, RSI=0x00000000097c41d0, RDI=0x00000000097c41d0
R8 =0x000000000edef520, R9 =0x0000000000000000, R10=0x2b11000000000000, R11=0x0000000006146b00
R12=0x00000000148a1f00, R13=0x0000000000000000, R14=0x000000000edef710, R15=0x00000000097c4000
RIP=0x0000000000000000, EFLAGS=0x0000000000010246

Top of Stack: (sp=0x000000000edef4f8)
0x000000000edef4f8:   000000006d515842 000000000edef5a0
0x000000000edef508:   0000000000000000 000000000bfbbd18
0x000000000edef518:   000000006d525264 00000000148ef5b0
0x000000000edef528:   0000000006146b00 000000001491ddb0
0x000000000edef538:   2b11000000001f44 00000000096b0108
0x000000000edef548:   0000000000000000 000000006d90a5cb
0x000000000edef558:   000000006d511ed4 00000000097c41d0
0x000000000edef568:   000000006d511ed4 00000000148ef5b0
0x000000000edef578:   000000006d516055 0000000000000000
0x000000000edef588:   0000000000000000 0000000000000000
0x000000000edef598:   0000000000000000 00000000148ef5b0
0x000000000edef5a8:   0000000006146b00 000000001491ed56
0x000000000edef5b8:   2b11000000000000 00000000096b0108
0x000000000edef5c8:   0000000000000000 000000006d90a5cb
0x000000000edef5d8:   000000006d52b54b 00000000000005c8
0x000000000edef5e8:   00000000bc162e50 0000000000000000 

Instructions: (pc=0x0000000000000000)
0xffffffffffffffe0:   


Register to memory mapping:

RAX=0x0000000000000000 is an unknown value
RBX=0x00000000148ef5b0 is an unknown value
RCX=0x00000000097c41d0 is an unknown value
RDX=0x0000000000000002 is an unknown value
RSP=0x000000000edef4f8 is pointing into the stack for thread: 0x00000000097c4000
RBP=0x000000000edef6e0 is pointing into the stack for thread: 0x00000000097c4000
RSI=0x00000000097c41d0 is an unknown value
RDI=0x00000000097c41d0 is an unknown value
R8 =0x000000000edef520 is pointing into the stack for thread: 0x00000000097c4000
R9 =0x0000000000000000 is an unknown value
R10=0x2b11000000000000 is an unknown value
R11=0x0000000006146b00 is a global jni handle
R12=0x00000000148a1f00 is an unknown value
R13=0x0000000000000000 is an unknown value
R14=0x000000000edef710 is pointing into the stack for thread: 0x00000000097c4000
R15=0x00000000097c4000 is a thread


Stack: [0x000000000ecf0000,0x000000000edf0000],  sp=0x000000000edef4f8,  free space=1021k
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  com.sun.media.sound.MixerSourceLine.nDrain(J)V+0
j  com.sun.media.sound.MixerSourceLine.drain()V+26
J  gameEngine.SoundThread.run()V
v  ~StubRoutines::call_stub

---------------  P R O C E S S  ---------------

Java Threads: ( => current thread )
  0x0000000009959000 JavaThread "Thread-1843" [_thread_in_native, id=4748, stack(0x0000000015780000,0x0000000015880000)]
  0x000000000995c000 JavaThread "Thread-1842" [_thread_in_native, id=10632, stack(0x00000000146b0000,0x00000000147b0000)]
  0x0000000009959800 JavaThread "Thread-1841" [_thread_in_native, id=4240, stack(0x0000000015a80000,0x0000000015b80000)]
  0x0000000009958800 JavaThread "Thread-1828" [_thread_blocked, id=632, stack(0x00000000145b0000,0x00000000146b0000)]
  0x000000000995c800 JavaThread "Thread-1754" [_thread_in_native, id=11188, stack(0x0000000015980000,0x0000000015a80000)]
  0x0000000009957800 JavaThread "Thread-1699" [_thread_in_native, id=8788, stack(0x00000000144b0000,0x00000000145b0000)]
  0x000000000995a800 JavaThread "Thread-1650" [_thread_in_native, id=10860, stack(0x000000000fe20000,0x000000000ff20000)]
  0x00000000097bc000 JavaThread "Java Sound Sequencer" [_thread_blocked, id=11096, stack(0x0000000006cc0000,0x0000000006dc0000)]
  0x0000000009957000 JavaThread "Thread-1285" [_thread_in_native, id=10608, stack(0x00000000142b0000,0x00000000143b0000)]
  0x00000000097c3800 JavaThread "Thread-1223" [_thread_in_native, id=6968, stack(0x000000000eff0000,0x000000000f0f0000)]
  0x00000000097c9000 JavaThread "Thread-1157" [_thread_in_vm, id=9260, stack(0x00000000143b0000,0x00000000144b0000)]
  0x00000000097c0800 JavaThread "Thread-1139" [_thread_in_native, id=10544, stack(0x00000000141b0000,0x00000000142b0000)]
  0x00000000097ca800 JavaThread "Thread-1138" [_thread_in_native, id=8456, stack(0x00000000140b0000,0x00000000141b0000)]
  0x00000000097c6800 JavaThread "Thread-1113" [_thread_in_native, id=10536, stack(0x000000000fa20000,0x000000000fb20000)]
  0x00000000097c8800 JavaThread "Thread-1110" [_thread_in_native, id=7780, stack(0x000000000edf0000,0x000000000eef0000)]
  0x00000000097c5800 JavaThread "Thread-1054" [_thread_in_native, id=10472, stack(0x000000000eef0000,0x000000000eff0000)]
  0x00000000097c1800 JavaThread "Thread-1046" [_thread_in_native, id=6148, stack(0x0000000013fb0000,0x00000000140b0000)]
  0x00000000097c0000 JavaThread "Thread-1030" [_thread_in_native, id=10720, stack(0x000000000e3a0000,0x000000000e4a0000)]
  0x00000000097c8000 JavaThread "Thread-963" [_thread_in_native, id=3148, stack(0x000000000ac50000,0x000000000ad50000)]
  0x00000000097c2000 JavaThread "Thread-923" [_thread_in_native, id=10492, stack(0x000000000fd20000,0x000000000fe20000)]
  0x00000000097c7000 JavaThread "Thread-791" [_thread_in_native, id=2044, stack(0x000000000e5a0000,0x000000000e6a0000)]
  0x00000000097c2800 JavaThread "Thread-751" [_thread_in_native, id=2780, stack(0x000000000e4a0000,0x000000000e5a0000)]
=>0x00000000097c4000 JavaThread "Thread-651" [_thread_in_native, id=5524, stack(0x000000000ecf0000,0x000000000edf0000)]
  0x00000000097bf000 JavaThread "DestroyJavaVM" [_thread_blocked, id=10636, stack(0x0000000002370000,0x0000000002470000)]
  0x00000000097be800 JavaThread "D3D Screen Updater" daemon [_thread_blocked, id=10044, stack(0x000000000d940000,0x000000000da40000)]
  0x00000000097bd800 JavaThread "AWT-EventQueue-0" [_thread_blocked, id=3036, stack(0x000000000cc50000,0x000000000cd50000)]
  0x00000000097bd000 JavaThread "AWT-Shutdown" [_thread_blocked, id=10372, stack(0x000000000cb50000,0x000000000cc50000)]
  0x0000000009633800 JavaThread "TimerQueue" daemon [_thread_blocked, id=10840, stack(0x000000000b650000,0x000000000b750000)]
  0x0000000009631000 JavaThread "Headspace mixer frame proc thread" daemon [_thread_blocked, id=10808, stack(0x000000000ae50000,0x000000000af50000)]
  0x00000000095f0800 JavaThread "Java Sound Event Dispatcher" daemon [_thread_blocked, id=8628, stack(0x000000000a950000,0x000000000aa50000)]
  0x00000000062c1000 JavaThread "Java Sound Event Dispatcher" daemon [_thread_blocked, id=10864, stack(0x000000000a850000,0x000000000a950000)]
  0x000000000618c000 JavaThread "AWT-Windows" daemon [_thread_in_native, id=10984, stack(0x0000000006dc0000,0x0000000006ec0000)]
  0x0000000006189800 JavaThread "Java2D Disposer" daemon [_thread_blocked, id=1848, stack(0x0000000006bc0000,0x0000000006cc0000)]
  0x0000000006145000 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=7160, stack(0x00000000066f0000,0x00000000067f0000)]
  0x000000000052d800 JavaThread "C2 CompilerThread1" daemon [_thread_blocked, id=10604, stack(0x00000000065f0000,0x00000000066f0000)]
  0x0000000000526800 JavaThread "C2 CompilerThread0" daemon [_thread_blocked, id=2820, stack(0x00000000064f0000,0x00000000065f0000)]
  0x0000000000524800 JavaThread "Attach Listener" daemon [_thread_blocked, id=1616, stack(0x00000000063f0000,0x00000000064f0000)]
  0x0000000000523800 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=9476, stack(0x00000000062f0000,0x00000000063f0000)]
  0x000000000050f800 JavaThread "Finalizer" daemon [_thread_blocked, id=9472, stack(0x0000000005ff0000,0x00000000060f0000)]
  0x0000000000506800 JavaThread "Reference Handler" daemon [_thread_blocked, id=8864, stack(0x0000000005ef0000,0x0000000005ff0000)]

Other Threads:
  0x00000000004fe000 VMThread [stack: 0x0000000005df0000,0x0000000005ef0000] [id=3480]
  0x0000000006160800 WatcherThread [stack: 0x00000000067f0000,0x00000000068f0000] [id=6728]

VM state:not at safepoint (normal execution)

VM Mutex/Monitor currently owned by a thread: None

Heap
 PSYoungGen      total 10240K, used 4696K [0x00000000ead60000, 0x00000000eb980000, 0x0000000100000000)
  eden space 10112K, 45% used [0x00000000ead60000,0x00000000eb1de278,0x00000000eb740000)
  from space 128K, 75% used [0x00000000eb770000,0x00000000eb788000,0x00000000eb790000)
  to   space 1152K, 0% used [0x00000000eb860000,0x00000000eb860000,0x00000000eb980000)
 PSOldGen        total 43392K, used 23839K [0x00000000c0800000, 0x00000000c3260000, 0x00000000ead60000)
  object space 43392K, 54% used [0x00000000c0800000,0x00000000c1f47f00,0x00000000c3260000)
 PSPermGen       total 21248K, used 12322K [0x00000000bb600000, 0x00000000bcac0000, 0x00000000c0800000)
  object space 21248K, 57% used [0x00000000bb600000,0x00000000bc208830,0x00000000bcac0000)

Code Cache  [0x0000000002470000, 0x00000000026f0000, 0x0000000005470000)
 total_blobs=1022 nmethods=599 adapters=376 free_code_cache=47801344 largest_free_block=16000

Dynamic libraries:
0x0000000000400000 - 0x000000000042e000     C:\Windows\system32\java.exe
0x00000000774b0000 - 0x0000000077659000     C:\Windows\SYSTEM32\ntdll.dll
0x0000000077020000 - 0x000000007713f000     C:\Windows\system32\kernel32.dll
0x000007fefda00000 - 0x000007fefda6c000     C:\Windows\system32\KERNELBASE.dll
0x000007feff4e0000 - 0x000007feff5bb000     C:\Windows\system32\ADVAPI32.dll
0x000007feff6a0000 - 0x000007feff73f000     C:\Windows\system32\msvcrt.dll
0x000007fefe490000 - 0x000007fefe4af000     C:\Windows\SYSTEM32\sechost.dll
0x000007fefe4b0000 - 0x000007fefe5dd000     C:\Windows\system32\RPCRT4.dll
0x000000006d7f0000 - 0x000000006dfa8000     C:\Program Files\Java\jre6\bin\server\jvm.dll
0x0000000076dd0000 - 0x0000000076eca000     C:\Windows\system32\USER32.dll
0x000007feff740000 - 0x000007feff7a7000     C:\Windows\system32\GDI32.dll
0x000007fefde60000 - 0x000007fefde6e000     C:\Windows\system32\LPK.dll
0x000007fefdd10000 - 0x000007fefddd9000     C:\Windows\system32\USP10.dll
0x000007fefb970000 - 0x000007fefb9ab000     C:\Windows\system32\WINMM.dll
0x000007fefdce0000 - 0x000007fefdd0e000     C:\Windows\system32\IMM32.DLL
0x000007fefe5e0000 - 0x000007fefe6e9000     C:\Windows\system32\MSCTF.dll
0x000000006d760000 - 0x000000006d76e000     C:\Program Files\Java\jre6\bin\verify.dll
0x000000006d3b0000 - 0x000000006d3d7000     C:\Program Files\Java\jre6\bin\java.dll
0x000000006d7b0000 - 0x000000006d7c2000     C:\Program Files\Java\jre6\bin\zip.dll
0x000000006d000000 - 0x000000006d1c3000     C:\Program Files\Java\jre6\bin\awt.dll
0x000007fefb9b0000 - 0x000007fefba21000     C:\Windows\system32\WINSPOOL.DRV
0x000007fefdf80000 - 0x000007fefe183000     C:\Windows\system32\ole32.dll
0x000007fefe750000 - 0x000007feff4d8000     C:\Windows\system32\SHELL32.dll
0x000007fefdde0000 - 0x000007fefde51000     C:\Windows\system32\SHLWAPI.dll
0x000007fefc3b0000 - 0x000007fefc5a4000     C:\Windows\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_fa396087175ac9ac\COMCTL32.dll
0x000007fefbd70000 - 0x000007fefbd88000     C:\Windows\system32\DWMAPI.DLL
0x000007fefc1d0000 - 0x000007fefc226000     C:\Windows\system32\uxtheme.dll
0x000000006d2a0000 - 0x000000006d306000     C:\Program Files\Java\jre6\bin\fontmanager.dll
0x000007fefd840000 - 0x000007fefd84f000     C:\Windows\system32\CRYPTBASE.dll
0x000007feee310000 - 0x000007feee50f000     C:\Windows\system32\d3d9.dll
0x000007fefca70000 - 0x000007fefca7c000     C:\Windows\system32\VERSION.dll
0x000007fefbad0000 - 0x000007fefbad7000     C:\Windows\system32\d3d8thk.dll
0x000007feea170000 - 0x000007feeaabb000     C:\Windows\system32\nvd3dumx.dll
0x000007fefbb00000 - 0x000007fefbb2c000     C:\Windows\system32\powrprof.dll
0x000007fefe210000 - 0x000007fefe3e7000     C:\Windows\system32\SETUPAPI.dll
0x000007fefd9c0000 - 0x000007fefd9f6000     C:\Windows\system32\CFGMGR32.dll
0x000007feff5c0000 - 0x000007feff697000     C:\Windows\system32\OLEAUT32.dll
0x000007fefdcc0000 - 0x000007fefdcda000     C:\Windows\system32\DEVOBJ.dll
0x000000006d510000 - 0x000000006d53e000     C:\Program Files\Java\jre6\bin\jsound.dll
0x000007fefbd90000 - 0x000007fefbddb000     C:\Windows\system32\MMDevAPI.DLL
0x000007fefc230000 - 0x000007fefc35c000     C:\Windows\system32\PROPSYS.dll
0x000007fef3590000 - 0x000007fef35cb000     C:\Windows\system32\wdmaud.drv
0x0000000074b10000 - 0x0000000074b16000     C:\Windows\system32\ksuser.dll
0x000007fefbea0000 - 0x000007fefbea9000     C:\Windows\system32\AVRT.dll
0x000007fefb5c0000 - 0x000007fefb60f000     C:\Windows\system32\AUDIOSES.DLL
0x000007fef40f0000 - 0x000007fef40fa000     C:\Windows\system32\msacm32.drv
0x000007fef40d0000 - 0x000007fef40e8000     C:\Windows\system32\MSACM32.dll
0x000007fef3580000 - 0x000007fef3589000     C:\Windows\system32\midimap.dll
0x000007fefe3f0000 - 0x000007fefe489000     C:\Windows\system32\CLBCatQ.DLL
0x0000000010000000 - 0x0000000010065000     C:\Program Files\WIDCOMM\Bluetooth Software\btmmhook.dll
0x0000000077670000 - 0x0000000077677000     C:\Windows\system32\PSAPI.DLL
0x000000006d600000 - 0x000000006d617000     C:\Program Files\Java\jre6\bin\net.dll
0x000007fefdf30000 - 0x000007fefdf7d000     C:\Windows\system32\WS2_32.dll
0x000007feff7b0000 - 0x000007feff7b8000     C:\Windows\system32\NSI.dll
0x000007fefd140000 - 0x000007fefd195000     C:\Windows\system32\mswsock.dll
0x000007fefd130000 - 0x000007fefd137000     C:\Windows\System32\wship6.dll
0x000000006d620000 - 0x000000006d62b000     C:\Program Files\Java\jre6\bin\nio.dll
0x0000000009540000 - 0x0000000009571000     C:\Program Files\WIDCOMM\Bluetooth Software\btkeyind.dll

VM Arguments:
java_command: MyGameMain
Launcher Type: SUN_STANDARD

Environment Variables:
CLASSPATH=.;C:\Program Files (x86)\Java\jre6\lib\ext\QTJava.zip
PATH=C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\PC Connectivity Solution\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Broadcom\Broadcom 802.11\Driver;C:\Program Files\WIDCOMM\Bluetooth Software\;C:\Program Files\WIDCOMM\Bluetooth Software\syswow64;C:\Program Files\Java\jdk1.6.0_21\bin;C:\MinGW\bin;C:\Program Files (x86)\QuickTime\QTSystem\;C:\Windows\system32\wbem;C:\Program Files (x86)\IVT Corporation\BlueSoleil\Mobile;c:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\;c:\Program Files\Microsoft SQL Server\100\Tools\Binn\;c:\Program Files\Microsoft SQL Server\100\DTS\Binn\;C:\Program Files\Common Files\Microsoft Shared\Windows Live
USERNAME=***********
OS=Windows_NT
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 23 Stepping 6, GenuineIntel



---------------  S Y S T E M  ---------------

OS: Windows 7 , 64 bit Build 7601 Service Pack 1

CPU:total 2 (2 cores per cpu, 1 threads per core) family 6 model 23 stepping 6, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3, sse4.1

Memory: 4k page, physical 4160724k(2268648k free), swap 8319600k(5448724k free)

vm_info: Java HotSpot(TM) 64-Bit Server VM (20.4-b02) for windows-amd64 JRE (1.6.0_29-b11), built on Oct  3 2011 01:06:42 by "java_re" with MS VC++ 8.0 (VS2005)

time: Sat Feb 04 09:25:56 2012
elapsed time: 145 seconds

Файлы журнала предполагают, что сбой происходит во время звуковых потоков, когда заканчивается звук, и вызывает SourceDataLine.drain (), чтобы избавиться от любых оставшихся данных в буфере звука.Я не уверен, что я делаю неправильно, чтобы это вызвало сбой jre моего тестера в середине игры, хотя ...

Любое понимание от вас, гуру звука / многопоточности, было бы полезно.

Ответы [ 4 ]

2 голосов
/ 14 ноября 2012

Возможно, слишком поздно для какой-либо помощи для вас, но на случай, если кто-то еще заинтересован -

В SoundThread::run вы проверяете bytesRead, но если stream.read возвращает zero (и, возможно, этоне должен) тогда вы застряли в бесконечном цикле.

Это может зависеть от точной длины воспроизводимого звука и может объяснить, почему только один человек видит проблему.

0 голосов
/ 08 февраля 2012

Этого достаточно другого ответа, что я не собираюсь пересматривать предыдущее предложение о написании пользовательского Клипа (который является действительным, хотя и совсем другим подходом).

Кстати: я был смущен использованиемимени переменной «клип» для SourceDataLine.На самом деле следует рефакторинг такого рода вещи!

ОК.Глядя на свой код, вы пропускаете три шага, которые я включаю в приложение, где я воспроизводю перекрывающиеся SDL.

line.drain();
line.stop();
line.close();
line = null;

aiStream.close();
aiStream = null;

, где "line" - это SourceDataLine, а aiStream - это AudioInputStream.

Я думаю, что установка их в null может быть ключевым шагом.Не уверен, насколько важен пропущенный шаг stop ().И я не могу точно сказать, зачем это нужно, но это изменило мое приложение.

0 голосов
/ 06 мая 2012

Эта проблема осталась нерешенной. В заключение, проблема, вероятно, присуща машинам, на которых эта проблема возникает, и, вероятно, не стоит ее продолжать в родной Java.

0 голосов
/ 08 февраля 2012

Риск получить отрицательный ответ за то, что не ответил на ваш вопрос напрямую, я хотел бы сделать предложение. Можно создать пользовательский объект «Клип», который позволяет как многократное воспроизведение, так и воспроизведение на разных скоростях. Если ClipTrack (мое имя для него) имеет несколько курсоров, их выходные данные могут быть суммированы и отправлены в виде одного звукового значения.

Я демонстрирую использование таких здесь: ClipTrack

На этом сайте есть ссылки, указывающие на код Java, размещенные по адресу Java-Gaming.org , которые вы можете использовать. Но вы, вероятно, захотите отредактировать исходный код МНОГО. Я знаю, что я с тех пор первоначально отправляю это. Я всего лишь Java-программист среднего уровня и учу себя звуку. Есть много вещей, которые должны быть выполнены по-другому (объект «передает» данные в микшер, который я написал, а не воспроизводит его напрямую - но вы можете переписать это, также использование CopyOnWriteArrayList, вероятно, не оптимально, если полностью не -блокирующий метод управления курсорами может быть разработан).

Но, по крайней мере, основную идею можно увидеть там. :)

Потенциальные выгоды этого подхода включают в себя уменьшение количества потоков. Кроме того, вы никогда не будете иметь более одной копии необработанных аудиоданных в памяти одновременно (в отличие от создания нескольких копий во всех ваших клипах).

Работа с клипами javax.sound показалась мне очень раздражающей, и я счастлив, что больше с ними не связывался.

...