Home | History | Annotate | Download | only in voice
      1 /*
      2  * Copyright (C) 2008-2009 Google Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
      5  * use this file except in compliance with the License. You may obtain a copy of
      6  * the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     13  * License for the specific language governing permissions and limitations under
     14  * the License.
     15  */
     16 
     17 package com.android.inputmethod.voice;
     18 
     19 import android.graphics.Bitmap;
     20 import android.graphics.Canvas;
     21 import android.graphics.Paint;
     22 
     23 import java.io.ByteArrayOutputStream;
     24 import java.nio.ByteBuffer;
     25 import java.nio.ByteOrder;
     26 import java.nio.ShortBuffer;
     27 
     28 /**
     29  * Utility class to draw a waveform into a bitmap, given a byte array
     30  * that represents the waveform as a sequence of 16-bit integers.
     31  * Adapted from RecognitionActivity.java.
     32  */
     33 public class WaveformImage {
     34     private static final int SAMPLING_RATE = 8000;
     35 
     36     private WaveformImage() {}
     37 
     38     public static Bitmap drawWaveform(
     39         ByteArrayOutputStream waveBuffer, int w, int h, int start, int end) {
     40         final Bitmap b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
     41         final Canvas c = new Canvas(b);
     42         final Paint paint = new Paint();
     43         paint.setColor(0xFFFFFFFF); // 0xRRGGBBAA
     44         paint.setAntiAlias(true);
     45         paint.setStrokeWidth(0);
     46 
     47         final ShortBuffer buf = ByteBuffer
     48             .wrap(waveBuffer.toByteArray())
     49             .order(ByteOrder.nativeOrder())
     50             .asShortBuffer();
     51         buf.position(0);
     52 
     53         final int numSamples = waveBuffer.size() / 2;
     54         final int delay = (SAMPLING_RATE * 100 / 1000);
     55         int endIndex = end / 2 + delay;
     56         if (end == 0 || endIndex >= numSamples) {
     57             endIndex = numSamples;
     58         }
     59         int index = start / 2 - delay;
     60         if (index < 0) {
     61             index = 0;
     62         }
     63         final int size = endIndex - index;
     64         int numSamplePerPixel = 32;
     65         int delta = size / (numSamplePerPixel * w);
     66         if (delta == 0) {
     67             numSamplePerPixel = size / w;
     68             delta = 1;
     69         }
     70 
     71         final float scale = 3.5f / 65536.0f;
     72         // do one less column to make sure we won't read past
     73         // the buffer.
     74         try {
     75             for (int i = 0; i < w - 1 ; i++) {
     76                 final float x = i;
     77                 for (int j = 0; j < numSamplePerPixel; j++) {
     78                     final short s = buf.get(index);
     79                     final float y = (h / 2) - (s * h * scale);
     80                     c.drawPoint(x, y, paint);
     81                     index += delta;
     82                 }
     83             }
     84         } catch (IndexOutOfBoundsException e) {
     85             // this can happen, but we don't care
     86         }
     87 
     88         return b;
     89     }
     90 }
     91