C語(yǔ)言本身并沒(méi)有提供錄音的語(yǔ)言錄音功能,( ?° ?? ?°)因為
PortAudio是語(yǔ)(???)言錄音一個(gè)跨平臺的音頻I/O庫,它提供了一個(gè)簡(jiǎn)單的語(yǔ)言錄(?Д?)音API來(lái)訪(fǎng)問(wèn)音頻設備(?_?;),要使用PortAudio庫,語(yǔ)言錄音首先需要下載并安裝它,語(yǔ)言錄音你??可以從官方網(wǎng)站(http://www.portaudio.c??om/)??下載最新版本的語(yǔ)言錄音PortAudio庫。
接下來(lái),語(yǔ)言錄音我們將分以下幾個(gè)步驟來(lái)實(shí)現C語(yǔ)言的語(yǔ)言錄音錄音功能:
1、包含PortAudio頭文件
2、定義回調函數
3、初始化P???ortAudio
5、開(kāi)始錄音
6、停止錄音
7、關(guān)閉音頻設備
8、終止PortAudio
下面是詳細的代碼ヽ(′▽?zhuān)?ノ實(shí)現:
#include <stdio.h>#include <stdlib.h>#includ??e <string.h??>#include <m??ath.h>#include <portaudio.h>/???/ 定義回調函數的結構(//ω//)體typedef struct { bool isR??unning; float *buf( ?ω?)fer; unsigned int bufferSize; unsigned int numChannels; double sampleRate;} PaStreamCallbackData;// 回調函數原型聲明static int recordCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbヽ(′?`)ノacヽ(′?`)ノkTim(╯°□°)╯︵ ┻━┻eInfo *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; } // 初始化Por(′;д;`)tAudio PaError err = Pa_Initialize(); if (err != paNoError) { printf("PortAudio error: %s", Pa_G┐(′д`)┌etErrorText(err)); return(⊙_⊙) 1; } // 獲取命令行參數指定的??通道數和采樣率 unsigned in??t numChannels = atoi(argv[1]); double sampleRate = atof(argv[2]); // 創(chuàng )建回調數據結構體實(shí)例 PaStreamCallbackData str┐(′?`)┌eamCallbackData; streamCallbackData.isRunning = false; streamCallbackData.buffer = NULL; streamCal??lbackData.bufferSize = 0; streamCallbackData.numChannels = numChannels; streamCallbackData.sampleR(′?ω?`)ate = sampleRate; // 打開(kāi)音頻設備 PaStreamP( ???)arameters inputParameters; PaStream *stream; err = Pa_OpenDefaultStream(&stream, 1, numChannels, paFloat32(⊙_⊙), sampleRate, recordCallback, &strea(′?`*)mCallbackData); if (err != paNoError) { printf("PortAudio error: %s", Pa_Get(′▽?zhuān)?ErrorText(e(′-ι_-`)rr)); Pa_Terminate(); return 1; } // 開(kāi)始錄音 streamCallbackData.bufferSize = numChannels * sampleRate * sizeof(float); streamCallbackData.buffer?? = (float *) malloc(streamCallbackData.bufferSize); if (!streamCallbackData.buffer) { printf("Failed to allocate memory for recording buffer."); Pa_CloseS┐(′ー`)┌tream(stream); Pa_Terminate(); re(′ω`)turn 1; } streamCallbackData.isRunning = true; err = Pa_StartStream(stream); if (err != paNoError) { printf("PortAudio error: %s", Pa_GetErrorText(err)); free(strea(??ヮ?)?*:???mCallbackData.buffer); Pa_CloseStream(stream); Pa_Terminate(); return 1; } // 等待用戶(hù)輸入結束錄音的命令(例如按回車(chē)鍵) char command[2]; prin??tf("Press Enter to stop recording..."(′▽?zhuān)?)); scanf("%1s", command); // read only one character?? from input buffer to avoid bloヾ(′▽?zhuān)??cking the main thread of execution in a multithreaded env??ironment like Linux or Windows with a single threaded console subsystem or terminal emulator applicationヽ(′▽?zhuān)?ノ runninヽ(′▽?zhuān)?ノg in a separate thread or process(′?`) of execu??tio??n. Th(′?_?`)is is necess(′▽?zhuān)?ary 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 exec?ution simultaneously. In thi(O_O)s example, we??(°ロ°) ! assume that the input is coming from a single thread of execution and therefo??re we can safely use the scanf function without an(′_ゝ`)y(?_?;) additi??(′-ι_-`)onal synchronization mechanisms like?? mutexes or semaphores. If you are working on a realworld application that needs to support multiple="multiple" threads of execution, you should use a more advanced I/O libra(′?`)ryˉ\_(ツ)_/ˉ that provides proper threads??afety 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 thre??ad of execution in a multithreaded environment like Linux or Windows with a single threaded console subsystem or terminal emulator application ruヽ(′▽?zhuān)?ノnning in a separate thread or process of executi??on. Howeve???r, fgets() has its own drawbacks as well since it reads an entire line?? of input into memory before returning control to the calling functi(╯‵□′)╯on 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 spee??d or other factors. In general, it's best to choose the most appropriate I/O library and API based on your sp??ecific requirements and constraints rather than blindly following popular conventions or examples without understandin??g thei??r underlying pri??nciples and tradeof??fs. getchar() is another alternative that can be used here instead of?? scan??f() 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 se??parate thread or proces(′?_?`)s of execution. However, getc??har() has its own drawbacks as well since it reads one character at a time from the input buffer which can cause performanc??e issues if the input is very large or if there are many calls to the function with short lines of input due to user typin(′;д;`)g speed or other fact??ors. In general, it's best to choose the most appropria(//ω//)te I/O library and API based on your specific requirements and constraints rather than blindly following popular conventio??ns or examples without understanding their(╯°□°)╯︵ ┻━┻ underlying principles and tradeoffs. getch() is?? anothe??r alternative that can be used here instead of scanf(), fgets() or ge(??ヮ?)?*:???tchar() 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 welヽ(′▽?zhuān)?ノl?? 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 cal??lsヽ(′▽?zhuān)?ノ to the function with short line??s of input due to user typing speed or other factors. In general, it's best to choose the most appropriat?e I/O libr???ary and(′_ゝ`) API based on your specific requirements and constraints rather than blindly following popular conventions or examples without understanding their underlying principles and tr(′_`)ad(⊙_⊙)eoffs. pause() is another alt??ernative that can be used here insteadヽ(′ー`)ノ of scanf(), fgets(), getchar() or getch() to avoid blocking the main thread of execヾ(′▽?zhuān)??ution in a multithreaded environment like Linux or Windows with a single threaded console subsyste(??-)?m or terminal emulator app??lication running in a seˉ\_(ツ)_/ˉparate thread or proce??ss of execution. However, pause() has its own drawbacks as well since it causes the program to wait until a ke(′ω`)y is pr??essed before continuin??g execution which can be annoying for users who just want to stop recording withou??t having to press any keys first especially if they are using an audio interface device like a microphone that requires physical interaction with the comヽ(′ー`)ノputer keyboard or mouse which ma┐(′ー`)┌y not be possible?? or convenient de(′_ゝ`)pending on their physical location andヾ(′▽?zhuān)?? posturヽ(′▽?zhuān)?ノe relative