Audiotrack播放PCM数据

复制代码
package com.example.audiotrack;

import android.media.AudioAttributes;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Bundle;

import com.google.android.material.snackbar.Snackbar;

import androidx.appcompat.app.AppCompatActivity;

import android.util.Log;
import android.view.View;

import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;

import com.example.audiotrack.databinding.ActivityMainBinding;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

public class MainActivity extends AppCompatActivity {

    private AppBarConfiguration appBarConfiguration;
    private ActivityMainBinding binding;
    private DataInputStream mInputStream;//输入流,用于读文件
    private AudioTrack mAudioTrack;
    AudioFormat audioFormat;
    private byte[] tmpBuf;//临时存储buffer
    private static final String TAG = "MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        setSupportActionBar(binding.toolbar);

        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
        appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
        NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
        //Create AudioTrack
        AudioAttributes attributes;
        audioFormat = new AudioFormat.Builder().build();
        //int bufSize = AudioTrack.getMinBufferSize(192000,AudioFormat.CHANNEL_OUT_5POINT1,AudioFormat.ENCODING_IEC61937);
        int bufSize = AudioTrack.getMinBufferSize(44100,AudioFormat.CHANNEL_IN_STEREO,AudioFormat.ENCODING_PCM_16BIT);//获取最小buffer的大小
        bufSize *=2;//对最小buff乘2
        Log.d(TAG,"getMinBufferSize*2 "+bufSize+" bytes");
        //mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 192000,AudioFormat.CHANNEL_OUT_5POINT1, AudioFormat.ENCODING_IEC61937,bufSize, AudioTrack.MODE_STREAM);
        创建一个44100hz,双通道,16位有符号格式的audiotrack
        mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100,AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT,bufSize, AudioTrack.MODE_STREAM);
        mAudioTrack.play();//启动AudioTrack
        tmpBuf = new byte[24576];
        File file = new File("/data/wangfeichuanq.pcm");//从文件读取pcm数据
        try {
            mInputStream = new DataInputStream(new FileInputStream(file));
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
        Log.d(TAG,"audioTrack state "+mAudioTrack.getState());

        binding.fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAnchorView(R.id.fab)
                        .setAction("Action", null).show();
                Runnable runPlay = new Runnable(){
                    @Override
                    public void run() {
                        int buflen;
                        while(true) {
                            try {
                                //每次循环读取24576字节的数据
                                buflen = mInputStream.read(tmpBuf, 0, 24576);
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                            //写入AudioTrack;
                            mAudioTrack.write(tmpBuf, 0, 24576);
                            //Log.d(TAG, "write");
                        }
                    }
                };
                runPlay.run();

            }
        });
    }

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
        return NavigationUI.navigateUp(navController, appBarConfiguration)
                || super.onSupportNavigateUp();
    }
}

一、以上是Activity的代码。

二、以下是androidstudio配置

复制代码
plugins {
    alias(libs.plugins.android.application)
}

android {
    namespace = "com.example.audiotrack"
    compileSdk = 34

    defaultConfig {
        applicationId = "com.example.audiotrack"
        minSdk = 29
        targetSdk = 34
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    buildFeatures {
        viewBinding = true
    }
}

dependencies {

    implementation(libs.appcompat)
    implementation(libs.material)
    implementation(libs.constraintlayout)
    implementation(libs.navigation.fragment)
    implementation(libs.navigation.ui)
    testImplementation(libs.junit)
    androidTestImplementation(libs.ext.junit)
    androidTestImplementation(libs.espresso.core)
}

三、点击邮件按钮

相关推荐
hansang_IR15 小时前
【题解】P4460 [CQOI2018] 解锁屏幕
c++·算法
ChampaignWolf16 小时前
在 SAP S/4HANA 内部基于 ICF Handler 从零实现 ABAP MCP Server:架构、代码与踩坑实录
c++·架构·sap·abap·mcp
尘客-追梦17 小时前
Day 01:插件化之前,先看清 ABI 这堵墙
开发语言·c++·qt
有点。17 小时前
*C++哈夫曼树与哈夫曼编码
java·c++·servlet
啦啦啦啦啦zzzz17 小时前
利用RAII机制进行日志的采集
linux·服务器·c++·网络编程·c++20
nLif18 小时前
基于GTK的简易MFC对话框兼容层 -- MfcToGTK
linux·c++·mfc·gtk
工具派19 小时前
口播视频怎么自动剪掉冷场?视频静音删除的阈值实测
ffmpeg·音视频·视频
小小、码农20 小时前
C++11右值引用与移动语义 —— 从拷贝资源到转移资源
开发语言·网络·c++·网络协议
❀͜͡傀儡师21 小时前
移动端 360° 商品展示方案:从 20MB 雪碧图到 800KB 丝滑视频
ffmpeg·webgl·sprite
charlie1145141911 天前
C++ 的新标准容器:flat_map、inplace_vector 与 mdspan
开发语言·c++·开源项目