RK3399使用ICS-43432音频录制Codec芯片
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RK3399使用ICS-43432音频录制Codec芯片相关的知识,希望对你有一定的参考价值。
参考技术A官网 ICS-43432
I2S总线主要有3个信号:串行时钟BCLK、帧时钟LRCK、串行数据SDATA;有时为了使系统间能够更好地同步,还需要另外传输一个信号MCLK,称为主时钟,也叫系统时钟(Sys Clock)。
对应SSI接口
I2S format: left-justified, right-justified, and PCM modes.
逻辑分析仪实测时序图
(LF:默认拉低,所以使用左声道录音,右声道没有数据)
数字音频的质量取决于采样频率和量化位数这两个参数,为了保真,在时间变化方向上取样点尽量密,取样率要高;在幅度取值上尽量细,量化比特率要高,直接的结果就是存储容量及传输信道容量要求的压力大;
音频信号的传输率= 取样频率 × 样本的量化比特数 × 通道数。
使用 AudioRecord 录制音频
【中文标题】使用 AudioRecord 录制音频【英文标题】:Audio recording using AudioRecord 【发布时间】:2015-01-08 18:34:37 【问题描述】:我决定使用AudioRecord
而不是MediaRecorder
录制音频,以达到最高质量。问题是,该应用程序由于某种原因无法运行。有2个按钮:录制和播放,录制用于开始和停止录制(使用新线程),播放应该使用MediaPlayer
播放文件。
代码:
public class MyActivity extends Activity
AudioRecord recorder = null;
int SAMPLE_RATE = 44100;
int ENCODING = AudioFormat.ENCODING_PCM_16BIT;
int SOURCE = MediaRecorder.AudioSource.MIC;
int CONFIG = AudioFormat.CHANNEL_IN_MONO;
int BUFFER_SIZE;
boolean isRecording = false;
boolean isPlaying = false;
String currentFileDir;
byte[] b;
File file;
OutputStream FOS;
int count =0;
MediaPlayer mediaPlayer;
Thread recordThread;
private Button recordButton;
private Button playButton;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
currentFileDir = getFilesDir().getAbsolutePath() + "Record.pcm";
recordButton = (Button)findViewById(R.id.RecordButton);
recordButton.setOnClickListener(new MyOCL());
playButton = (Button)findViewById(R.id.PlayButton);
playButton.setOnClickListener(new MyOCL());
protected void record()
file = new File(currentFileDir);
BUFFER_SIZE = AudioRecord.getMinBufferSize(SAMPLE_RATE, CONFIG, ENCODING);
recorder = new AudioRecord(SOURCE, SAMPLE_RATE, CONFIG, ENCODING, BUFFER_SIZE);
isRecording = true;
b = new byte[BUFFER_SIZE];
try
FOS = new FileOutputStream(file);
catch (Exception e)Log.e("Open FOS", "new failed");
while (isRecording)
recorder.read(b, 0, BUFFER_SIZE);
try
FOS.write(b, count * BUFFER_SIZE, BUFFER_SIZE);
count++;
catch (Exception e)Log.e("write FOS", "write failed");
try
FOS.close();
catch (Exception e)Log.e("close FOS", "close failed");
private class MyOCL implements View.OnClickListener
@Override
public void onClick(View view)
switch(view.getId())
case R.id.PlayButton:
if(isPlaying == false)
playButton.setText("Stop Playing");
setPlaying();
mediaPlayer.start();
else
playButton.setText("Start Playing");
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer.reset();
break;
case R.id.RecordButton:
if(isRecording == false)
recordThread = new Thread(new Runnable()
@Override
public void run()
record();
);
recordThread.start();
recordButton.setText("Stop Recording");
else
recordButton.setText("Start recording");
isRecording = false;
break;
protected void setPlaying()
try
mediaPlayer = new MediaPlayer();
mediaPlayer.reset();
mediaPlayer.setDataSource(currentFileDir);
mediaPlayer.prepare();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
//mediaPlayer.start();
catch (Exception e)
Log.e("Play initialize", "Can't call prepare function" + e.getMessage());
@Override
public boolean onCreateOptionsMenu(Menu menu)
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.my, menu);
return true;
@Override
public boolean onOptionsItemSelected(MenuItem item)
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings)
return true;
return super.onOptionsItemSelected(item);
【问题讨论】:
您应该提供有关“应用程序无法正常工作”的详细信息 由于某种原因,该文件没有被保存。稍后我会添加一些日志,但问题在于似乎无限的 while(isRecording) 循环。 【参考方案1】:这是我的代码,对我有用:
public class MainActivity extends Activity
AudioRecord record = null;
AudioTrack track = null;
boolean isRecording;
int sampleRate = 44100;
Button startRecord, stopRecord, playRecord = null;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setVolumeControlStream(AudioManager.MODE_IN_COMMUNICATION);
startRecord = (Button) findViewById(R.id.start_recording);
stopRecord = (Button) findViewById(R.id.stop_recording);
playRecord = (Button) findViewById(R.id.play_recording);
startRecord.setOnClickListener(new StartRecordListener());
stopRecord.setOnClickListener(new StopRecordListener());
playRecord.setOnClickListener(new PlayRecordListener());
stopRecord.setEnabled(false);
private void startRecord()
File recordFile = new File(Environment.getExternalStorageDirectory(), "Record.pcm");
try
recordFile.createNewFile();
OutputStream outputStream = new FileOutputStream(recordFile);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream);
int minBufferSize = AudioRecord.getMinBufferSize(sampleRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
short[] audioData = new short[minBufferSize];
record = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT,
minBufferSize);
record.startRecording();
while (isRecording)
int numberOfShort = record.read(audioData, 0, minBufferSize);
for (int i = 0; i < numberOfShort; i++)
dataOutputStream.writeShort(audioData[i]);
record.stop();
dataOutputStream.close();
catch (IOException e)
e.printStackTrace();
public void playRecord()
File recordFile = new File(Environment.getExternalStorageDirectory(), "Record.pcm");
int shortSizeInBytes = Short.SIZE / Byte.SIZE;
int bufferSizeInBytes = (int) (recordFile.length() / shortSizeInBytes);
short[] audioData = new short[bufferSizeInBytes];
try
InputStream inputStream = new FileInputStream(recordFile);
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
DataInputStream dataInputStream = new DataInputStream(bufferedInputStream);
int i = 0;
while (dataInputStream.available() > 0)
audioData[i] = dataInputStream.readShort();
i++;
dataInputStream.close();
track = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT,
bufferSizeInBytes, AudioTrack.MODE_STREAM);
track.play();
track.write(audioData, 0, bufferSizeInBytes);
catch (FileNotFoundException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
public class StartRecordListener implements View.OnClickListener
@Override
public void onClick(View v)
Thread recordThread = new Thread(new Runnable()
@Override
public void run()
isRecording = true;
MainActivity.this.startRecord();
);
recordThread.start();
startRecord.setEnabled(false);
stopRecord.setEnabled(true);
public class StopRecordListener implements View.OnClickListener
@Override
public void onClick(View v)
isRecording = false;
startRecord.setEnabled(true);
stopRecord.setEnabled(false);
public class PlayRecordListener implements View.OnClickListener
@Override
public void onClick(View v)
MainActivity.this.playRecord();
XML 布局包含 3 个具有以下 ID 的按钮:start_recording、stop_recording、play_recording
并添加以下权限:
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
祝你好运,我希望你没问题,我在上面的代码中使用了 3 个按钮。
【讨论】:
非常感谢!我来看看代码。我看到你使用了短裤并将它们解析为字节......这是为什么呢? 您可以将 record.read() 给出的字节直接存储到您的输出流中。 那么有什么解释为什么当我用 OutputStream(而不是中间的缓冲区)初始化 DataOutputStream 时,音频要快得多? (我认为比现实快 2 倍) 对不起,我不明白你的意思。您可以尝试上面的示例并对其进行测量。 我试过了,效果很好,我只是想知道是什么原因造成的以上是关于RK3399使用ICS-43432音频录制Codec芯片的主要内容,如果未能解决你的问题,请参考以下文章
RK3588平台开发系列讲解(AUDIO篇)基于alsa api的音频播放/录制流程
RK3588平台开发系列讲解(AUDIO篇)基于alsa api的音频播放/录制流程
RK3399平台开发系列讲解(电源管理篇)11.7PM callback
Rock Pi开发笔记(三):Rock Pi 4B plus(基于瑞星微RK3399)板子硬件资源介绍