I am looking for a way to play chords (4 notes together), threw audiotrack.
What is the best way to do this?
I consider about starting from a single sampled note, applying pitch filters to it. Is there a simpler solution for doing this?
thanks
A simpler way is to have an audio file for each note.
To play them at the same you will need to sum the signals of all the files. A java virtual machine is not the best environment to do this, take a look at the ByteBuffer API if you want to do it this way.
You can also use audiotrack objects in 4 different threads, so the write methode of AudioTrack won't block the other audiotracks playing sounds, I do this with 5 threads and it works.
Related
I have 5 audio files with each having length 5 seconds. I wanted to play each sound file one by one but the condition is if an audio file playing next file should play after 4 seconds ie adjacent audio file sounds should overlap for 1 second. How can I implement it? Which is the best audio player you can suggest?
The amount of specific work you can do with audio playback on the Java side is pretty limited on android.
It sounds like you will need to mix your sounds at some point during their playback to overlap.
The best way to do this in my head is through a C++ library called Oboe (I am currently working with this). This is a library created by Google for audio playback. Now hold on now, let me explain! I know implementing C++ (especially if your only on the Java stack right now) can add a bit of time to your project.
The reason this came to mind is because in this way of playing audio (through Oboe/C++), you physically move individual bits of the audio sample through a buffer stream. The C++ libraries also actually have a Mixer class that you can put 2 different audio samples (up to 100 actually) into to mix, and then eventually render through the buffer stream.
Using this methodology, you can add specific logic to manage when your audio starts playing (after 4 seconds if adjacent). At which point you can mix the first second of the next clip with the current playing clip.
Now the exciting bit, is you may be able to replicate this process in Java! I found this post which may be of help to you:
Android: How to mix 2 audio files and reproduce them with soundPool
Now I do warn you, rendering audio in this way (through buffer streams) is a complicated process, and some extra research may be needed to fully understand the process. I can't say I know all of the functionality of the Java audio libraries, but I'm willing to bet they don't have much support for mixing sound in the way that you need. So most likely you will have to mix it yourself, or your last resort might be to use the NDK (C++).
Hopefully this answer helps. The best wishes in your research! Hopefully you will find a simple way that works. (If you do, don't forget to share your findings on this question!)
I am developing a sound related application. I am trying to change the audio sound in to completely different like robot sound or make the audio echo. I tried with soundpool , but no any idea, anyone knows how to achieve that? i need only a basic idea to achieve this, please help. many thanks.
Pitch and echo are 2 different things.
Pitch:
You can alter the pitch by modifing the playback rate. You can do it in 2 ways, with audioTrack and setPlayBackRate or with SoundPool and setRate. Depends on your needs, AudioTrack allow a larger range of pitch (from 1hz to x2) on large files and SoundPool for sound effects and picth can vary between x0.5 and x2.
Echo/reverb:
You can archive this with AudioEffect since API lvl 9 by attaching it to an AudioTrack or MediaPlayer instance.
For a robot effect you want to set a constant pitch for the audio. I.e. do a FFT, move everything into a single frequency bin, and then do an inverse FFT to get back into the time domain.
For an echo effect you could keep a separate buffer which is as long as your desired echo delay. And for every sample do something like the following (pseudo-code):
output = mix(currentSample, echoBuffer[echoPos]*echoVolume)
echoBuffer[echoPos] = mix(currentSample, echoBuffer[echoPos]*echofeedback)
echoPos += 1
Im working on a similar project and i can say that you need to look into DSP (digital signal processing), PCM 16 format and preferably fourier transforms.
It is possible to loopback audio with the AudioRecord class (running a thread constantly filling the buffer on a AudioTrack)
But the delay might be too big for what you are trying to accomplish.
Best of luck in your endevours!
Some really good pointers:
Android AudioRecord class - process live mic audio quickly, set up callback function
I want to develop a bass effect for media player.Can any body help me regarding this..
First step is to isolate the low-frequency components. You will need an FFT to do this... there's one linked to this older S/O question.
After you've got the frequency representation of your audio data, alter the magnitudes of the low-frequency components as you see it, run the inverse transform to convert it back to audio samples, and pass it to the audio hardware for playback.
I'm currently implementing a sound effect mixing on Android via OpenSL. I have an initial implementation going, but I've encountered some issues.
My implementation is as follows:
1) For each sound effect I create several AudioPlayer objects (one for each simultaneous sound) that uses an SLDataLocator_AndroidFD data source that in turn refers to an OGG file. For example, if I have a gun firing sound (lets call it gun.ogg) that is played in rapid succession, I use around 5 AudioPlayer objects that refer to the same gun.ogg audio source and also the same outputmix object.
2) When I need to play that sound effect, I search through all the AudioPlayer objects I created and find one that isn't currently in the SL_PLAYSTATE_PLAYING state and use it to play the effect.
3) Before playing a clip, I seek to the start of it using SLPlayItf::SetPosition.
This is working out alright so far, but there is some crackling noise that occurs when playing sounds in rapid succession. I read on the Android NDK newsgroup that OpenSL on Android has problems with switching data sources. Has anyone come across this issue?
I'm also wondering if anyone else seen or come up with a sound mixing approach for OpenSL on Android. If so, does your approach differ from mine? Any advice on the crackling noise?
I've scoured the internet for OpenSL documentation and example code, but there isn't much out there with regards to mixing (only loading which I've figured out already). Any help would be greatly appreciated.
This is probably not the best approach (creating many instances of audio players). Unfortunately the Android version (2.3) of OpenSL ES doesn't support SLDynamicSourceItf. Which would be similar to OpenAL's source binding interface. One approach would be to create multiple stream players. You would then search for a stream player that isn't currently playing and start streaming your sound effect to it from memory. It's not ideal but it's doable.
You should probably not use the ogg format for sound effects either. You're better off with WAV (PCM) as it won't need to be decoded.
Ogg is fine for streaming background music.
is there a way to filter audio in android system?
I am interested to get only the audio of a fixed frequency.
If you get your audio via the AudioRecord class, then you'll have raw audio data that you could filter using whatever audio filter algorithm you have. Or are you looking for an audio filtering library?
As Dave says, the AudioRecord class is the easiest way. Often times, I will extend an AsyncTask that implements AudioRecord to read the audio buffer and push the buffer back to the UI thread for visualization (if needed).
Regarding the filtering of the audio, Android does not provide any built-in way of doing this. The way you would filter out certain frequencies is by taking the Fourier Transform of the sampled audio and then pulling out the frequencies of interest.
If you want more details on filtering, you should probably post a new SO question or wiki the Fast Fourier Transform (FFT). You might also look into JTransforms which is a great open source FFT library that runs wonderfully on Android.
Please do NOT use the FFT for this. That's amateur hour. (The FFT is a great tool with many great use-cases, but this is not one of them.) You most likely want to solve this problem using time domain filters. Here's a post to get you started writing your own filters in the time domain as easy as can be. However, a lot of people stumble on that since it's a bit specialized, so if you want to use something built-in to android, start with the equalizer audio effect.