java


Java audio keeps crackling in custom-made Sound class


To keep it short and simple, I am using a custom Sound class for Java, but the way I am using it, it is for some reason, producing a lot of crackling noise for certain sounds. If uploading the audio might be helpful, please let me know.
This is the code of the Sound class that I am using:
package brad.classes;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;
import sun.audio.AudioData;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
import sun.audio.ContinuousAudioDataStream;
/*
* Custom class for playing audio (audio file must be in src)
*/
public class Sound {
private ContinuousAudioDataStream loop = null; //Puts music data into loop
private InputStream in = null; //Takes in music file as input
private AudioStream audioStreamMusic = null; //Takes in InputStream of music file as input
private AudioData audioData = null; //Changes AudioStream to data
private boolean loopable; //Whether the music input is meant to be looped or not
private String music; //The name of the music file
private double length; //The duration of the audio snippet in seconds
private static boolean isStopped = false;
/*
* Takes in music file name and whether or not the file is loopable
*/
public Sound(String music, boolean loopable) throws IOException, UnsupportedAudioFileException {
if(music.length() < 4 || !music.substring(music.length() - 4, music.length()).equals(".wav"))
throw new IOException(music + " (Given file must be .wav)");
else if(new File(music).length() > 1000000)
throw new IOException(music + " (Given file must not be over 1 megabyte)");
this.music = System.getProperty("user.dir") + "/" + music;
this.loopable = loopable;
in = new FileInputStream(music);
audioStreamMusic = new AudioStream(in);
if(loopable) {
audioData = audioStreamMusic.getData();
loop = new ContinuousAudioDataStream(audioData);
}
AudioInputStream stream = AudioSystem.getAudioInputStream(new File(music));
AudioFormat format = stream.getFormat();
long frames = stream.getFrameLength();
length = (double) frames/format.getFrameRate();
}
/*
* Also takes in whether the file size limit should be ignored
*/
public Sound(String music, boolean loopable, boolean override) throws IOException {
if(music.length() < 4 || !music.substring(music.length() - 4, music.length()).equals(".wav"))
throw new IOException(music + " (Given file must be .wav)");
if(!override) {
if(new File(music).length() > 1000000)
throw new IOException(music + " (Given file must not be over 1 megabyte)");
}
this.music = System.getProperty("user.dir") + "/" + music;
this.loopable = loopable;
in = new FileInputStream(music);
audioStreamMusic = new AudioStream(in);
if(loopable) {
audioData = audioStreamMusic.getData();
loop = new ContinuousAudioDataStream(audioData);
}
}
/*
* Plays audio file
*/
public void play() {
if(loopable)
AudioPlayer.player.start(loop);
else {
try {
in = new FileInputStream(music);
audioStreamMusic = new AudioStream(in);
AudioPlayer.player.start(audioStreamMusic);
}
catch(IOException error) {
System.out.println(error);
}
}
}
/*
* Stops audio file if playing
*/
public void stop() {
if(loopable)
AudioPlayer.player.stop(loop);
else
AudioPlayer.player.stop(audioStreamMusic);
}
/*
* Returns a string representation of the sound, including
* the given name of the audio file as well as whether or
* not it is loopable
*/
#Override
public String toString() {
return String.format("Sound[music = %s, loopable = %b]", music, loopable);
}
public boolean equals(Sound other) {
if(music.equals(other.music))
return true;
return false;
}
/*
* Returns value of music
*/
public String getMusic() {
return music;
}
/*
* Returns value of loopable
*/
public boolean getLoopable() {
return loopable;
}
/*
* Returns value of length
*/
public double getLength() {
return length;
}
/*
* Plays group of Sounds
*/
public static Thread playGroup(Sound[] sounds, boolean loopable) throws InterruptedException {
return playGroup(new ArrayList<Sound>(Arrays.asList(sounds)), loopable);
}
/*
* Plays group of Sounds
*/
public static Thread playGroup(ArrayList<Sound> sounds, boolean loopable) throws InterruptedException {
Runnable r = new Runnable() {
#Override
public void run() {
do {
int i = 0;
try {
sounds.get(0).play();
Thread.sleep((long) (sounds.get(0).getLength() * 1000));
for(i = 1; i < sounds.size(); ++i) {
sounds.get(i).play();
sounds.get(i - 1).stop();
Thread.sleep((long) (sounds.get(i).getLength() * 1000));
}
}
catch(Exception e) {
sounds.get(i).stop();
break;
}
} while(loopable && !isStopped);
}
};
Thread t = new Thread(r);
t.start();
return t;
}
public static void stopGroup(Thread t) {
while(t != null && !t.isInterrupted()) {
t.interrupt();
isStopped = true;
}
}
}
I removed a lot of the code. So, I hope this is somewhat concise enough to get the basic idea.
package defense;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontFormatException;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import javax.imageio.ImageIO;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import brad.classes.Sound;
public class Runner extends JPanel implements ActionListener, KeyListener {
private static final long serialVersionUID = 1L;
static char dir = 'u';
static int delay = 10;
static int angle = 0;
static int breakCount = 0;
static int breakFrame = 0;
static int count = 0;
static int gifCount = 0;
static int currentDirection = 0;
static int gameOverCount = 0;
static int gameOverFrame = 0;
static boolean isHard = true;
static boolean runsGif = false;
static boolean heartDone = false;
static boolean gameOverDone = false;
static boolean firstEnd = true;
static boolean secondEnd = true;
protected Timer timer;
BufferedImage gif;
BufferedImage heart;
BufferedImage heartBreak;
BufferedImage gameOver;
static Thread mainSound;
Attack a1 = new Attack(new LinkedList<Arrow>(), 2);
Player p = new Player();
public Runner(String s) {
JFrame frame = new JFrame(s);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Runner bp = new Runner();
frame.add(bp);
frame.addKeyListener(this);
frame.setSize(600, 600);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
frame.setSize(600, 600);
frame.setLocation(dim.width/2 - frame.getSize().width/2, dim.height/2 - frame.getSize().height/2);
frame.setResizable(false);
frame.setVisible(true);
}
public static void main(String args[]) throws IOException, UnsupportedAudioFileException, InterruptedException {
#SuppressWarnings("unused")
Runner a = new Runner("Game");
ArrayList<Sound> mainTheme = new ArrayList<Sound>();
int max;
String base;
if(isHard) {
max = 16;
base = "BATH";
}
else {
max = 12;
base = "SOJ";
}
for(int i = 1; i <= max; ++i) {
mainTheme.add(new Sound("audio/" + base + i + ".wav", false));
}
mainSound = Sound.playGroup(mainTheme, true);
}
public Runner() {
timer = new Timer(delay, this);
timer.start();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if(p.getHealth() != 0) {
drawBG(g);
drawSqu(g);
drawCircle(g);
drawHeart(g);
p.shield(g, dir);
gif(g);
try {
a1.spawnArrows(g, p);
p.drawHealth(g);
}
catch (FontFormatException | IOException e) {
e.printStackTrace();
}
}
else {
drawBG(g);
if(firstEnd) {
Sound.stopGroup(mainSound);
firstEnd = false;
}
if(!heartDone)
breakHeart(g);
else if(secondEnd){
secondEnd = false;
ArrayList<Sound> determination = new ArrayList<Sound>();
try {
for(int i = 1; i <= 6; ++i) {
determination.add(new Sound("audio/DT" + i + ".wav", false));
}
Sound.playGroup(determination, true);
}
catch(Exception e) {
e.printStackTrace();
}
}
else if(!gameOverDone){
gameOver(g);
}
}
}
public boolean breakHeartException(int breakFrame) {
int[] exceptions = {2, 6, 8, 12, 14, 18, 20, 22, 23};
for(int exception : exceptions) {
if(breakFrame == exception)
return true;
}
return false;
}
public void makeBreakHeart(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
int width = heartBreak.getWidth();
int height = heartBreak.getHeight();
g2d.drawImage(heartBreak, getWidth() / 2 - (width / 2) + 11, getHeight() / 2 - height / 2 + 78, null);
g2d.dispose();
}
public void breakHeart(Graphics g) {
++breakCount;
boolean exception = breakHeartException(breakFrame);
try {
heartBreak = ImageIO.read(new File("images/gif/heartBreak" + breakFrame + ".png"));
} catch (IOException e) {
e.printStackTrace();
}
if(breakCount % 4 == 0 && breakCount != 0 && !exception) {
++breakFrame;
if(breakFrame == 25) {
try {
Sound split = new Sound("audio/split.wav", false);
split.play();
} catch (IOException | UnsupportedAudioFileException e) {
e.printStackTrace();
}
}
if(breakFrame == 48)
heartDone = true;
breakCount = 0;
}
else if(exception) {
switch(breakFrame) {
case 2:
case 12:
if(breakCount % 24 == 0) {
++breakFrame;
breakCount = 0;
}
break;
case 14:
if(breakCount % 28 == 0) {
++breakFrame;
breakCount = 0;
}
break;
default:
if(breakCount % 8 == 0) {
++breakFrame;
if(breakFrame == 9) {
try {
Sound broke = new Sound("audio/heartBreak.wav", false);
broke.play();
} catch (IOException | UnsupportedAudioFileException e) {
e.printStackTrace();
}
}
breakCount = 0;
}
}
}
makeBreakHeart(g);
}
public void gameOver(Graphics g) {
++gameOverCount;
try {
gameOver = ImageIO.read(new File("images/gif/gameOver" + gameOverFrame + ".png"));
} catch (IOException e) {
e.printStackTrace();
}
if(gameOverCount % 4 == 0 && gameOverCount != 0) {
++gameOverFrame;
switch(gameOverFrame) {
case 68:
case 70:
case 73:
case 75:
case 76:
case 78:
case 80:
case 81:
case 85:
case 86:
case 88:
case 93:
case 95:
case 96:
case 98:
try {
Sound asgore = new Sound("audio/asgore.wav", false);
asgore.play();
}
catch(Exception e) {
e.printStackTrace();
}
break;
}
if(gameOverFrame == 225)
gameOverDone = true;
gameOverCount = 0;
}
Graphics2D g2d = (Graphics2D) g.create();
int width = gameOver.getWidth();
int height = gameOver.getHeight();
g2d.drawImage(gameOver, getWidth() / 2 - (width / 2) + 1, getHeight() / 2 - height / 2, null);
g2d.dispose();
}
#Override
public void actionPerformed(ActionEvent e) {
repaint();
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
dir = 'u';
break;
case KeyEvent.VK_DOWN:
dir = 'd';
break;
case KeyEvent.VK_RIGHT:
dir = 'r';
break;
case KeyEvent.VK_LEFT:
dir = 'l';
break;
}
}
#Override
public void keyReleased(KeyEvent e) {
}
}
Please let me know if any further details are needed. Thanks!
Update 1:
I just realized that I left out some fairly important information. The playGroup() sounds seem to work fine (or at least good enough) for my purposes. The main problem happens with playing small sound effects over those sounds at the same time.
So, the Sounds that are being put into an ArrayList and put into the playGroup() and stopGroup() methods seem to be working well enough. The main problems occur when I create an individual sound and play it over the main looping sound.

Related Links

Police Station finder application
Android Studio - if file exists in system folder then
how to edit the existing jar file in eclipse
How can I change numberPicker speed in Android java/xml
Hibernate - Select Child and then join with Parent returns Parent with other children as well
How to transfer control from service to post method in servlets?
JAVA - Cannot make a static reference to the non-static method [duplicate]
How do I read from JSON File in Java? [duplicate]
Populate foreign collection in Hibernate based on two columns
Eclipse paho for mqtt in Android throws error
With Guice, how to provide different instances of the same Type?
How do you complete a CompletableFuture when another set of CompletableFutures is complete?
Grid index Structure
Getting each column in a string in webservice and display it in textview in android
Throwing exceptions outside of a method - Java
Simplifying very long if statements

Categories

HOME
osgi
gremlin
deezer
fluentd
mockito
relative-path
hashmap
office365api
session
syntax
grep
rsyslog
analysis
serverspec
fancybox
swagger-ui
medical
gorm
fancybox-3
quicklook
modx-revolution
mapserver
resize
google-apps-marketplace
jplayer
spring-tool-suite
usergrid
windows-phone-7
orchardcms
fortumo
ibm-odm
netflix
workload-scheduler
dosgi
sms-gateway
crystal-reports-2008
nodatime
language-agnostic
java-7
bootstrap-duallistbox
phpfox
linkerd
strncpy
xacml
subdomains
bluestacks
pdb
io-redirection
main
abstract-class
uft-api
leading-zero
bootstrapper
awt
avro4s
gzipstream
vao
unixodbc
apache-fop
jedis
elgg
python-cryptography
minimization
gnome-shell-extensions
player
bluegiga
itextpdf
browser-link
natvis
unity-networking
ios8-today-widget
spim
citrus-pay
pundit
security-testing
kcachegrind
deis
event-bubbling
fpml
cctv
wordpress-theme-customize
android-radiobutton
dealloc
html5-notifications
industrial
lcs
tinn-r
chuck
funscript
chrono
ohm
spring-portlet-mvc
assembly-loading
actionview
visitor-statistic
mozilla-prism
filtered-index
photoshop-cs4
xetex
sustainable-pace
caching-application-block

Resources

Encrypt Message