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)
}

三、点击邮件按钮

相关推荐
杨忆28 分钟前
构建自己的开发工作台MFC
数据库·c++·mfc
wadesir41 分钟前
C++非对称加密实战指南(从零开始掌握RSA加密算法)
开发语言·c++
七禾页丫1 小时前
面试记录12 软件(c++)工程师
c++·面试·职场和发展
酷酷的佳2 小时前
C语言--数组作为函数参数
c++
爱装代码的小瓶子2 小时前
【c++进阶】从C++98到C++11的奇妙旅程(故事科普版)
开发语言·c++
superman超哥3 小时前
仓颉类型别名的使用方法深度解析
c语言·开发语言·c++·python·仓颉
superman超哥3 小时前
仓颉GC调优参数深度解析
c语言·开发语言·c++·python·仓颉
誰能久伴不乏3 小时前
Linux `epoll` 学习笔记:从原理到正确写法(含 ET 经典坑总结)
linux·服务器·网络·c++·ubuntu
(❁´◡`❁)Jimmy(❁´◡`❁)4 小时前
【算法】 二分图理论知识和判断方法
c++·算法
im_AMBER4 小时前
Leetcode 85 【滑动窗口(不定长)】最多 K 个重复元素的最长子数组
c++·笔记·学习·算法·leetcode·哈希算法