• (2 Pages)
  • +
  • 1
  • 2

Visualizing sound from the microphone

#1 EndLessMind  Icon User is offline

  • These are the droids you're looking for
  • member icon

Reputation: 193
  • View blog
  • Posts: 1,099
  • Joined: 13-March 09

Posted 08 December 2012 - 03:08 PM

Hello everyone, and welcome to another wonderful tutorial session.
Today, I'm going to show you how to create a custom SurfaceView that can visualizer the sound from your microphone!

This might sound really advanced, but it's isn't. Hang on and you'll find out for your self!

Introduction
Who doesn't like the beautiful music visualizations that you can find in your mediaplayer on your desktop?
But for some reason there aren't many music apps to Android that has this function.
That reason is that before Android 2.3, it was not possible to snoop the system sound.
Only the visualizer-wallpaper could do this, because is was hard-coded in to the android source code.
So, the only way to get sound from your device, would be from the microphone picking up sound from the speakers.
And this do of course not work very well for a music player where the user, often listen via headphones.

This is also the reason why you can find any tutorial on how to visualize sound on a android version older then 2.3
This is where i come in, this is going to be a quite big tutorial, with a lot of code, and i won't have time/room to explain everything.

Are you ready?
Then let's begin!

Creating the project
Okey, so lets start out with creating the project

Lets first create a new Android project and name it "com.example.soundvisualizer"
and the build target for Android 2.1, and next set the following:
Application name: Tutorial Sound Visualizer
Package name: com.example.soundvisualizer
Create Activity (Checked): MainActivity
Then press Finish.

We are not going to make any layout right now, because we need to make the widget, that we're going to use, first.


Starting small
So, now we're going to make a class.

We'll name it CSleeper and it will contain:
package com.example.soundvisualizer;

/**
 *  This is the sleeper for the visualizer
 *  This allows the sampler to collect data before running.
 *  @author Pontus Holmberg (EndLessMind)
 *  Email: the_mr_hb@hotmail.com
 **/ 
import java.io.PrintStream;

public class CSleeper
  implements Runnable
{
  private Boolean done = Boolean.valueOf(false);
  private MainActivity m_ma;
  private CSampler m_sampler;

  public CSleeper(MainActivity paramMainActivity, CSampler paramCSampler)
  {
    m_ma = paramMainActivity;
    m_sampler = paramCSampler;
  }

  public void run()
  {
    m_sampler.Init();
    while (true)
      try
      {
        Thread.sleep(1000L);
        System.out.println("Tick");
        continue;
      }
      catch (InterruptedException localInterruptedException)
      {
        localInterruptedException.printStackTrace();
      }
  }
}


This code is self explained.
Basically, it send the thread to sleep while the sampler is collecting data.

So far this has nothing to do with audio at all, but let's get working on it right now..


Sampling audio-data
Now we need to collect the audio-data, or sample as it's called in fancy-language.
To do that, we create a class called CSampler and adds this:
package com.example.soundvisualizer;

/**
 *  This is the sampler for the visualizer
 *  This collects the data the will be visualized
 *  @author Pontus Holmberg (EndLessMind)
 *  Email: the_mr_hb@hotmail.com
 **/

import android.media.AudioRecord;
import android.media.MediaPlayer;
import android.util.Log;
import com.example.soundvisualizer.*;

import java.io.PrintStream;

public class CSampler
{
  private static final int SAMPPERSEC = 44100;
  private static short[] buffer;
  private AudioRecord ar;
  private int audioEncoding = 2;
  private int buffersizebytes;
  private int buflen;
  private int channelConfiguration = 16;
  private int mSamplesRead;
  private Boolean m_bDead = Boolean.valueOf(false);
  private Boolean m_bDead2 = Boolean.valueOf(true);
  private Boolean m_bRun;
  private Boolean m_bSleep = Boolean.valueOf(false);
  private MainActivity m_ma;
  private Thread recordingThread;

  public CSampler(MainActivity paramMainActivity)
  {
    m_ma = paramMainActivity;
    m_bRun = Boolean.valueOf(false);
  }

  public Boolean GetDead2()
  {
    return m_bDead2;
  }

  public Boolean GetSleep()
  {
    return m_bSleep;
  }

  /**
   * Prepares to collect audiodata.
 * @throws Exception 
   */
  public void Init() throws Exception
  {
	  try {
    if (!m_bRun)
    {
      ar = new AudioRecord(1, 44100, channelConfiguration, audioEncoding, AudioRecord.getMinBufferSize(44100, channelConfiguration, audioEncoding));
      if (ar.getState() != 1)
      return;
      System.out.println("State initialized");
    }
	  } catch (Exception e) {
		  Log.d("TE", e.getMessage());
		  throw new Exception();
	  }
    while (true)
    {
      buffersizebytes = AudioRecord.getMinBufferSize(44100, channelConfiguration, audioEncoding);
      buffer = new short[buffersizebytes];
      m_bRun = Boolean.valueOf(true);
      System.out.println("State unitialized!!!");
      return;
    }
  }

  /**
   * Restarts the thread
   */
  public void Restart()
  {
    while (true)
    {
      if (m_bDead2.booleanValue())
      {
        m_bDead2 = Boolean.valueOf(false);
        if (m_bDead.booleanValue())
        {
          m_bDead = Boolean.valueOf(false);
          ar.stop();
          ar.release();
          try {
			Init();
		} catch (Exception e) {
			return;
		}
          StartRecording();
          StartSampling();
        }
        return;
      }
      try
      {
        Thread.sleep(1000L);
      }
      catch (InterruptedException localInterruptedException)
      {
        localInterruptedException.printStackTrace();
      }
    }
  }

  /**
   * Reads the data-bufferts
   */
  public void Sample()
  {
    mSamplesRead = ar.read(buffer, 0, buffersizebytes);
  }

  
  public void SetRun(Boolean paramBoolean)
  {
    m_bRun = paramBoolean;
    if (m_bRun.booleanValue())
      StartRecording();
    while (true)
    {
     
      StopRecording();
      return;
    }
  }

  public void SetSleeping(Boolean paramBoolean)
  {
    m_bSleep = paramBoolean;
  }


  public void StartRecording()
  {
	  if (ar == null) {
		  try {
			Init();
		} catch (Exception e) {
			e.printStackTrace();
		}
		  StartRecording();
	  } else {
		 
		  ar.startRecording(); 
	  }
    
  }

  /**
   * Collects audiodata and sends it back to the main activity
   */
  public void StartSampling()
  {
    recordingThread = new Thread()
    {
      public void run()
      {
        while (true)
        {
          if (!m_bRun.booleanValue())
          {
            m_bDead = Boolean.valueOf(true);
            m_bDead2 = Boolean.valueOf(true);
            return;
          }
          Sample();
          m_ma.setBuffer(CSampler.buffer);
        }
      }
    };
    recordingThread.start();
  }

  public void StopRecording()
  {
    ar.stop();
  }

  public short[] getBuffer()
  {
    return buffer;
  }


}


This is a bit more advance, right?
Actually no, this just instance a new AudioRecorder, starts and stops recording at the right time, and sends the data back to the main activity. Not really anything hard.
Well, now you might say "Hey man,i got an error at m_ma.setBuffer(CSampler.buffer);! What's up with that?"

That's because we haven't added that function to the Main activity, where we are trying to send the data.
Why haven't we done that, you might ask? Well there's no point at doing that until we completed the next step!

Lets move on to the hardest part, calculating the points for the line and render in to the screen.


A ballistic renderer, or not
Okey, so we got the audio-data where we want it, or soon we will.
Now, create a new class called CDrawer:
package com.example.soundvisualizer;

/**
 *  This is the drawer for the visualizer
 *  @author Pontus Holmberg (EndLessMind)
 *  Email: the_mr_hb@hotmail.com
 **/

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import java.io.PrintStream;
import java.util.Arrays;

public class CDrawer extends SurfaceView

  implements SurfaceHolder.Callback
  
{
	
  private Context mContext;
  private CDrawThread mDrawThread;
  private SurfaceHolder mHolder;

  private Boolean isCreated = false;
  /** 
   * This is where you instance the drawer
   * You relly don't need to care about the parameters, they are set in the xml-layout
   * @param Apply the baseContext of you current acitivty 
   * @param AttributeSet
   */
  public CDrawer(Context paramContext, AttributeSet paramAttributeSet)
  {
    super(paramContext, paramAttributeSet);
    System.out.println("CDrawer()");
    mHolder = getHolder();
    mContext = paramContext;
    mHolder.addCallback(this);
    mDrawThread = new CDrawThread(mHolder, paramContext, new Handler()
    {
      public void handleMessage(Message paramMessage)
      {
      }
    });
    mDrawThread.setName("" + System.currentTimeMillis());
    setFocusable(true);
  }

  public Boolean GetDead2()
  {
    return mDrawThread.GetDead2();
  }

  /**
   * restarts the thread
   * @param Is the thread dead?
   */
  public void Restart(Boolean paramBoolean)
  {
	  if (isCreated) {
    if (mDrawThread.GetDead2().booleanValue())
    {
      mDrawThread.SetDead2(Boolean.valueOf(false));
      if ((!paramBoolean.booleanValue()) || (!mDrawThread.GetDead().booleanValue()))

      mHolder = getHolder();
      mHolder.addCallback(this);
      System.out.println("Restart drawthread");
      mDrawThread = new CDrawThread(mHolder, mContext, new Handler()
      {
        public void handleMessage(Message paramMessage)
        {
        }
      });
      mDrawThread.setName("" + System.currentTimeMillis());
      mDrawThread.start();
      return;
    }
    Boolean No1,No2 = true;
    while (true)
    {
      while (No2 = true)
      {
        
        try
        {
          Thread.sleep(1000L);
          System.out.println("Just chilling in Restart");
          No2 = false;
          mDrawThread.SetDead2(Boolean.valueOf(true));
        }
        catch (InterruptedException localInterruptedException)
        {
          localInterruptedException.printStackTrace();
        }
        return;
      }
      
     if (!mDrawThread.GetDead().booleanValue())
        continue;
      mHolder = getHolder();
      mHolder.addCallback(this);
      System.out.println("Restart drawthread");
      mDrawThread = new CDrawThread(mHolder, mContext, new Handler()
      {
        public void handleMessage(Message paramMessage)
        {
        }
      });
      mDrawThread.setName("" +System.currentTimeMillis());
      mDrawThread.start();
      return;
    }
	  }
  }

  public void SetRun(Boolean paramBoolean)
  {
    mDrawThread.setRun(paramBoolean);
  }

  public CDrawThread getThread()
  {
    return mDrawThread;
  }

  /**
   * Called when there's a change in the surface
   */
  public void surfaceChanged(SurfaceHolder paramSurfaceHolder, int paramInt1, int paramInt2, int paramInt3)
  {
    mDrawThread.setSurfaceSize(paramInt2, paramInt3);
  }

  /**
   * Creates the surface
   */
  public void surfaceCreated(SurfaceHolder paramSurfaceHolder)
  {
    System.out.println("surfaceCreated");
    if (mDrawThread.getRun().booleanValue())
    {
      System.out.println("11111");
      isCreated = true;
      mDrawThread.start();
   
    }
    while (true)
    {
      System.out.println("22222");
      Restart(Boolean.valueOf(false));
      return;
    }
  }

  /**
   * Surface destroyd
   */
  public void surfaceDestroyed(SurfaceHolder paramSurfaceHolder)
  {
    int i = 1;
    while (true)
    {
      if (i == 0)
        return;
      try
      {
        mDrawThread.join();
        i = 0;
      }
      catch (InterruptedException localInterruptedException)
      {
      }
    }
  }

  /**
   * The Drawer Thread, subclass to cDrawer class
   * We want to keep most of this process in a background thread,
   * so the UI don't hang 
   *  @author Pontus Holmberg (EndLessMind)
   *  Email: the_mr_hb@hotmail.com
   */
  class CDrawThread extends Thread
  {
    private Paint mBackPaint;
    private Bitmap mBackgroundImage;
    private short[] mBuffer;
    private int mCanvasHeight = 1;
    private int mCanvasWidth = 1;
    private Paint mLinePaint;
    private int mPaintCounter = 0;
    private SurfaceHolder mSurfaceHolder;
    private Boolean m_bDead = Boolean.valueOf(false);
    private Boolean m_bDead2 = Boolean.valueOf(true);
    private Boolean m_bRun = Boolean.valueOf(true);
    private Boolean m_bSleep = Boolean.valueOf(false);
    private int m_iScaler = 8;
    private int counter = 0;
    /**
     * Instance the Thread
     * All the parameters i handled by the cDrawer class
     * @param paramContext
     * @param paramHandler
     * @param arg4
     */
    public CDrawThread(SurfaceHolder paramContext, Context paramHandler, Handler arg4)
    {
      mSurfaceHolder = paramContext;
      mLinePaint = new Paint();
      mLinePaint.setAntiAlias(true);
      mLinePaint.setARGB(255, 255, 0, 0);
      mLinePaint = new Paint();
      mLinePaint.setAntiAlias(true);
      mLinePaint.setARGB(255, 255, 0, 255);
      mBackPaint = new Paint();
      mBackPaint.setAntiAlias(true);
      mBackPaint.setARGB(255, 0, 0, 0);
      mBuffer = new short[2048];
      mBackgroundImage = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);

    }

    /**
     * Allow you to change the size of the waveform displayed on the screen
     * Or scale of you so will
     * @return returns a new scale value
     */
    public int ChangeSensitivity()
    {
      m_iScaler = (2 + m_iScaler);
      if (m_iScaler > 20)
        m_iScaler = 1;
      return m_iScaler;
    }

    public Boolean GetDead()
    {
      return m_bDead;
    }

    public Boolean GetDead2()
    {
      return m_bDead2;
    }

    public Boolean GetSleep()
    {
      return m_bSleep;
    }

    public void SetDead2(Boolean paramBoolean)
    {
      m_bDead2 = paramBoolean;
    }

    public void SetSleeping(Boolean paramBoolean)
    {
      m_bSleep = paramBoolean;
    }

    /**
     * Calculate and draws the line
     * @param Canvas to draw on, handled by cDrawer class
     */
    public void doDraw(Canvas paramCanvas)
    {
      if (mCanvasHeight == 1)
        mCanvasHeight = paramCanvas.getHeight();
      paramCanvas.drawPaint(mBackPaint); 
      /**
       * Set some base values as a starting point
       * This could be considerd as a part of the calculation process
       */
      int height = paramCanvas.getHeight();
      int BuffIndex = (mBuffer.length / 2 - paramCanvas.getWidth()) / 2;
      int width = paramCanvas.getWidth();
      int mBuffIndex = BuffIndex;
      int scale = height / m_iScaler;
      int StratX = 0;
      if (StratX >= width)
      {
        paramCanvas.save();
        return;
      }
   	int cu1 = 0;
   	/**
   	 * Here is where the real calculations is taken in to action
   	 * In this while loop, we calculate the start and stop points
   	 * for both X and Y
   	 * 
   	 * The line is then drawer to the canvas with drawLine method
   	 */
    while (StratX < width -1)
    {
      int StartBaseY = mBuffer[(mBuffIndex - 1)] / scale;
      
      int StopBaseY = mBuffer[mBuffIndex] / scale;
      if (StartBaseY > height / 2)
      {
    	  StartBaseY = 2 + height / 2;
        int checkSize = height / 2;
        if (StopBaseY <= checkSize)
        	return;
        StopBaseY = 2 + height / 2;
      }
 
        int StartY = StartBaseY + height / 2;
        int StopY = StopBaseY + height / 2;
        paramCanvas.drawLine(StratX, StartY, StratX +1, StopY, mLinePaint);
        cu1++;
        mBuffIndex++;
        StratX++;
        int checkSize_again = -1 * (height / 2);
        if (StopBaseY >= checkSize_again)
          continue;
        StopBaseY = -2 + -1 * (height / 2);
      }
    }

    public Boolean getRun()
    {
      return m_bRun;
    }

    /**
     * Updated the Surface and redraws the new audio-data
     */
    public void run()
    {
      while (true)
      {
        if (!m_bRun.booleanValue())
        {
          m_bDead = Boolean.valueOf(true);
          m_bDead2 = Boolean.valueOf(true);
          System.out.println("Goodbye Drawthread");
          return;
        }
        Canvas localCanvas = null;
        try
        {
          localCanvas = mSurfaceHolder.lockCanvas(null);
          synchronized (mSurfaceHolder)
          {
        	  if (localCanvas != null) 
            doDraw(localCanvas);
        	  
        }
        }
        finally
        {
          if (localCanvas != null)
            mSurfaceHolder.unlockCanvasAndPost(localCanvas);
        }
      }
    }

    public void setBuffer(short[] paramArrayOfShort)
    {
      synchronized (mBuffer)
      {
        mBuffer = paramArrayOfShort;
        return;
      }
    }

    public void setRun(Boolean paramBoolean)
    {
      m_bRun = paramBoolean;
    }

    public void setSurfaceSize(int paramInt1, int paramInt2)
    {
      synchronized (mSurfaceHolder)
      {
        mCanvasWidth = paramInt1;
        mCanvasHeight = paramInt2;
        mBackgroundImage = Bitmap.createScaledBitmap(mBackgroundImage, paramInt1, paramInt2, true);
        return;
      }
    }
  }
}

This class creates a SurfaceView that we can draw on, and it's this that will become our widget to place in a layout.
It also has the drawing thread in it, to keep the UI becoming unresponsive and do all calculations in on a separate thread. I could go on explaining the the code fully, but that would make this post to long for anyone to read.
Instead, the code is documented, specially the onDraw where the calculations happens.
But basically, I'm turning the data in to FFT-values and then easily calculating how long each line are going to be.

So, that is all the extra classes we need, now to MainActivity.java..

The Finish Line
Oh, that was quite a bit of code, right?
Well, we are almost done.
Now, in the ManActivity.java, we are going to do some stuff.
The code should look like this:
package com.example.soundvisualizer;

import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends Activity {
	private CDrawer.CDrawThread mDrawThread;
	private CDrawer mdrawer;
	
	  private View.onclickListener listener;
	  private Boolean m_bStart = Boolean.valueOf(false);
	 private Boolean recording;
	  private CSampler sampler;
	  @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mdrawer = (CDrawer) findViewById(R.id.drawer);
        m_bStart = Boolean.valueOf(false);

        
        while (true)
        {
          recording = Boolean.valueOf(false);
          run();    
          System.out.println("mDrawThread NOT NULL");
          System.out.println("recorder NOT NULL");
          return;
        }
    }
    /**
     * Pause the visualizer when the app is paused
     */
    @Override
    protected void onpause()
    {
      System.out.println("onpause");
      sampler.SetRun(Boolean.valueOf(false));
      mDrawThread.setRun(Boolean.valueOf(false));
      sampler.SetSleeping(Boolean.valueOf(true));
      mDrawThread.SetSleeping(Boolean.valueOf(true));
      Boolean.valueOf(false);
      super.onpause();
    }
    /**
     * Resters the visualizer when the app restarts
     */
    @Override
    protected void onRestart()
    {
      m_bStart = Boolean.valueOf(true);
      System.out.println("onRestart");
      super.onRestart();
    }
    /**
     * Resume the visualizer when the app resumes
     */
    @Override
    protected void onresume()
    {
      System.out.println("onresume");
      int i = 0;
      while (true)
      {
        if ((sampler.GetDead2().booleanValue()) && (mdrawer.GetDead2().booleanValue()))
        {
          System.out.println(sampler.GetDead2() + ", " + mdrawer.GetDead2());
          sampler.Restart();
          if (!m_bStart.booleanValue())
            mdrawer.Restart(Boolean.valueOf(true));
          sampler.SetSleeping(Boolean.valueOf(false));
          mDrawThread.SetSleeping(Boolean.valueOf(false));
          m_bStart = Boolean.valueOf(false);
          super.onresume();
          return;
        }
        try
        {
          Thread.sleep(500L);
          System.out.println("Hang on..");
          i++;
          if (!sampler.GetDead2().booleanValue())
            System.out.println("sampler not DEAD!!!");
          if (!mdrawer.GetDead2().booleanValue())
          {
            System.out.println("mDrawer not DeAD!!");
            mdrawer.SetRun(Boolean.valueOf(false));
          }
          if (i <= 4)
            continue;
          mDrawThread.SetDead2(Boolean.valueOf(true));
        }
        catch (InterruptedException localInterruptedException)
        {
          localInterruptedException.printStackTrace();
        }
      }
    }

    @Override
    protected void onstart()
    {
      System.out.println("onstart");
      super.onstart();
    }
    
    @Override
    protected void onstop()
    {
      System.out.println("onstop");
      super.onstop();
    }
    
    
    /** 
     * Recives the buffert from the sampler
     * @param buffert
     */
    public void setBuffer(short[] paramArrayOfShort)
    {
      mDrawThread = mdrawer.getThread();
      mDrawThread.setBuffer(paramArrayOfShort);
    }

    /**
     * Called by OnCreate to get everything up and running
     */
    public void run()
    {
    	  try 
    	  {
        if (mDrawThread == null)
        {
          mDrawThread = mdrawer.getThread();
        }
        if (sampler == null)
            sampler = new CSampler(this);
      Context localContext = getApplicationContext();
      Display localDisplay = getWindowManager().getDefaultDisplay();
      Toast localToast = Toast.makeText(localContext, "Please make some noise..", Toast.LENGTH_LONG);
      localToast.setGravity(48, 0, localDisplay.getHeight() / 8);
      localToast.show();
      mdrawer.setonclickListener(listener);
      if (sampler != null){
      sampler.Init();
      sampler.StartRecording();
      sampler.StartSampling();
      }
    	  } catch (NullPointerException e) {
    		  Log.e("Main_Run", "NullPointer: " + e.getMessage());
    	  }
    }
    
}


Basically, we handle all the onpause, onresume, onRestart so that the drawer dose the same as the MainActivity.
That way, it won't stay in the background draining battery and filling the garbage collector when you minimize the app.

Now we are almost done, now we go into the layout of the activity:
res->layout and there should be a file named main.xml
Replace all it's content with this small set of code
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <com.example.soundvisualizer.CDrawer
        android:id="@+id/drawer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:soundEffectsEnabled="true" />

</RelativeLayout>



That's about it, just go in to the manifest and add permissions, remove titlebar and set it as landscape.
Permission needed are:
android.permission.RECORD_AUDIO
android.permission.MODIFY_AUDIO_SETTINGS
Your manifast should look like this if you followed the tutorial:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.soundvisualizer"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="7" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" android:screenOrientation="landscape" android:theme="@android:style/Theme.NoTitleBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
</manifest>


This is the finish product of this tutorial
Attached Image


Here is the sources:
Attached File  Tutorial Sound Visualizer.zip (765.98K)
Number of downloads: 1462

OBS! This can not be run in a emulator, because of missing microphone support
Hope this can be helpful, and i wish you the best of luck, making android software.

Cheers, EndLessMind



------
from modi123_1:
Per this post - there is an update to some of the code.

http://www.dreaminco...attach_id=35296

This post has been edited by modi123_1: 12 March 2014 - 10:28 AM
Reason for edit:: updated link to new file download


Is This A Good Question/Topic? 3
  • +

Replies To: Visualizing sound from the microphone

#2 patax  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 12-August 13

Posted 16 August 2013 - 08:28 AM

Hello,
Thank you for this tutorial, it really helps to understand audio sampling in android.
I have encountered an issue though. When I turn the screen off and on again, the behavior of the app seems to be unpredictable. Sometimes it starts again without problems, but other times it freezes or force closes. When you use the home button or go to another app (without closing the sound visualizer with the back button) and then go back to the sound visualizer, it freezes most of the time. To my understanding there's a problem with the activity's lifecycle, but I don't know exactly where.
I haven't changed anything in the code from this tutorial and I've tried the app with 3 different phones running android 4.0 and 4.1.

Does anyone know how this could be solved?
Was This Post Helpful? 0
  • +
  • -

#3 sunil sunny  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 03-December 13

Posted 03 December 2013 - 12:36 AM

Hello,
Thank you for this tutorial
But i am not getting any wave .its just showing a blank line when i say something its not changing its state could you please help...
I haven't changed anything in the code from this tutorial and I've tried the app with android 2.3
Was This Post Helpful? 0
  • +
  • -

#4 EndLessMind  Icon User is offline

  • These are the droids you're looking for
  • member icon

Reputation: 193
  • View blog
  • Posts: 1,099
  • Joined: 13-March 09

Posted 03 December 2013 - 12:44 AM

Are you running on and emulator?
Was This Post Helpful? 1
  • +
  • -

#5 sunil sunny  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 03-December 13

Posted 03 December 2013 - 01:25 AM

Hello Again,
I just run the same code again in another phone and its working fine in android 4.1...
but have some orientation problems ,the app crashed when i tilted my phone everything else i s fine...
Then i run it on another phone it is android 2.2 And this time when I turn the screen off and on again, the behavior of the app seems to be unpredictable.

View PostEndLessMind, on 03 December 2013 - 12:44 AM, said:

Are you running on and emulator?


no i am not running it on emulator

Any way this is a very nice tutorial i will try to fix my errors ...Thank you for such a wonderful code.....
Was This Post Helpful? 0
  • +
  • -

#6 EndLessMind  Icon User is offline

  • These are the droids you're looking for
  • member icon

Reputation: 193
  • View blog
  • Posts: 1,099
  • Joined: 13-March 09

Posted 03 December 2013 - 04:24 AM

Okay. Well, it's not a perfect code.
It's more of a proof of concept thing :)
There is also a problem with devices with 1080p+ displays.
But most of the bugs is fixed with a few lines of code each :)
Was This Post Helpful? 1
  • +
  • -

#7 sunil sunny  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 03-December 13

Posted 03 December 2013 - 05:09 AM

View PostEndLessMind, on 03 December 2013 - 04:24 AM, said:

Okay. Well, it's not a perfect code.
It's more of a proof of concept thing :)/>
There is also a problem with devices with 1080p+ displays.
But most of the bugs is fixed with a few lines of code each :)/>

Was This Post Helpful? 0
  • +
  • -

#8 sunil sunny  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 03-December 13

Posted 03 December 2013 - 05:15 AM

k if possible can you please send the major fixes of the codes to my mail
my email id is sunilsunny565@gmail.com ..Thank you in advance
Was This Post Helpful? 0
  • +
  • -

#9 EndLessMind  Icon User is offline

  • These are the droids you're looking for
  • member icon

Reputation: 193
  • View blog
  • Posts: 1,099
  • Joined: 13-March 09

Posted 03 December 2013 - 05:24 AM

View Postsunil sunny, on 03 December 2013 - 12:15 PM, said:

k if possible can you please send the major fixes of the codes to my mail
my email id is sunilsunny565@gmail.com ..Thank you in advance

I would love to, but the only fixes i've right now is for the 1080p+ screen-issue.
I did fix almost all bugs, but that's when i used this code to create a firerate counter for Paintball guns.
But i lost all the code when my laptop crashed :/
Fortunately, the laptop only contained some old test project and that app.
So it wasn't much of a lost :P
Was This Post Helpful? 1
  • +
  • -

#10 sunil sunny  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 03-December 13

Posted 03 December 2013 - 05:34 AM

View PostEndLessMind, on 03 December 2013 - 05:24 AM, said:

View Postsunil sunny, on 03 December 2013 - 12:15 PM, said:

k if possible can you please send the major fixes of the codes to my mail
my email id is sunilsunny565@gmail.com ..Thank you in advance

I would love to, but the only fixes i've right now is for the 1080p+ screen-issue.
I did fix almost all bugs, but that's when i used this code to create a firerate counter for Paintball guns.
But i lost all the code when my laptop crashed ://>
Fortunately, the laptop only contained some old test project and that app.
So it wasn't much of a lost :P/>


View PostEndLessMind, on 03 December 2013 - 05:24 AM, said:

View Postsunil sunny, on 03 December 2013 - 12:15 PM, said:

k if possible can you please send the major fixes of the codes to my mail
my email id is sunilsunny565@gmail.com ..Thank you in advance

I would love to, but the only fixes i've right now is for the 1080p+ screen-issue.
I did fix almost all bugs, but that's when i used this code to create a firerate counter for Paintball guns.
But i lost all the code when my laptop crashed ://>
Fortunately, the laptop only contained some old test project and that app.
So it wasn't much of a lost :P/>


Ha ha that is very unfortunate.... :-D/>

Ha ha that is very unfortunate.... :-D/>

k then please send me the fixes you have now...
http://cdn.dreaminco...ault/tongue.gif
Was This Post Helpful? 0
  • +
  • -

#11 EndLessMind  Icon User is offline

  • These are the droids you're looking for
  • member icon

Reputation: 193
  • View blog
  • Posts: 1,099
  • Joined: 13-March 09

Posted 03 December 2013 - 05:36 AM

It is on it's way :)
Was This Post Helpful? 1
  • +
  • -

#12 sunil sunny  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 03-December 13

Posted 03 December 2013 - 05:37 AM

Thank you man !!!!
Was This Post Helpful? 0
  • +
  • -

#13 sunil sunny  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 03-December 13

Posted 03 December 2013 - 06:04 AM

Thanks some of the errors are fixed ...But if you are planning to correct all problems please mail me .!!!!!!!!!!!!!!

:)
Was This Post Helpful? 0
  • +
  • -

#14 kctong529  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 29-December 13

Posted 29 December 2013 - 10:52 AM

Would you consider making an audio processing library?
It can be hosted on GitHub and grow fast.
Was This Post Helpful? 0
  • +
  • -

#15 dinashehada  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 26-January 14

Posted 26 January 2014 - 03:46 AM

Hi Thank you,
but I have a comment Iam trying this on a nexus 4 but the output signal does not seem to look like a sound wave it's very different and i was wondering how can I make it a little slower or make the (duration) of the visualizer larger so the signal would be clearer
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2