Search This Blog

Showing posts with label Media. Show all posts
Showing posts with label Media. Show all posts

Monday, 22 July 2013

Sound Pool Tutorial in Android : changing pitch of an sound file

SoundPool provide a frequency range to change the pitch of voice. This tutorial address the sound pool features. After reading this tutorial you will be able to answer these question

1) What is soundPool?
2) Why we use it?
3) How to change pitch of sound file through frequency?

How to prepare a simple sound Pool?


Sound Pool : A SoundPool is a collection of samples that can be loaded into memory from a resource inside the APK or from a file in the file system. The SoundPool library uses the MediaPlayer service to decode the audio into a raw 16-bit PCM mono or stereo stream. This allows applications to ship with compressed streams without having to suffer the CPU load and latency of decompressing during playback.

Creating simple sound pool with one sound file. Keep your sound file inside raw folder

SoundPool soundPool = new SoundPool(50, AudioManager.STREAM_MUSIC, 0);

50 is the number of repeat cycle, 0 is srcquality

Now load one sound file and wait until load finish using OnLoadCompleteListener.

        /** Sound ID for Later handling of sound pool **/
        soundId = soundPool.load(this, R.raw.sounds, 1);
        soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
            @Override
            public void onLoadComplete(SoundPool arg0, int arg1, int arg2) {
                streamId = soundPool.play(soundId, 1, 1, 1, 3, pitch);
                soundPool.setLoop(streamId, -1);
                Log.e("TAG", String.valueOf(streamId));
            }
        });

This tutorial has two button two increase and decrease frequency rate. Just See the complete code

XML


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".PitchActivity" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="147dp"
        android:text="@string/hello_world" />

    <Button
        android:id="@+id/plus"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView1"
        android:layout_marginLeft="147dp"
        android:layout_marginTop="35dp"
        android:text="+" />

    <Button
        android:id="@+id/minus"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@+id/plus"
        android:layout_below="@+id/plus"
        android:layout_marginTop="41dp"
        android:text="-" />

</RelativeLayout>

Activity


package com.pitch;

import android.app.Activity;
import android.media.AudioManager;
import android.media.SoundPool;
import android.media.SoundPool.OnLoadCompleteListener;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

public class PitchActivity extends Activity implements OnClickListener {
    TextView mtxView;
    SoundPool soundPool;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pitch);
        mtxView = (TextView) findViewById(R.id.textView1);
        mtxView.setText("Current Pitch=0.5");
        findViewById(R.id.plus).setOnClickListener(this);
        findViewById(R.id.minus).setOnClickListener(this);
        setVolumeControlStream(AudioManager.STREAM_MUSIC);
        soundPool = new SoundPool(50, AudioManager.STREAM_MUSIC, 0);
        /** Sound ID for Later handling of sound pool **/
        soundId = soundPool.load(this, R.raw.sounds, 1);
        soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
            @Override
            public void onLoadComplete(SoundPool arg0, int arg1, int arg2) {
                streamId = soundPool.play(soundId, 1, 1, 1, 3, pitch);
                soundPool.setLoop(streamId, -1);
                Log.e("TAG", String.valueOf(streamId));
            }
        });
    }

    int streamId = 0;
    int soundId = -1;
    float pitch = 01f;

    @Override
    public void onClick(View arg0) {
        switch (arg0.getId()) {
        case R.id.minus:
            pitch -= 0.5;
            mtxView.setText("Current Pitch=" + pitch);
            soundPool.setRate(streamId, pitch);
            break;
        case R.id.plus:
            pitch += 0.5;
            mtxView.setText("Current Pitch=" + pitch);
            soundPool.setRate(streamId, pitch);
            break;
        default:
            break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        try {
            soundPool.pause(streamId);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}



Important Points : your file not be bigger than 32 because Android Audio Framework allows only 32 tracks(includes playing/stopped/paused/...) per mixer thread at the same time. If it exceed then you will get error code -12

AudioFlinger could not create track, status: -12
Error creating AudioTrack

Reference Link

Android Developer

Tuesday, 26 March 2013

Audio recording example in android using MediaRecorder

Recording audio in androd is simple. This article use MediaRecoder class to record Audio, Same class is used for recording video. This below class will illustrate the complete task of recording video

Recording.java 

import java.io.IOException;

import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.FragmentActivity;

public class Recording extends FragmentActivity {
    @Override
    protected void onCreate(Bundle arg0) {
        super.onCreate(arg0);
        try {
            MediaRecorder recorder = new MediaRecorder();
            recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            String str = Environment.getExternalStorageDirectory()
                    .getAbsolutePath();
            recorder.setOutputFile(str + "/" + System.currentTimeMillis()
                    + ".mp3");
            try {
                recorder.prepare();
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            recorder.start();
        } catch (Exception e) {
            e.getMessage();
        }
    }
}

Lets have a look how it work
recorder.setAudioSource(MediaRecorder.AudioSource.MIC) : set the source of audio. Here mic is doing the work of recording taking user voice as input

recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP) : Audio format in which you want output Setting path to reuse the recorded Audio

String str = Environment.getExternalStorageDirectory()
                    .getAbsolutePath();
recorder.setOutputFile(str + "/" + System.currentTimeMillis()
                    + ".mp3");

Permission is require to record audio and to save video inside manifest

<uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Thursday, 27 September 2012

Media player example in android with seek bar

Playing audio in android is very simple. It provides a lots of tool to handle life cycle of Media Player. We can play a audio file from following source

  • Playing from Resource
  • Playing from local i.e sdcard 
  • Playing from online URL 
Android provide some listener to handle how your song will play, to handle when your song completed, to forward song or to backward song.
I have make one simple application of media player that will play media from above three specified source. Lets discuss one by one


  • Playing from resource -  suppose you want to give one custom notification in an application. so better to keep this sound file inside raw folder and play it from there using Media Player. In this simple we do not need any bigger complexity                 
  • 1:  MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.sor);  
    2:  mediaPlayer.start();  
       

  • Playing from sdcard or online - These both ways are quite similar. We have to prepare Media Player to be ready for playing music either from sdcard or online URL.  But in online URL case we used  mediaPlayer.prepareAsync(); as we do not know how much time URL will take to respond. Immediately when Media Player prepared, called onPreparedListener();  and we start music. 
When music file played completely then listener onCompletionListener() gives us a way to start a new song or played it again. 
These are piece of line that will play a online URL

1:       /**  
2:        * Give the online url  
3:        */  
4:       private void PlayOnlineUrl() {  
5:            String url = "http://www.gaana.mp3"; // your URL here  
6:            MediaPlayer mediaPlayer = new MediaPlayer();  
7:            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);  
8:            try {  
9:                 mediaPlayer.setDataSource(url);  
10:            } catch (IllegalArgumentException e) {  
11:                 e.printStackTrace();  
12:            } catch (SecurityException e) {  
13:                 e.printStackTrace();  
14:            } catch (IllegalStateException e) {  
15:                 e.printStackTrace();  
16:            } catch (IOException e) {  
17:                 e.printStackTrace();  
18:            }  
19:            mediaPlayer.prepareAsync();  
20:            // You can show progress dialog here untill it prepared to play  
21:            mediaPlayer.setOnPreparedListener(new OnPreparedListener() {  
22:                 @Override  
23:                 public void onPrepared(MediaPlayer mp) {  
24:                      // Now dismis progress dialog, Media palyer will start playing  
25:                      mp.start();  
26:                 }  
27:            });  
28:            mediaPlayer.setOnErrorListener(new OnErrorListener() {  
29:                 @Override  
30:                 public boolean onError(MediaPlayer mp, int what, int extra) {  
31:                      // dissmiss progress bar here. It will come here when  
32:                      // MediaPlayer  
33:                      // is not able to play file. You can show error message to user  
34:                      return false;  
35:                 }  
36:            });  
37:       }  

                                                       Screen Shot will be look like

Media player
                         


Main thing remains now is, Extracting information of song file to show in the list. Even though i have not used this feature anywhere in my sample media player example but android provide a way to extract information about song like image, Song name, Album name, Year, Rating etc

If you are using Media query to fetch URL(From content provider) then you will get all information using cursor index else you can use MediaMetadataReceiver  class to find information about currently playing song.  These information will return as null if not available so checking these condition to avoid UN-necessary crash of application is very useful.

Note - MediaMetadataReceiver   is available only after API level 10


Generally this application run Media Player inside the main thread. But we recommend to play a media player inside a service so we have to bind a service with activity .Please see this how to bind a service and updating UI
                                             

                                        Download Source Code of Media Player

Android News and source code