Android's soundpool.play [documentation][1] says "The playback rate allows the application to vary the playback rate (pitch) of the sound. A value of 1.0 means play back at the original frequency. A value of 2.0 means play back twice as fast, and a value of 0.5 means playback at half speed.".
However, when I set the rate to 1.49f, I hear silence. 1.485f renders correctly (it's ogg file). Is this specific to my handset, is the documentation wrong, or am I being foolish in some other way?
[1]: http://developer.android.com/reference/android/media/SoundPool.html#play(int, float, float, int, int, float)
I'm sort of new at this, but I'm pretty sure it needs to be 0.5f, 1f, or 1.5f and no other values. It's not specific to any particular ogg file. I do know it changes the pitch during playback in soundmanager. Since no one else answered, I figured my answer might be better than no answer.
Related
I imagine the answer to this question must be something quite typical. The point is that I have some buttons that play sounds when you click on them. I want to control the sound volume. How do I control the sound volume? I am using the following code:
private fun playSound() {
val sound = getSystemService(Context.AUDIO_SERVICE) as AudioManager
sound.playSoundEffect(AudioManager.FX_KEY_CLICK, 1f)
}
https://developer.android.com/reference/android/media/AudioManager#playSoundEffect(int,%20float)
volume float: Sound effect volume. The volume value is a raw scalar so UI controls should be scaled logarithmically. If a volume of -1 is specified, the AudioManager.STREAM_MUSIC stream volume minus 3dB will be used. NOTE: This version is for applications that have their own settings panel for enabling and controlling volume.
So you need to adjust that second parameter. I haven't used it, but it says that's a scalar so I'd imagine 1 is full volume? It doesn't mention any other value as a max constant or anything. -1 gives you a sound a little quieter than the current media volume setting, if that's convenient. You'll need to play around with different values between 0 and 1 (I assume!) and see what you need
I would like to play an audio file that starts on the left speaker and then switches to the right speaker.
I have tried doing something like this:
MediaPlayer mp = new MediaPlayer();
// Setup audio file
mp.start();
mp.setVolume(1.0F, 0F);
// Delay a second or two (I actually use a Handler and the postDelayed method)
mp.setVolume(0F, 1.0F);
but the sound comes through on both speakers the whole time.
How can I play audio in Android with either the left or right speaker muted (or at reduced volume)?
EDIT:
I got the correct behavior for a while while I was testing my app, but then it returned to what I described above with the exact same code base. Based on this, is there anything else I could check to find out what's going on?
One option would be
Start mediaplayer with setVolume(1.0F, 0F);
When you want to switch to other speaker, get current position of media player by using getCurrentPosition() method.
Then stop media player.
Then again start with setVolume(0F,1.0F);
Seek to the positin you got in 2nd step using seekTo() method
Done.
Overhead:This method may cause you some delay
It looks like you are doing it correctly according to the Android API http://developer.android.com/reference/android/media/MediaPlayer.html
public void setVolume (float leftVolume, float rightVolume)
Sets the volume on this player. This API is recommended for balancing the output of
audio streams within an application. Unless you are writing an application to control
user settings, this API should be used in preference to setStreamVolume(int, int, int)
which sets the volume of ALL streams of a particular type. Note that the passed volume
values are raw scalars in range 0.0 to 1.0. UI controls should be scaled logarithmically.
Parameters
leftVolume left volume scalar
rightVolume right volume scalar
My best advice is to try 0.0F instead of just 0F and then maybe trying to set the volume before you start playing the track then transition while it's playing.
I want to make a Seek Bar that controls DTMF volume(e.g 0 to 100). I have searched a lot but could not find any thing. I am doing this but its not working..
int seekbarValue=seekBar.getProgress();
AudioManager audioManager=(AudioManager) getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_DTMF, seekbarValue, 0);
Please any one tell me a solution to control DTMF volume.
None of the (AudioManager.STREAM_*) volumes go to 100 (int).
A valid stream volume for setStreamVolume(...) is between 0 and getStreamMaxVolume(int streamType).
Each stream can have a different max volume int, like 8, 10, or 16 from what I remember. Might even be different on different devices.
I hope that is enough to point you and future visitors in the right direction.
I wanted to add a little more information to the answer of #Anonsage.
As #Anonsage mentioned, each stream has a different max volume. As per Kitkat 4.4.2 implementation, these are the max values.
STREAM.DTMF: 15
STREAM.MUSIC: 15
STREAM.VOICECALL: 5
STREAM.RINGTONE: 7
If you actually get into the lower levels and look into the AudioService.java of AOSP code, there is a rescaling operation that helps to show similar UI and update the actual values of the stream.
How can I implement
setRate(float f)
for my Android MediaPlayer, and secondly is it posible?
I believe this is the function you are looking for.
This sets the sampling rate at which the audio data will be consumed and played back, not the original sampling rate of the content. Setting it to half the sample rate of the content will cause the playback to last twice as long, but will also result in a negative pitch shift. The valid sample rate range is from 1Hz to twice the value returned by getNativeOutputSampleRate(int).
If you want to play mp3 directly using AudioTrack, you can either have a look at this example or convert your mp3 file to wav format, which enables AudioTrack to use it without hassle. This is the tradeoff you should account for if you want to adjust the playback rate easily.
Android 6.0 adds PlaybackParams for MediaPlayer, so you can now do this:
String recordingPath = recordingDirectory + File.separator + "music.mp3";
MediaPlayer audioPlayer = MediaPlayer.create(getApplicationContext(), Uri.parse(recordingPath));
audioPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
PlaybackParams params = new PlaybackParams();
params.setSpeed(0.75f);
audioPlayer.setPlaybackParams(params);
audioPlayer.start();
I don't have an Android 6 device yet, but this works for me in the emulator.
Based on the Android developer documentation, you may have to use SoundPool instead.
Android Developer: Media SoundPool-setRate
public final void setRate (int streamID, float rate)
Change playback rate. The playback rate allows the application to vary
the playback rate (pitch) of the sound. A value of 1.0 means playback
at the original frequency. A value of 2.0 means playback twice as
fast, and a value of 0.5 means playback at half speed. If the stream
does not exist, it will have no effect.
Parameters
streamID: a streamID returned by the play() function
rate: playback rate (1.0 = normal playback, range 0.5 to 2.0)
Similar topics on this question include only playing tone in mono where the left and right frequencies are the same.
My question is: how to generate a stereo tone such that the left channel has a different frequency than the right channel?
I thought of pre-recording .wav files but recording many .wav files and putting it on res folder is not a good idea.
i come across the SoundPool and AudioTrack class but I need a snippet showing the different frequencies of the left and right channel stored as buffer before playing the tone.
Or is there other ways? Please provide the desired snippet.
I have never tried this:
Initialize your left and right frequencies
//playback rate (1.0 = normal playback, range 0.5 to 2.0)
float lFrequency = 1.0;
float rFrequency = 1.0;
Initialize a SoundPool object
SoundPool sp = SoundPool(2, AudioManager.STREAM_MUSIC, 0);
Load your track twice (load function)
int sLeft = sp.load(mContext, R.raw.yourAudioFileId, 1);
int sRight = sp.load(mContext, R.raw.yourAudioFileId, 1);
Play the 2 sounds (one on Left and one on Right) using different rates (play function)
sp.play (sLeft, 1.0, 0.0, 0, 0, lFrequency);
sp.play (sRight, 0.0, 1.0, 0, 0, rFrequency);
From my understanding, if you use SoundPool it will play in stereo without any special configuration. From the documentation: "The SoundPool library uses the MediaPlayer service to decode the audio into a raw 16-bit PCM mono or stereo stream"
so as long as the file you play is in Stereo to begin with, it should play that way.
Instead of prerecording WAV files and embedding them in your application, you can instead generate the split-channel WAV audio in memory from code, and then either save it as a WAV file that you would play with SoundPool, or play the audio directly using AudioTrack (I'd recommend the latter).
The audio itself is just an array of (usually) 2-byte integers. With stereo, the left and right samples are interleaved throughout the array (so sample[0] is the first L sample, sample[1] is the first R sample, sample[2] is the second L sample etc.). So when your app starts up, you would create an array however long you need (with CD-quality audio, your array will need 88200 elements for each second of audio) then fill the samples with calculated values for your tone, then pass the array to AudioTrack for playing.
Or you would save the audio as a WAV file and play it with SoundPool (which might actually be better from a memory footprint standpoint). The WAV format is very simple to write (reading is more complicated): just a 44-byte header with various properties, and then the audio data itself.
I think I've answered a similar android question before, so I'm going to go see if I have some basic code for doing this.
Not me, but some good code for reading and writing WAV files in java:
http://computermusicblog.com/blog/2008/08/29/reading-and-writing-wav-files-in-java
I would use other software to generate an .ogg stereo file (don't use WAV files, they weight too much), wich is a very lightweight audio format wich works well in Android. I use the free Reaper, Audacity is easier, anyone would do. Just create two mono audio tracks, set their pan to full right and full left. Load your samples, and apply a pitch-change plugin to alter the frequency of one of the tracks. You can also generate them with a sintesizer. Then render all to a tone.ogg file.
Tone