I am wondering if there is a way to change the sampling rate at which MediaPlayer plays data back. I'd like to tweak it and play data back at a slower rate than encoded. Thoughts?
This might not be doable with MediaPlayer, but for audio you can do it with SoundPool:
The playback rate can also be changed. A playback rate of 1.0 causes
the sound to play at its original frequency (resampled, if necessary,
to the hardware output frequency). A playback rate of 2.0 causes the
sound to play at twice its original frequency, and a playback rate of
0.5 causes it to play at half its original frequency. The playback rate range is 0.5 to 2.0.
You didn't mention this in your original question, but if you want to maintain pitch while changing the frequency, you'd need to provide a pitch-shift algorithm. Perhaps there's one in the android.media.audiofx package - there's a queryEffects() method that might return some type of pitch shifter.
For MediaPlayer, you might look at the attachAuxEffect method that would let you process the audio stream.
Related
I am working with ijkplayer video player library to play videos in my android app.But when i try to increase the audio speed (e.g 1.5+) it change my audio tone.I looked into the source code of ijkplayer but couldn't figure out the issue. When setting playback rate it calculates pitch and sample rate which seems working to me.I enabled soundtouch for playing audio.Can anyone help me figure out how i can fix this issue. If you need more information please leave a comment.
I'm not familiar with the specific software you are using, but a fundamental aspect of sound is that if you change the rate of the playback, this will change the pitch of the sound. Sound is measured in pulses per unit time, for example, in Hertz, which is waves per second, where 440 Hz is the A note used to tune an orchestra. If you change the rate of playback to speed it up 50%, the resulting sound will vibrate at 660 Hz, which is the E above that A.
If you want to change the playback rate without altering the pitch, this will require additional digital signal processing. The algorithm is a bit too complex for me to explain here. It involves breaking the original signal up into 'granules' and rejoining them. The process is specialized enough that it is something more commonly dealt with at another forum, dedicated to Signal Processing.
I am using the AudioRecord class to record an user's voice through mic. Is there anyway to change the voice or pitch of the user during the recording in progress. If there is no such way, how can I modulate the output audio file and alter its pitch and save the file back. I don't need the solution to alter the pitch while playing the audio. Thanks in advance.
If you don't care about preserving playback speed, then most simple solution is to change playback speed. I.e. you can record a sound in 22050 samples per second rate, and then put it in a file, as if it was recorded in 44100 sps. When file will be played, it will be 2 times faster and, respectively, one octave higher pitch.
If you want to preserve the sampling rate, or you want to change speed in some fractional ration, then you need to apply some resampling algorithm to your sound data.
If you want to change only pitch while preserving playback time, you need to implement some algorithm on your own.
There are a lot of algorithms that allows to change a pitch. They varying on their sound quality.
For my taste, better quality could be obtain by performing FFT-based time stretch algorithm, which will make your sound longer or shorter while preserving pitch. After that apply a resampling algorithm with reciprocal scale, which will change both pitch and speed, and speed will be returned back to original, while pitch will be changed as you want.
I don't think there are solutions in stile "someObject.doEverythingGoodForMe()" that will be work on all platforms.
My question is about the relative latency of playing, pausing/stopping, and setting volume of audio in Android. Specifically: whether it's the same or lower latency to pause/stop an audio clip than to play it, and likewise whether it's the same or lower latency to set the volume of a clip (or of the system volume) than to play it.
For context, suppose the latency of playing an audio clip in Android is 150ms, i.e. SoundPool.play is executed at T=0m and the end-user hears the sound at T=150ms.
At T=200m, the program executes SoundPool.pause. If the pause latency is also 150m, that means the pause won't be heard by the end-user until T=350m, after they have heard 200m of the clip. If, however, the pause latency is, say 50m, then the sound will stop at T=250m, after only 100m has been head by the end-user.
Obviously latency isn't constant, exact, or consistent across devices, so to be more precise, what I'm really asking is whether Android uses a separate pathway or technique to pause/stop/change volume of audio (either program-specific or system-wide volume) that is inherently lower-latency than the way audio is played.
Setting up Play takes more time as it has to initialize the play the following actions takes path
find the MIME type of the media file, this needs parsing of the media format and looks for specific header
initialize audio decoder(usually hardware), the OMX decoder has to be loaded into memory
setup the buffers say allocate 10 buffers in the parser and 10 buffers in the decoder.
Setup the paths between parser and decoder and playback audio device (Speaker)
Play happens at this step, data flows from parser buffers to decoder buffers, when the decoder buffers are filled, OMX (decoder framework) will notify player engine, engine passes the buffer data to AudioManager -> AudioTrack etc.
Decoder will again process the data from Parser buffers and this process goes on until EOF or user press pause/stop
During pause latency should be much low than play because, only the data exchnage is paused, but buffers are not released.
During stop buffers are released and player is also released, so need to do same process for play again if user needs to play again.
Volume up and down is simple calls to AudioManager to adjust the call voleumes. So its latency should be lower than play/stop
Is it possible to change the sampling rate while recording an Audio in Android using AudioRecord or MediaRecorder?
Both of these class requires to initialize first the sampling rates before recording an Audio, But I was wondering if I can change the sampling rate, let's say 8000 to 16000 and vis-a-vis, in the middle of recording.
What would you expect to happen when you change the sampling rate once it is recording? Setting the rate directly is not supported by AudioRecord, so that is a definite no.
Setting the rate directly with MediaRecorder is allowed, but is expected to be done before starting the recording. I would not expect all, if any, implementations of the Android OS to handle this.
I am making a birding app with playback to call birds. Many of the songs recorded are quite bad, some with very low volume. I know how to set max volume of music with
AudioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0);
but this may not be enough for many songs; my Galaxy Note has quite bad speakers, and even with headphones max is low...
Would it be possible to add gain over this max for low volume songs, in order to be played at a decent volume?
This may sound like a silly question, but mplayer for Linux/Maemo has this option, called gain, that allowed me to play some songs higher than max in a Nokia N800.
Thanks!!
instead of using mediaplayer use audiotrack to play the filese. for the the work flow will be following
read from the files as byte or short array
to add a gain just multiply the sample by some fraction
(related question Android - how to add gain control when recording)
now write the samples to audiotrack
then play it.