I want to add audio to my java game, but I don't know how to put it in practice. By I've read, Java only plays wav files, but this files are too big.
I've read a little about JLayer, but I actually need something like soundpool in android, for handle all in game effects. Do you know how to do it? I've to build a class that does it?
Here is some code for you that I've used in a game a while back using JLayer:
public class MP3 {
public void play(final InputStream in) {
new Thread() {
#Override
public void run() {
try {
new Player(in).play();
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}.start();
}
}
private HashMap<String, URL> soundMap = new HashMap<String, URL>();
public void loadSounds() {
String[] filenames = {
"5_seconds_remaining.mp3",
"10_seconds_remaining.mp3",
"button_press_loud.mp3"
};
for (String s : filenames) {
soundMap.put(s.substring(0, s.indexOf('.')), getClass().getResource("sounds/" + s));
}
}
public void playSound(String name) {
try {
new MP3().play(new BufferedInputStream(soundMap.get(name).openStream()));
} catch (IOException ex) {}
}
I recommend TinySound. It supports ogg/vorbis files (a free compression format comparable to mp3, but does not require licensing as mp3 does).
http://www.java-gaming.org/topics/need-a-really-simple-library-for-playing-sounds-and-music-try-tinysound/25974/view.html
A link is provided there to the github source for this library.
It is also possible to use Java as a synthesizer (I've been dabbling with this) but I'm still working on making something 'practical' for use in a game.
Related
I would like to open file specified by its path in NetBeans editor (IOProvider.getDefault().getIO(...);).
I would like the same functionality as is when some Java/C/C++ or any other programming language prints an Exception. As far as I went for now:
Write the output in console (see the example at the end)
By using OutputListener resolve what should be printed as hypertext
OutputListener.outputLineAction that defines what to do when clicked on hypertext IOColorPrint.print(InputOutput io, CharSequence text, OutputListener listener, boolean important, Color color)
Open the file on the system when clicking on
An example of error message I need to resolve:
The export was successful. The exported file can be found in: C:\Users\MY_USER\Desktop\myFile.xml
The problem that I have is that I have to print all the output in one line and the OutputEvent gives me all the line. Is there any way to get only the Highlited text (The path) ?
This call open new console output tab:
IOProvider.getDefault().getIO(...)
You should take inputStream and use class while(x=is.read()!=n ....
IOProvider.getDefault().getIO(...).getInputStream
Let me know, if this was usefull.
Here the Listener :
public class HyperlinkToFileOutputListener implements OutputListener {
private final File file;
public HyperlinkToFileOutputListener(File file) {
this.file = file;
}
#Override
public void outputLineSelected(OutputEvent oe) {
}
#Override
public void outputLineAction(OutputEvent oe) {
try {
if (file.exists()) {
Desktop.getDesktop().open(file);
}
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
}
#Override
public void outputLineCleared(OutputEvent oe) {
}
}
here the call
IOColorPrint.print(io, file.getName(), new HyperlinkToFileOutputListener(file), true, Color.BLUE);
best regards
I wrote a short player with command line arguments for mp3 files. Now I would like to access the amplitude data but there seems to be no possibility to get the audio data directly from the AudioClip class in javafx. The solution with mp3si from javazoom seems not to be state of the art, as it is already 9 years old and java has changed considerably over this time.
//lots of imports should appear here.
//
public class PlayingSound extends Application{
protected List<String> files=null;
#Override
public void start(Stage stage) {
for(String soundfile : files) {
AudioClip sound =
new AudioClip(new File(soundfile).toURI().toString());
sound.play();
while( sound.isPlaying() ) try {
Thread.sleep(100);
} catch(InterruptedException ie) {
}
}
Platform.exit();
}
#Override
public void init(){
files = getParameters().getRaw();
}
public static void main(String[] args) {
Application.launch(args);
}}
I trying to make an app, with a lot of short sounds(more than 20), using Sound Pool.
But when i load that sounds, it take like 3-10 sec to load it.
How can i improve speed of loading?
Here is Function of loading
private int loadSound(String filename) {
AssetFileDescriptor assetFileDescriptor;
try {
assetFileDescriptor = assetManager.openFd(filename);
}
catch (IOException e){
e.printStackTrace();
return -1;
}
return soundPool.load(assetFileDescriptor,1);
}
Use .OGG files at the lowest sample rate you can tolerate, like 96kb/s. This will create the smallest files so they load faster. I had a lot of problems with loading/playing sounds using .WAV files, they all went away when I converted them to .OGG files.
Do your sound loading off the main UI thread. If you need to know when the sound is loaded, use an OnLoadCompleteListener:
mSoundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
Log.d(TAG, "soundpool onLoadComplete, sampleId = " + sampleId + ", status = " + status);
// ... sound is ready to play
}
});
// sound load should happen off the UI thread
new Thread() {
#Override
public void run() {
mSoundId = mSoundPool.load(getActivity(), R.raw.sound1, 1);
// ... load other sounds here
}
}.start();
I embedded the audio files so I could use raw resource ids. If you have to load from files, grab all your filenames and send them off to a load method inside a non-UI thread.
I've been doing some work in Android, and I've found after three or four different attempts, I can't seem to get Android to save my file anywhere. In fact, it doesn't even create a folder in data/ for my app.
Here's how I'm trying to save the file - this is in my main activity also.
#Override
public void onStop(){
super.onStop();
try{
FileOutputStream memboricOut = getApplicationContext().openFileOutput("memboric.core", Context.MODE_PRIVATE);
brain.save(memboricOut);
}catch(Exception e){
System.err.println("Could not save memboric core.");
e.printStackTrace();
}
}
And inside brain.save():
public boolean save(FileOutputStream fileOut) {
try{
ObjectOutputStream oo = new ObjectOutputStream(fileOut);
oo.writeObject(this);
oo.close();
fileOut.close();
System.out.println("Memboric Core saved successfully.");
return true;
}catch (Exception e) {
e.printStackTrace();
}
return false;
}
This code seems to do nothing. I've also placed the saving in onDestroy as well.
Have I just chosen bad placement for the saving? I can't imagine what could possibly being going wrong.
Do you have the permission to save files ?
You can add that by adding android.permission.WRITE_EXTERNAL_STORAGE permission to you AnroidManifest.xml.
oo.writeObject(this);
Is brain have serializable data?
Class Brain implements java.io.Serializable {
public String toString() {
return "serialized data";
}
}
If not, DataOutputStream maybe a better choice.
DataOutputStream oo = new DataOutputStream(fileOut);
oo.writeInt(value); // if breain have int value
oo.flush();
oo.close();
Saved data will be appear in /data/data/(your.package.name)/files/memboric.core
Check the file with emulator (or rooted device).
for some time I am trying to open file godatabase on android using ESRI api in version 10.2.
I have a file godatabase made with Arccatalog 10.1. It contains one layer. I can open it in Arcmap so everything looks fine here.
The geodatabase is in folder named android.gdb
I copied it to microSD card and tried to open it using this code:
new com.esri.core.gdb.Geodatabase("/mnt/sdcard2/android.gdb");
The "/mnt/sdcard2/android.gdb" file exists and is a folder and I have read and write permissions.
I get a RuntimeException with the message that the goedatabase file could not be opened.
Anyone had similiar issues with that ?
The ESRI runtime api for android wont be able to open that kind of database. It uses a proprietary version of a geodatabase built in SQLLite. You will need to publish a service in ArcGisOnline or ArcServer 10.2 and call the GeodatabaseSyncTask object in order to get a version of your database in the right format onto the device. On your published feature service you will need to make sure Sync is enabled. Then you can utilize this code to call your feature service and store it locally. This code is based on this ESRI sample -- https://developers.arcgis.com/android/sample-code/offline-editor/
public void LoadGdb(UserCredentials credentials, Polygon extent, SpatialReference spatRef){
mapExtent = extent;
mapSpatialRef = spatRef;
String replicaUrl = callingActivity.getResources().getString(R.string.feature_service_url);
gdbTask = new GeodatabaseSyncTask(replicaUrl, credentials);
gdbTask.fetchFeatureServiceInfo(new CallbackListener<FeatureServiceInfo>() {
#Override
public void onError(Throwable e) {
Log.e(TAG, "", e);
}
#Override
public void onCallback(FeatureServiceInfo objs) {
if (objs.isSyncEnabled()) {
requestGdbInOneMethod(gdbTask, mapExtent, mapSpatialRef);
}
}
});
}
protected void requestGdbInOneMethod(GeodatabaseSyncTask geodatabaseSyncTask, Polygon extent, SpatialReference spatRef) {
GenerateGeodatabaseParameters params = new GenerateGeodatabaseParameters({0, 1}, extent,
spatRef, true, SyncModel.LAYER, spatRef);
CallbackListener<String> gdbResponseCallback = new CallbackListener<String>() {
#Override
public void onCallback(String obj) {
try {
// This onCallback gets called after the generateGeodatabase
// function on the GeodatabaseSyncTask is called.
// You can store a reference to this database or you can load it
// with your code and point it to the gdbFileName location
Geodatabase myGeodatabase = (Geodatabase)obj;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
#Override
public void onError(Throwable e) {
Log.e(TAG, "", e);
}
};
GeodatabaseStatusCallback statusCallback = new GeodatabaseStatusCallback() {
#Override
public void statusUpdated(GeodatabaseStatusInfo status) {
showMessage(callingActivity, status.getStatus().toString());
}
};
// !! THE gdbFileName is a string of the path and filename
// where the geodatabse will be stored.
geodatabaseSyncTask.generateGeodatabase(params, gdbFileName, false, statusCallback, gdbResponseCallback);
}
To load a local file you need to use ArcGIS Desktop 10.2.1 or higher to generate a Runtime Geodatabase file with a *.geodatabase file extension. See the instructions here: http://resources.arcgis.com/en/help/main/10.2/index.html#//00660000045q000000