Android音频可视化开发案例说明

2016-02-19 11:23 83 1 收藏

在这个颜值当道,屌丝闪边的时代,拼不过颜值拼内涵,只有知识丰富才能提升一个人的内在气质和修养,所谓人丑就要多学习,今天图老师给大家分享Android音频可视化开发案例说明,希望可以对大家能有小小的帮助。

【 tulaoshi.com - 编程语言 】

Android 调用自带的录制音频程序
Android中有自带的音频录制程序,我们可以通过指定一个Action MediaStore.Audio.Media.RECORD_SOUND_ACTION的Intent来
启动它就可以了。然后在onActivityResult()方法中,获取Intent的Data,就是录制的音频对应的URI。
java代码:
代码如下:

package eoe.demo;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Toast;
/**
* 被实例演示如何调用Android自带的应用来完成Audio的录入
* 其实很简单,我们需要指定一个MediaStore.Audio.Media.RECORD_SOUND_ACTION的Action来启动就可以
* 返回的Data数据就是我们录制的音频的URI了
*
* 通过上面这种方式,灵活性不够高,我们可以利用MediaRecorder类来实现自己的音频录制程序
* MediaRecorder既可以用来录制音频,也可以用来录制视频
* 创建了一个MediaRecorder实例后,需要调用setAudioSource和setAudioEncoder来初始化
* 通常情况下,在准备录制前,我们还需要调用setOutputFormat()方法来决定使用的音频格式,同时调用
* setOutputFile()来指定存放录制内容的文件
*
* 这几个方法的调用顺序是:setAudioSource,setOutputFormat,setAudioEncoder,setOutputFile
*
*
*
* @author Administrator
*
*/
public class AudioRecordDemo extends Activity {
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.audio_record);
}
public void onActivityResult(int requestCode, int resultCode, Intent data){
//super.onActivityResult(requestCode, resultCode, data);
//这里我们就可以获取到刚刚录制的音频的Uri,可以进行播放等操作,这里显示返回的Uri
if(resultCode == RESULT_OK){
Uri audioPath = data.getData();
Toast.makeText(this, audioPath.toString(), Toast.LENGTH_LONG).show();
}
}
public void onClick(View v){
int id = v.getId();
switch(id){
case R.id.btn1: //调用Android自带的音频录制应用
Intent intent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
startActivityForResult(intent, 0);
break;
case R.id.btn2:
//通过MediaRecorder类来实现自己的音频录制程序
Intent intent2 = new Intent();
intent2.setClass(this, MyAudioRecord.class);
startActivityForResult(intent2, 1);
break;
case R.id.btn3:
//通过AudioRecord类实现自己的音频录制程序
Intent intent3 = new Intent();
intent3.setClass(this, MyAudioRecord2.class);
startActivityForResult(intent3, 2);
break;
}
}
}

Android 音频的介绍
最近移植Android,当Android能够在设备上面运行之后,首先想到的是让音频设备跑起来。“没有声音,再好的戏也出不来”。本文简单介绍一下Android音频适配层。
这个世界音频设备千变万化,Android也不可能为每种设备都提供支持。Android定义了一个框架,这个框架来适配底层的音频设备。该适配层的定义位于:
Java代码:
代码如下:

hardware/libhardware_legacy/include/hardware_legacy/AudioHardwareInterface.h

要想视频底层的音频设备必须要继承该文件中定义的AudioStreamOut,AudioStreamIn,AudioHardwareInterface等类,并实现createAudioHardware函数。
下面我们看一下Android创建音频设备的代码,代码位于:
Java代码:
代码如下:

frameworks/base/libs/audioflinger/AudioHardwareInterface.cpp

该文件有如下代码:
Java代码:
代码如下:

AudioHardwareInterface* AudioHardwareInterface::create()
{
/*
* FIXME: This code needs to instantiate the correct audio device
* interface. For now - we use compile-time switches.
*/
AudioHardwareInterface* hw = 0;
char value[PROPERTY_VALUE_MAX];
#ifdef GENERIC_AUDIO
hw = new AudioHardwareGeneric();
#else
// 如果运行在仿真中——用这个模拟器
if (property_get("ro.kernel.qemu", value, 0)) {
LOGD("Running in emulation - using generic audio driver");
hw = new AudioHardwareGeneric();
}
else {
LOGV("Creating Vendor Specific AudioHardware");
hw = createAudioHardware();
}
#endif
if (hw-initCheck() != NO_ERROR) {
LOGW("Using stubbed audio hardware. No sound will be produced.");
delete hw;
hw = new AudioHardwareStub();
}
#ifdef WITH_A2DP
hw = new A2dpAudioInterface(hw);
#endif
#ifdef ENABLE_AUDIO_DUMP
recorded in the file.
LOGV("opening PCM dump interface");
hw = new AudioDumpInterface(hw); // replace interface
#endif
return hw;
}

从代码中我们可以看出如果定义了GENERIC_AUDIO的宏,则会创建AudioHardwareGeneric,如果是模拟器的话,AudioHardwareGeneric会不能初始化,进而创建AudioHardwareStub。这两个类都是Audio设备的适配层,是Android默认提供的。模拟器都是用AudioHardwareStub,不会有声音输出。设备都是用AudioHardwareGeneric,因为默认GENERIC_AUDIO是设置的。
一般我们只关心AudioHardwareGeneric实现,谁会去给模拟器去调试声音呢,反正我没这个闲心。首先说明一下这个音频适配层是Android自带的,可以保证你的音频设备正常运行,但是不能发挥设备的最佳性能。通过后面的描述你将会了解。AudioHardwareGeneric的定义位于:
Java代码:
代码如下:

frameworks/base/libs/audioflinger/AudioHardwareGeneric.cpp

上面就是eoe给我们介绍音频用途,如果有什么不明白的就多看看android的源码,这样有助与你对音频的理解。
先看一下效果图
 
代码如下:

public class FFTActivity extends Activity implements OnClickListener{
private Button button;
private ImageView imageView;
private int frequency = 8000;
private int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
private RealDoubleFFT transformer;
private int blockSize = 256;
private boolean started = false;
private Canvas canvas;
private Paint paint;
private Bitmap bitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fft);
button = (Button) findViewById(R.id.fft_button);
button.setOnClickListener(this);
imageView = (ImageView) findViewById(R.id.fft_imageView);
transformer = new RealDoubleFFT(blockSize);
bitmap = Bitmap.createBitmap(256, 100, Bitmap.Config.ARGB_8888);
canvas = new Canvas(bitmap);
paint = new Paint();
paint.setColor(Color.GREEN);
imageView.setImageBitmap(bitmap);
}
private class RecordAudio extends AsyncTaskVoid, double[], Void {
@Override
protected Void doInBackground(Void... params) {
int bufferSize = AudioRecord.getMinBufferSize(frequency,
channelConfiguration, audioEncoding);
AudioRecord audioRecord = new AudioRecord(
MediaRecorder.AudioSource.MIC, frequency,
channelConfiguration, audioEncoding, bufferSize);
short[] buffer = new short[blockSize];
double[] toTransform = new double[blockSize];
audioRecord.startRecording();
while (started) {
//将record的数据 读到buffer中,但是我认为叫做write可能会比较合适些。
int bufferResult = audioRecord.read(buffer, 0, blockSize);
for (int i = 0; i bufferResult; i++) {
toTransformi = (double) bufferi / Short.MAX_VALUE;
}
transformer.ft(toTransform);
publishProgress(toTransform);
}
audioRecord.stop();
return null;
}
@Override
protected void onProgressUpdate(double[]... values) {
super.onProgressUpdate(values);
canvas.drawColor(Color.BLACK);
for (int i = 0; i values[0].length; i++) {
int x=i;
int downy=(int)(100-(values[0]i)*10);
int upy=100;
canvas.drawLine(x, downy, x, upy, paint);
}
imageView.invalidate();
}
}
@Override
public void onClick(View v) {
started=true;
new RecordAudio().execute();
}
}

android音频可视化的原理是使用离散傅里叶变换,但是数学不好的同学不要担心,有开源的java离散傅里叶变换的代码!!直接到www.netlib.org/fftpack/jfftpack.tgz,直接将里面javasource目录拖动到(ca目录)src即可!!

来源:http://www.tulaoshi.com/n/20160219/1597324.html

延伸阅读
标签: 软件教程
我们在进行了调查普及之后得到的数据是独立的,所以需要对数据进行分析才能体现调查之后我们要知道的情况。下面小编为大家分享一下FineReport报表如何进行数据可视化分析 1、B/S数据源配置 启动web服务器(FR工程部署在web服务器下,端口号为对应的web服务器端口号,如tomcat下,端口号为8080,如果...
20个简单易上手堪称「神器」的可视化工具   国外的可视化行业发展得相当成熟,这催生了不少在线信息图表制作工具,介绍比较好用的几个,利用它们,五分钟你就可以做出一张超屌的信息图表: 1】infogr.am 这是较早的一个在线制作工具,亮点是支持实时数据刷新,而且制作的信息图表支持在多终端展示。 2】Venngage...
虽然如今好的配色方案已经唾手可得,但想为数据可视化找到合适的配色方案,难度仍然不小。因信息图的独特属性,在保证色彩具有清晰辨识度的同时,还必须满足丰富而不凌乱的配色要求。不过即使你对色彩不敏感,用了今天这篇干货提到的3个技巧,也能轻松制作出好看的信息图。 在信息图方面,事情甚至更加棘手,因为我们要通过上千种各不相同的数...
可视化数据信息图是将一些复杂的数据以图形化形式展示出来,信息图的视觉呈现要求很高的,如果设计不好,还不如直接看Excel表格了。所以设计可视化信息图是非常考验设计师们的能力。 如果没有设计过信息图的同学,建议还是多看点别人的作品,今天设计达人网整理了31张来自Dribbble上的设计精美的可视化数据信息图,我想这些一定能给你带来创作...
需要寻找信息图灵感?又或者需要制作一些数据信息图?那么今天分享的25个可视化信息图表素材你一定能派上用场。这里的可视化素数据材风格多样化,有常用的数据柱状图、人物模型、创意图像等,外面流行时尚,适合大部分数据信息展示。 Infographic Template   进入下载页 Infographic Elements Pack   进入下载页 Infographic...

经验教程

359

收藏

27
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部