最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android音頻可視化開發(fā)案例說明

 更新時間:2012年12月28日 14:42:03   投稿:whsnow  
最近移植Android,當Android能夠在設備上面運行之后,首先想到的是讓音頻設備跑起來?!皼]有聲音,再好的戲也出不來”接下來介紹Android音頻可視化開發(fā)流程

Android 調(diào)用自帶的錄制音頻程序
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;
/**
* 被實例演示如何調(diào)用Android自帶的應用來完成Audio的錄入
* 其實很簡單,我們需要指定一個MediaStore.Audio.Media.RECORD_SOUND_ACTION的Action來啟動就可以
* 返回的Data數(shù)據(jù)就是我們錄制的音頻的URI了
*
* 通過上面這種方式,靈活性不夠高,我們可以利用MediaRecorder類來實現(xiàn)自己的音頻錄制程序
* MediaRecorder既可以用來錄制音頻,也可以用來錄制視頻
* 創(chuàng)建了一個MediaRecorder實例后,需要調(diào)用setAudioSource和setAudioEncoder來初始化
* 通常情況下,在準備錄制前,我們還需要調(diào)用setOutputFormat()方法來決定使用的音頻格式,同時調(diào)用
* setOutputFile()來指定存放錄制內(nèi)容的文件
*
* 這幾個方法的調(diào)用順序是: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: //調(diào)用Android自帶的音頻錄制應用
Intent intent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
startActivityForResult(intent, 0);
break;
case R.id.btn2:
//通過MediaRecorder類來實現(xiàn)自己的音頻錄制程序
Intent intent2 = new Intent();
intent2.setClass(this, MyAudioRecord.class);
startActivityForResult(intent2, 1);
break;
case R.id.btn3:
//通過AudioRecord類實現(xiàn)自己的音頻錄制程序
Intent intent3 = new Intent();
intent3.setClass(this, MyAudioRecord2.class);
startActivityForResult(intent3, 2);
break;
}
}
}

Android 音頻的介紹
最近移植Android,當Android能夠在設備上面運行之后,首先想到的是讓音頻設備跑起來。“沒有聲音,再好的戲也出不來”。本文簡單介紹一下Android音頻適配層。
這個世界音頻設備千變?nèi)f化,Android也不可能為每種設備都提供支持。Android定義了一個框架,這個框架來適配底層的音頻設備。該適配層的定義位于:
Java代碼:
復制代碼 代碼如下:

hardware/libhardware_legacy/include/hardware_legacy/AudioHardwareInterface.h

要想視頻底層的音頻設備必須要繼承該文件中定義的AudioStreamOut,AudioStreamIn,AudioHardwareInterface等類,并實現(xiàn)createAudioHardware函數(shù)。
下面我們看一下Android創(chuàng)建音頻設備的代碼,代碼位于:
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();
#elseif (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的宏,則會創(chuàng)建AudioHardwareGeneric,如果是模擬器的話,AudioHardwareGeneric會不能初始化,進而創(chuàng)建AudioHardwareStub。這兩個類都是Audio設備的適配層,是Android默認提供的。模擬器都是用AudioHardwareStub,不會有聲音輸出。設備都是用AudioHardwareGeneric,因為默認GENERIC_AUDIO是設置的。
一般我們只關(guān)心AudioHardwareGeneric實現(xiàn),誰會去給模擬器去調(diào)試聲音呢,反正我沒這個閑心。首先說明一下這個音頻適配層是Android自帶的,可以保證你的音頻設備正常運行,但是不能發(fā)揮設備的最佳性能。通過后面的描述你將會了解。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 AsyncTask<Void, 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的數(shù)據(jù) 讀到buffer中,但是我認為叫做write可能會比較合適些。
int bufferResult = audioRecord.read(buffer, 0, blockSize);
for (int i = 0; i < bufferResult; i++) {
toTransform<i> = (double) buffer<i> / 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音頻可視化的原理是使用離散傅里葉變換,但是數(shù)學不好的同學不要擔心,有開源的java離散傅里葉變換的代碼??!直接到www.netlib.org/fftpack/jfftpack.tgz,直接將里面javasource目錄拖動到(ca目錄)src即可!!

相關(guān)文章

  • Android軟鍵盤擋住輸入框的終極解決方案

    Android軟鍵盤擋住輸入框的終極解決方案

    最近在開發(fā)android的項目,在項目開發(fā)中遇到各種坑,今天小編就給大家分享一個關(guān)于軟鍵盤擋住輸入框的問題,下面給大家介紹的非常詳細,具有一定的參考借鑒價值,對軟鍵盤擋住輸入框的知識感興趣的朋友一起看看吧
    2016-10-10
  • Android三種菜單實例分析

    Android三種菜單實例分析

    這篇文章主要介紹了Android三種菜單,較為詳細的分析了Android菜單分類及相關(guān)使用技巧,需要的朋友可以參考下
    2015-05-05
  • Android Room數(shù)據(jù)庫自動升級與遷移的策略

    Android Room數(shù)據(jù)庫自動升級與遷移的策略

    在 Android 應用開發(fā)中,Room 是 Google 提供的一個輕量級數(shù)據(jù)庫框架,用于簡化與 SQLite 的交互,本文將介紹 Room 數(shù)據(jù)庫升級的幾種場景和常見的處理方法,包括手動遷移和自動遷移的策略,需要的朋友可以參考下
    2024-09-09
  • Android使用ExpandableListView實現(xiàn)三層嵌套折疊菜單

    Android使用ExpandableListView實現(xiàn)三層嵌套折疊菜單

    這篇文章主要介紹了Android使用ExpandableListView實現(xiàn)三層嵌套折疊菜單,對布局感興趣的同學可以參考下
    2021-04-04
  • Android開發(fā)ProGuard使用技巧掌握

    Android開發(fā)ProGuard使用技巧掌握

    這篇文章主要為大家介紹了Android開發(fā)ProGuard使用技巧的掌握,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • Flutter?彈性布局基石flex算法flexible示例詳解

    Flutter?彈性布局基石flex算法flexible示例詳解

    這篇文章主要為大家介紹了Flutter?彈性布局基石flex算法flexible示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • Kotlin標準函數(shù)與靜態(tài)方法基礎知識詳解

    Kotlin標準函數(shù)與靜態(tài)方法基礎知識詳解

    Kotlin中的標準函數(shù)指的是Standard.kt文件中定義的函數(shù),任何Kotlin代碼都可以自由地調(diào)用所有的標準函數(shù)。例如let這個標準函數(shù),他的主要作用就是配合?.操作符來進行輔助判空處理
    2022-11-11
  • Android?Jetpack庫剖析之ViewModel組件篇

    Android?Jetpack庫剖析之ViewModel組件篇

    這篇文章主要介紹了Android?Jetpack架構(gòu)組件?ViewModel詳解,ViewModel類讓數(shù)據(jù)可在發(fā)生屏幕旋轉(zhuǎn)等配置更改后繼續(xù)存在,ViewModel類旨在以注重生命周期的方式存儲和管理界面相關(guān)的數(shù)據(jù)。感興趣可以來學習一下
    2022-07-07
  • Android加載圖片內(nèi)存溢出問題解決方法

    Android加載圖片內(nèi)存溢出問題解決方法

    這篇文章主要介紹了Android加載圖片內(nèi)存溢出問題解決方法,本文講解使用BitmapFactory.Options解決內(nèi)存溢出問題,需要的朋友可以參考下
    2015-06-06
  • Android仿手機通訊錄地址選擇功能

    Android仿手機通訊錄地址選擇功能

    這篇文章主要為大家詳細介紹了Android仿手機通訊錄地址選擇功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12

最新評論

柳河县| 邵阳市| 建宁县| 麦盖提县| 容城县| 鹰潭市| 肥城市| 宾阳县| 云林县| 方山县| 会宁县| 贵定县| 潢川县| 万盛区| 平武县| 兴义市| 龙口市| 新宾| 家居| 津南区| 噶尔县| 瓦房店市| 陆河县| 抚顺县| 连州市| 中宁县| 茌平县| 桓仁| 昌乐县| 县级市| 育儿| 浙江省| 扶沟县| 札达县| 同德县| 体育| 岑溪市| 台湾省| 芜湖县| 广元市| 巴青县|