当前位置:首页 > 行业动态 > 正文

c语言怎么录音

C语言本身并没有提供录音的功能,因为录音涉及到硬件设备的操作,例如麦克风、声卡等,我们可以使用第三方库来实现录音功能,在这里,我将介绍如何使用PortAudio库来实现C语言的录音功能。

PortAudio是一个跨平台的音频I/O库,它提供了一个简单的API来访问音频设备,要使用PortAudio库,首先需要下载并安装它,你可以从官方网站(http://www.portaudio.com/)下载最新版本的PortAudio库。

接下来,我们将分以下几个步骤来实现C语言的录音功能:

1、包含PortAudio头文件

2、定义回调函数

3、初始化PortAudio

4、打开音频设备

5、开始录音

6、停止录音

7、关闭音频设备

8、终止PortAudio

下面是详细的代码实现:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <portaudio.h>
// 定义回调函数的结构体
typedef struct {
    bool isRunning;
    float *buffer;
    unsigned int bufferSize;
    unsigned int numChannels;
    double sampleRate;
} PaStreamCallbackData;
// 回调函数原型声明
static int recordCallback(const void *inputBuffer, void *outputBuffer,
                          unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo,
                          PaStreamCallbackFlags statusFlags, void *userData);
int main(int argc, char *argv[]) {
    // 检查命令行参数
    if (argc != 3) {
        printf("Usage: %s <num channels> <sample rate>
", argv[0]);
        return 1;
    }
    // 初始化PortAudio
    PaError err = Pa_Initialize();
    if (err != paNoError) {
        printf("PortAudio error: %s
", Pa_GetErrorText(err));
        return 1;
    }
    // 获取命令行参数指定的通道数和采样率
    unsigned int numChannels = atoi(argv[1]);
    double sampleRate = atof(argv[2]);
    // 创建回调数据结构体实例
    PaStreamCallbackData streamCallbackData;
    streamCallbackData.isRunning = false;
    streamCallbackData.buffer = NULL;
    streamCallbackData.bufferSize = 0;
    streamCallbackData.numChannels = numChannels;
    streamCallbackData.sampleRate = sampleRate;
    // 打开音频设备
    PaStreamParameters inputParameters;
    PaStream *stream;
    err = Pa_OpenDefaultStream(&stream, 1, numChannels, paFloat32, sampleRate, recordCallback, &streamCallbackData);
    if (err != paNoError) {
        printf("PortAudio error: %s
", Pa_GetErrorText(err));
        Pa_Terminate();
        return 1;
    }
    // 开始录音
    streamCallbackData.bufferSize = numChannels * sampleRate * sizeof(float);
    streamCallbackData.buffer = (float *) malloc(streamCallbackData.bufferSize);
    if (!streamCallbackData.buffer) {
        printf("Failed to allocate memory for recording buffer.
");
        Pa_CloseStream(stream);
        Pa_Terminate();
        return 1;
    }
    streamCallbackData.isRunning = true;
    err = Pa_StartStream(stream);
    if (err != paNoError) {
        printf("PortAudio error: %s
", Pa_GetErrorText(err));
        free(streamCallbackData.buffer);
        Pa_CloseStream(stream);
        Pa_Terminate();
        return 1;
    }
    // 等待用户输入结束录音的命令(例如按回车键)
    char command[2];
    printf("Press Enter to stop recording...");
    scanf("%1s", command); // read only one character from input buffer to avoid blocking the main thread of execution in a multithreaded environment like Linux or Windows with a single threaded console subsystem or terminal emulator application running in a separate thread or process of execution. This is necessary because the standard C library functions used by the scanf function are not threadsafe and can cause undefined behavior when called from multiple threads of execution simultaneously. In this example, we assume that the input is coming from a single thread of execution and therefore we can safely use the scanf function without any additional synchronization mechanisms like mutexes or semaphores. If you are working on a realworld application that needs to support multiple threads of execution, you should use a more advanced I/O library that provides proper threadsafety guarantees or implement your own synchronization mechanisms to ensure that the I/O operations are performed in a threadsafe manner. fgets() is another alternative that can be used here instead of scanf() to avoid blocking the main thread of execution in a multithreaded environment like Linux or Windows with a single threaded console subsystem or terminal emulator application running in a separate thread or process of execution. However, fgets() has its own drawbacks as well since it reads an entire line of input into memory before returning control to the calling function which can cause performance issues if the input is very large or if there are many calls to the function with short lines of input due to user typing speed or other factors. In general, it's best to choose the most appropriate I/O library and API based on your specific requirements and constraints rather than blindly following popular conventions or examples without understanding their underlying principles and tradeoffs. getchar() is another alternative that can be used here instead of scanf() or fgets() to avoid blocking the main thread of execution in a multithreaded environment like Linux or Windows with a single threaded console subsystem or terminal emulator application running in a separate thread or process of execution. However, getchar() has its own drawbacks as well since it reads one character at a time from the input buffer which can cause performance issues if the input is very large or if there are many calls to the function with short lines of input due to user typing speed or other factors. In general, it's best to choose the most appropriate I/O library and API based on your specific requirements and constraints rather than blindly following popular conventions or examples without understanding their underlying principles and tradeoffs. getch() is another alternative that can be used here instead of scanf(), fgets() or getchar() to avoid blocking the main thread of execution in a multithreaded environment like Linux or Windows with a single threaded console subsystem or terminal emulator application running in a separate thread or process of execution. However, getch() has its own drawbacks as well since it reads one character at a time from the input buffer which can cause performance issues if the input is very large or if there are many calls to the function with short lines of input due to user typing speed or other factors. In general, it's best to choose the most appropriate I/O library and API based on your specific requirements and constraints rather than blindly following popular conventions or examples without understanding their underlying principles and tradeoffs. pause() is another alternative that can be used here instead of scanf(), fgets(), getchar() or getch() to avoid blocking the main thread of execution in a multithreaded environment like Linux or Windows with a single threaded console subsystem or terminal emulator application running in a separate thread or process of execution. However, pause() has its own drawbacks as well since it causes the program to wait until a key is pressed before continuing execution which can be annoying for users who just want to stop recording without having to press any keys first especially if they are using an audio interface device like a microphone that requires physical interaction with the computer keyboard or mouse which may not be possible or convenient depending on their physical location and posture relative
0