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.
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 SoundPool to change the pitch of sound. A value of 1.0 means playback at the original frequency. A value of 2.0 means playback fast as with double speed, and a value of 0.5 means playback at half speed, but I want to to change the pitch of sound without changing playing speed(frequency) of sound.
How could I achieve that like I want to achieve robot like sound by setting pitch rate to 0.5 etc but playing speed is too slow.
Any help will highly appreciated!
I have a wav file playing through my speakers. Now I have recorded the sound playing through my speakers using my mic. At the same bit rate and PCM quality values as the playing file. Now I want to exactly sync these two songs.Say for eg: the 15th PCM value in the song playing through the speaker was recorded as the 5th PCM value. I want to detect this and sync the song accordingly. Complexity is not much a concern and I need to do this without human intervention. I know there would be noise and the values wont be the same but I need to just sync these two songs so they play exactly superimpose. I am using mono,16BIt PCM value with a bit rate of 44100.
Because of noise, distortion, echos and other delays, there is no simple solution for your problem. However, generally speaking, the solution to this type of problem is to use Cross Correlation. Broadly speaking, the peak in the cross-correlation will tell you the delay between the two signals.
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.
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