I am in the very ealy stages of developing this app but looking into it I have already reached a problem. I need to be able to play an audio file backwards (you know like to reveal hidden messages ;)). I have no experience working with audio on android and have no idea if this is even possible.
I found a question on here which solves the problem in java (Click Here For Question)
But this makes use of the javax.sound library which android does not support. Will I need this library to solve this problem or is there another way to reverse an audio file?
A typical WAV file consists of a 44-byte header followed by the actual sample values. The size of a "frame" is dependent upon the WAV file's properties: a file that is stereo and 16-bits-per-sample will have a 4-byte frame size (two bytes for the left sample and two bytes for the right sample).
So in code, you would create a second WAV file by creating a byte array the same overall size as the original. You copy the 44-byte header from the original into the copy, and then iterate through the original frames starting at the last and working forward to the first. You copy each frame into the inverse location in the copy array (i.e. last original frame is copied into the copy array immediately after the header; second-to-last frame is copied after the first frame etc.). Then just play the reversed file.
So you don't need the javax.sound library to do this - you just need to be able to copy and manipulate bytes. FYI, not all WAV files are "canonical" like this (canonical means 44-byte header plus sample values, and nothing else). The WAV format is actually a RIFF format, which means in theory you need to do more complex extraction of the sample values. In practice (especially if you're creating the WAV files yourself) you can usually get away with a much simpler approach as I've described here.
NOTE: if your sounds are MP3 files, then reversing is a more complicated task, since the sample data are not stored as samples in an MP3 file. If you're using MP3s, one way to reverse them is to convert them to WAV and then reverse the WAV file.
Related
I want merge more WAV files in my app into one WAV file. But I don't want combine them consecutively (like File1-File2-File3...) but all files should start at the same time (concurrently/simultaneously).
Is this possible in Android without using some natives libraries (like FFmpeg)? I looked at the AudioTrack and SoundPool but I think it's not a solution for this problem.
Also I found this post Android: How to mix 2 audio files and reproduce them with soundPool but how can I combine bytes from more WAV files?
If you use AudioTrack or SoundPool, you won't be able to synchronize playing precisely, and most probably that will be easy to hear. Another problem is that your files can have different sound level, and thus the softer ones will get masked by the louder ones (think of playing some pop track on top of a piece of soft classical music). You will probably need to normalize the levels of the input sound files.
For precise merging and normalizing at the same time, you have to mix the sound contents of the files yourself, and then play the resulting output. You will need to read the .wav files yourself as binary streams, as Android lacks Java's AudioInputStream class which could make this easier. See this as an example of how to do it with basic IO classes:
https://thiscouldbebetter.wordpress.com/2011/08/14/reading-and-writing-a-wav-file-in-java/
Now you have your sound data as an array of short integers. This answer describes how to convert samples data from integer into floating point and merge two audio streams, while normalizing their sound level:
https://stackoverflow.com/a/32023546/4477684
In order to merge more that two sound inputs, start with merging two, and then merge the result with the third input, and so on.
Android SDK provides class MediaMetadataRetriever for extracting metadata from MP4 files. Is there a way to edit MP4 metadata fields using MediaCodec API (without ffmpeg)? My task is to reset rotation field.
mp4parser seems to be what you are looking for, although I'm not certain where exactly the rotation field is located in the MP4 (I don't know enough about the file layout). If you know which box (or "atom") the metadata is stored in, then the MetaDataRead and MetaDataInsert classes are pretty clear examples of how to read and write the data (they specifically work on the iTunes "Name"/"Title" field, but writing other metadata works the same way, once you know where it should be located). Hope this helps!
Well, so I've been digging through an android game's files trying to get sprites and the like. So I've managed to come across this folder called "raw", and inside were jpg files like imagelocal2.jpg (along with imagelocal2.list) and such. These files aren't valid images and can't be viewed normally, but they're big enough to contain many images inside of them.
What I'm wondering is, is there some unknown JPG compression-like method where they manage to squish a bunch of files into one? I opened the files with a hex editor but I couldn't make heads or tails of them (the fact that I have no experience with hex editors doesn't really help), so if anyone knows anything about how these files are compressed, please help.
There is no standard multi-image JPEG format. it would be anything with a JPG extension. No competently-written decoder would rely on the extension anyway.
You could take a look at the first few bytes and try to match the file signature.
http://en.wikipedia.org/wiki/List_of_file_signatures
Requirement
Android open a .wav file in sd card, play it , add some effect (like echo, pitch shift etc), save the file with effect. Simple :(
What I know
I can open and play file using Soundpool or MediaPlayer.
I can give some effect while playing using both. ie for Media Player
I can set Environmental Reverb effect. Using SoundPool I can set
playing rate, which is kind of like pitch shift. I am successful in
implementing these right now.
But either of this classes doesn't have any method to save the
played file. So I can only play, I cannot save the music with
effect.
What I want to know
Is there any other classes of interest, other than MediaPlayer or
SoundPool. Never mind about saving, you just mention the class, I will do the
research about saving file with them.
Any 3rd party libraries where I can add effects and save? Happy if
it is open source and free. But mention them even if it is
proprietary.
Any other areas where I can look into. Does OpenAL support voice
filtering along with voice positioning? Will it work with Android?
Ready to do the dirty work. You please lend me the path..
EDIT: Did some more searching, and come across AudioTrack. But it also won't support saving to a file. So no luck there also..
EDIT Ok, what if I do it myself? Get raw bytes from a wav file, and work on that. I recorded a wav file using AudioRecord, got a wav file. Is there any resource describing low level audio processing (I mean at the bytes level).
EDIT Well bounty time is up, and I am giving bounty to the only answer that I got. After 7 days, what I understood is
We can't save what we play using MediaPlayer, AudioTrack etc.
There is no audio processing libraries available to use.
You can get raw wav files, and do the audio processing yourself. The
answer gave a good wrapper class for reading/writing wav files. A
good java code to read and change pitch of wav files is here.
The WavFile class http://www.labbookpages.co.uk/audio/javaWavFiles.html claims to read and write wav files and allow per-sample manipulation through arrays of sample values. It's certainly reasonably small, 23kbytes total source code.
I did struggle for a while to build an android app with the Wavfile Class included. This turned out to be because both WavFile and ReadExample (from the above link) were intended as standalone java programs, so include a method main(String [] args){}. Eclipse sees this and thinks the Class is a standalone runnable program, and, when I click the run button, tries to execute just the one Class with the java in the development machine, instead of launching the whole app to my phone. When I take care to run the whole app with the little drop-down menu on the run button, I don't have any trouble, and the WavFile Class and examples drop straight in, give zero warnings in the IDE, and work as advertised running on my phone.
I'm developing for Android 2.2.
Things put to res and assets are compressed in the APK by default unless their extension indicates that they're already compressed (mp3, png). Moreover, before Android 2.3, to assets, you could only put uncompressed files of size less than 1 MB.
Question 1:
if I put a 1.5MB binary file to res/raw, and my program refers to it with its standard Android ID (R.raw.....), then will the system pull the whole file into memory? Since the 1.5MB is stored in a compressed way, I suppose it must. This is unpleasant because it is possible that the program only needs 1KB of data to be loaded from a given file offset. This can have a serious impact on app performance/speed.
I see two solutions:
(hack) Use mp3 or png extensions; but I am not sure this allows memory-efficient access after all (i.e. inputstream.skipbytes, etc.)
After the installation, at the first start of the app, the app will copy the files to its own writable working folder (in SD card). Since this point, it will always access the files from there instead of the R.raw... way. Therefore, the sequential read will work for sure, i.e. the memory usage will be no more than the actual data read from the specified file offset (apart from temporary read buffers used by inputstream.seek implementation, which are well-optimized i.e. small I suppose).
Question 2:
what is the best way of reading binary data memory-efficiently, from big files? I don't want to split my big files into many small ones unless that's the only way.
I'd go with #2 solution and then would use RandomAccessFile to avoid linear access.
I also would to opt for solution #2, but instead of using random access file, I would use java.nio.MappedByteBuffer - this way you will get fast random access with byte buffer semantic.