用c语言实调用电脑麦克风,录制一段音频
时间: 2023-06-02 18:02:14 浏览: 220
C语言使用libZPlay录制声音并写到文件的方法
由于语音识别需要用到麦克风录制音频,以下提供一份简单的C语言代码用于录制音频。
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <alsa/asoundlib.h>
#define PCM_DEVICE "default"
int main(int argc, char **argv)
{
int rc;
snd_pcm_t *pcm_handle;
snd_pcm_hw_params_t *params;
unsigned int sample_rate = 44100;
unsigned int channels = 2;
unsigned int buffer_time = 500000; // 500ms
unsigned int period_time = 100000; // 100ms
unsigned int buffer_size, period_size;
char *buffer;
int fd;
fd = open("output.raw", O_CREAT | O_WRONLY | O_TRUNC, 0644);
if (fd == -1) {
fprintf(stderr, "Error: open() failed: %s\n", strerror(errno));
return -1;
}
rc = snd_pcm_open(&pcm_handle, PCM_DEVICE, SND_PCM_STREAM_CAPTURE, 0);
if (rc < 0) {
fprintf(stderr, "Error: snd_pcm_open() failed: %s\n", snd_strerror(rc));
return -1;
}
snd_pcm_hw_params_alloca(¶ms);
rc = snd_pcm_hw_params_any(pcm_handle, params);
if (rc < 0) {
fprintf(stderr, "Error: snd_pcm_hw_params_any() failed: %s\n", snd_strerror(rc));
return -1;
}
rc = snd_pcm_hw_params_set_access(pcm_handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
if (rc < 0) {
fprintf(stderr, "Error: snd_pcm_hw_params_set_access() failed: %s\n", snd_strerror(rc));
return -1;
}
rc = snd_pcm_hw_params_set_format(pcm_handle, params, SND_PCM_FORMAT_S16_LE);
if (rc < 0) {
fprintf(stderr, "Error: snd_pcm_hw_params_set_format() failed: %s\n", snd_strerror(rc));
return -1;
}
rc = snd_pcm_hw_params_set_channels(pcm_handle, params, channels);
if (rc < 0) {
fprintf(stderr, "Error: snd_pcm_hw_params_set_channels() failed: %s\n", snd_strerror(rc));
return -1;
}
rc = snd_pcm_hw_params_set_rate_near(pcm_handle, params, &sample_rate, 0);
if (rc < 0) {
fprintf(stderr, "Error: snd_pcm_hw_params_set_rate_near() failed: %s\n", snd_strerror(rc));
return -1;
}
rc = snd_pcm_hw_params_set_buffer_time_near(pcm_handle, params, &buffer_time, 0);
if (rc < 0) {
fprintf(stderr, "Error: snd_pcm_hw_params_set_buffer_time_near() failed: %s\n", snd_strerror(rc));
return -1;
}
rc = snd_pcm_hw_params_set_period_time_near(pcm_handle, params, &period_time, 0);
if (rc < 0) {
fprintf(stderr, "Error: snd_pcm_hw_params_set_period_time_near() failed: %s\n", snd_strerror(rc));
return -1;
}
rc = snd_pcm_hw_params(pcm_handle, params);
if (rc < 0) {
fprintf(stderr, "Error: snd_pcm_hw_params() failed: %s\n", snd_strerror(rc));
return -1;
}
snd_pcm_hw_params_get_buffer_size(params, &buffer_size);
snd_pcm_hw_params_get_period_size(params, &period_size, NULL);
buffer = malloc(buffer_size);
if (!buffer) {
fprintf(stderr, "Error: malloc() failed: %s\n", strerror(errno));
return -1;
}
while (1) {
rc = snd_pcm_readi(pcm_handle, buffer, period_size);
if (rc == -EPIPE) {
fprintf(stderr, "Error: snd_pcm_readi() failed: %s\n", snd_strerror(rc));
snd_pcm_prepare(pcm_handle);
} else if (rc < 0) {
fprintf(stderr, "Error: snd_pcm_readi() failed: %s\n", snd_strerror(rc));
} else if (rc != period_size) {
fprintf(stderr, "Error: short read, expected %d frames, got %d\n", period_size, rc);
} else {
write(fd, buffer, buffer_size);
}
}
free(buffer);
close(fd);
snd_pcm_close(pcm_handle);
return 0;
}
```
这段代码使用 ALSA(Advanced Linux Sound Architecture)库来调用电脑的麦克风进行音频录制。录制的音频数据将保存在一个名为 `output.raw` 的文件中。录制的音频数据格式为 16 位有符号整数的 PCM 格式,采样率为 44100 Hz,声道数为 2(立体声)。录制的音频数据以周期(period)的方式进行读取和保存,每个周期的长度为 100 毫秒,缓冲区的长度为 500 毫秒。由于录制的音频数据是以二进制形式保存到文件中的,因此在使用之前需要进行解码。这里提供一个简单的 Python 代码用于解码:
```python
import numpy as np
with open('output.raw', 'rb') as f:
data = f.read()
samples = np.frombuffer(data, dtype=np.int16)
```
这段代码使用 NumPy 库来将二进制数据解码为整数数组。解码后的数组 `samples` 中每个元素代表一个采样值,采样值的范围为 [-32768, 32767],表示声音的振幅。如果要将采样值转换为音频信号的幅度,可以使用下面的代码:
```python
amplitude = samples / 32768.0
```
这段代码将采样值除以 32768,得到的结果即为音频信号的幅度,取值范围为 [-1.0, 1.0]。如果要将音频信号保存为 WAV 格式,可以使用下面的代码:
```python
import wave
with wave.open('output.wav', 'wb') as f:
f.setnchannels(2)
f.setsampwidth(2)
f.setframerate(44100)
f.writeframes(samples.tobytes())
```
这段代码使用 Python 标准库中的 wave 模块将音频信号保存为 WAV 格式。保存的 WAV 文件中采样率为 44100 Hz,声道数为 2(立体声),采样深度为 16 位。
阅读全文