Load sound from memory in Android - java

Is there any way to load a sound samples from memory using SoundPool.load method?
Unfortunatelly, all methods provided in SoundPool are using arguments for real files.
The problem is that I want to load sounds from zip file on SDcard, and extracting zip (like in this solution) is not an option.
Furthermore, there is a solution for loading from uncomressed zip files, but my files is comressed (and will be with password).
So is there any way to have java.io.FileDescriptor that represents a virtual file, so I can implement some abstract class placing my own streams?
Best regards.

I got the final answer on this question.
This is feature-missing on Android platform. Android media playback framework doesn't support it for a very long time. Google also notices it, so Android6.0(API Level23) introduces android.media.MediaDataSource which could be used as a pure memory byte-array data source. Before API Level23, we still need to copy the memory data to a temporary file in the file system.
The following URL provide some more clues on this issue, its explanation is correct for both audio and video:
how to play video from byte array in media player

I wanted to suggest you to use MemoryFile, but after checking it, I found the MemoryFile has no getFileDescriptor() method, it means we couldn't use it as a parameter in SoundPool.load().
But I found this post:
what is the use of MemoryFile in android
One guy implemented MemoryFileUtil.getFileDescriptor(memFile), he posts his codes there.
If his codes really could work, it means we could load a sound sample from memory using SoundPool.load().
The only problem is writing our memory data into that memory file.
The following site shows how to write memory data(from SQLITE query result) into a memory file:
http://www.programcreek.com/java-api-examples/index.php?api=android.os.MemoryFile
I'll give you updates after my test.

Related

Are there an examples of how to use the java api io.humble to encode audio?

I was able to follow the examples of how to encode video with io.humble easily enough. But, the only example of including audio that I can find simply encodes audio at the beginning of the video. I can't figure out how to encode samples at arbitrary locations. Using setTimestamp doesn't do anything.
Here is the example I found:
https://www.javatips.net/api/myLib-master/myLib.AGPLv3/myLib.humble.test/src/test/java/com/ttProject/humble/test/BeepSoundTest.java
If I modify the beepSamples() method to increase the "sampleNum" value, I can create a longer tone. But calling the method multiple times or setting samples.setTimestamp() to other values or calling setTimestamp() on the packets, all do nothing.
No matter what I do, the audio always shows up at the beginning of the video.
Ultimately, I want to be able to load arbitrary mp3 files of various audioclips and then merge them into the audio stream of the video at specific timestamps. But I can't even get this example to encode at different points in the video stream.
The author of this tool unfortunately is not interested in maintaining it or providing examples. Luckily, I found JavaCV which is an alternative that turned out to be really easy to use.
So to anyone else having this problem, I recommend switching to JavaCV. Other options are also JCodec and Xuggler, but Xuggler is deprecated (same author as io.humble) and JCodec apparently is slow and produces much larger files.
If you need support with these kind of projects. I maintain a fork of Xuggler (https://github.com/olivierayache/xuggle-xuggler)..I can provide help on these topics.

Azure Functions and temporary File Storage

I'm a beginner and have never dealt with cloud-based solutions yet before, so apologies for the dumb question.
I have an Azure Blob Storage containing PDF files from which I want to extract data using PDFBox. Because PDFbox can't load blobs directly, I currently download these files locally first. However, eventually my project will need to become fully Cloud-based, preferably as an Azure Function.
The main hurdle therefore is figuring out how my Azure Function should access the files. When using the console inside my Azure Function I noticed it comes with a file storage. Can the Function download blobs and store them here before processing it? Does this file storage work the same as a local environment or are there differences to keep in mind?
I'm only looking to store files temporarily here, for only a few minutes at a time.
The main hurdle therefore is figuring out how my Azure Function should
access the files. When using the console inside my Azure Function I
noticed it comes with a file storage.
Yes, all of the information of your deployed azure function is stored in the file storage you set.(It is defined when you create the function app.)
Can the Function download blobs and store them here before processing
it? Does this file storage work the same as a local environment or are
there differences to keep in mind?
Yes, you can. And the root directory is D:/home/site/wwwroot. So if you don't specify, the file you create will be in this directory.
Remember to delete the files, because the storage space is limited. It is based on the plan you selected.
I'm only looking to store files temporarily here, for only a few
minutes at a time.
By the way, if you get a file from blob storage, at this time you have completely got its data. You can process the obtained data directly in the code without temporarily storing it in the current folder. (Of course, if you have special needs, please ignore this one.)
You can use a blob trigger or input binding to load a blob into memory of your function for processing by PDFBox.
With regards to the local file system, you can read about more about it here. From the description of your problem I think a blob trigger or input binding should be sufficient for you.

I need to play a sound for a text based game in the cmd

I need a function that I can call, that plays a sound. It needs to have a parameter where I can give it the name of the file I'm trying to play. I've tried searching on the internet, but it's all mostly based around the sun library. And that gives me a warning. Thanks in advance.
You can use Java media framework to play media. As for the method :)
that you have to customize as per your need.
Or if you just want beep sounds, you can use bell character or create beep using awt toolkit
//Bell character
System.out.println("\007");
//Toolkit
java.awt.Toolkit.getDefaultToolkit().beep();
The Java Tutorials, for some reason, doesn't have a simple example of playing a sound in the fire-and-forget manner that you are asking about. But there are other tutorials online that do so.
The search term that will be of most help is "Clip" from the library javax.sound.sampled. This is a core library, so there is no need to import anything. The Clip class loads audio files in RAM, and allows you to play them back from RAM on demand. It is mostly used for short sounds. You should be able to find some code examples if you include "java clip" in a search.
Also in that library is SourceDataLine. This is often used for sounds that are too large to hold in memory. The class plays back data that you provide to its write() method. Thus it is common to pair the class with an AudioInputStream that was set up to read data from a file location. Again, there should be code examples if you search on the class name.
I made use of SourceDataLine to write a small audio library which can be found on GitHub, called AudioCue. The syntax is simpler than with Clip, assuming your source file is a wav file with 16-bit encoding, 44100 fps, stereo, low-endian (also known as "CD Quality"). To make use of it, there are six classes to load. You can just cut and paste. It is kind of a "super Clip" in that it allows extra capabilities like real time volume, panning and variable speed playback, as well as concurrent playback. There is a simple "fire-and-forget" example posted in the README.MD
The library is free to use. (BSD-type license.)

How to play back in-memory sound via MediaPlayer in Java/JavaFX

The API reference says javafx.scene.media supports playback sound from URLs. In my case, the sound file is:
completely in memory (in a byte-array), or
downloaded on-the-fly into memory
It must not be saved to a local file, but I want to play it back via MediaPlayer.
How can I create a URL of an in-memory sound byte-array?
Sorry you can't , because:
Only HTTP, FILE, and JAR URLs are supported.
As per the documentation
com.sun.media.jfxmedia.AudioClip.create() (the class used internally by javafx.scene.media.AudioClip in Oracle's JFX implementation) offers the ability to create an audio clip from an in-memory byte array. However, as of java8-b127 it (and the other interesting methods that that class contains, such as createSegment) throw an UnsupportedOperationException.
The source code doc refer to http://javafx-jira.kenai.com/browse/RT-27007 However, it has been deleted from the JIRA. So, don't hold your breath for it to be implemented.

Android GTFS app

I'm trying to work on an app which uses GTFS. This may seems like a stupid question but I couldn't find any answer to it.
The GTFS for Israel, a rather small country with not so many buses infrastructure, is around 120 MB zipped file.
Right now the only possible way I could think of for getting it working is to download the file, but downloading 120 MB using the phone could take quite a long time. Sure you can do this only once and save it in a database on the phone, but it still requires downloading 120 MB.
Since it is zipped, I can't unzip it over the server and than just get the txt files..
So basically I'm asking, How can I get the information to the phone, without downloading the zipped file?
I've seen and used apps which uses that same GTFS file, and they load up really fast, even on the first load..
I hope you understand my issue, not sure how to explain it better.
Thanks!
P.s I would make an iPhone app too, and it's the same issue, hence the iPhone tag
One approach might be to preprocess the GTFS data during your app development. You could load it into a SQLite database, and use Core Data to get the data you need out of the file at runtime. This also gives you an opportunity to include only the data that you actually need for your app - it doesn't make sense to ask users to download extra data that they won't need.
Use protocol binary format (pbf) formely google and now open source. It is compact and very fast searchable, so no need to decompress it on a device and load it into a database on that device because pbf acts as a database. Just include pbf library in your code to query it. Of course you have to compress it once before distributing the data online.

Categories