欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++使用alsa庫(kù)實(shí)現(xiàn)播放聲音文件

 更新時(shí)間:2024年04月24日 08:38:01   作者:洛克希德馬丁  
這篇文章主要為大家詳細(xì)介紹了Linux系統(tǒng)上C++如何使用alsa庫(kù)播放聲音文件,文中示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

前言

平常讀麥克風(fēng)的場(chǎng)景居多,有時(shí)候也需要播放一個(gè)聲音文件,這里就介紹怎么處理。

一、命令行

1.ffmpeg

ffmpeg -i <filename.wav> -f alsa default

2.aplay

aplay -i <filename.wav>

如果提示找不到aplay就安裝工具:

sudo apt install alsa-utils

二、代碼實(shí)現(xiàn)

main.cpp

#include <alsa/asoundlib.h>
#include <iostream>
#include <fstream>

#define PCM_DEVICE "default"http://默認(rèn)的播放設(shè)備,你可以在settings里面調(diào)換

int main(int argc, char *argv[]) {
    const char *audioFilename = "../wakeup.wav";

    // 配置ALSA參數(shù)
    snd_pcm_t *pcmHandle;
    if (snd_pcm_open(&pcmHandle, PCM_DEVICE, SND_PCM_STREAM_PLAYBACK, 0) < 0) {
        std::cerr << "Error: Failed to open PCM device" << std::endl;
        return 1;
    }

    snd_pcm_hw_params_t *params;
    snd_pcm_hw_params_alloca(&params);
    snd_pcm_hw_params_any(pcmHandle, params);
    snd_pcm_hw_params_set_access(pcmHandle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
    snd_pcm_hw_params_set_format(pcmHandle, params, SND_PCM_FORMAT_S16_LE);
    snd_pcm_hw_params_set_channels(pcmHandle, params, 2);
    unsigned int sampleRate = 48000;
    snd_pcm_hw_params_set_rate_near(pcmHandle, params, &sampleRate, nullptr);
    snd_pcm_uframes_t bufferSize = 512;
    snd_pcm_hw_params_set_buffer_size_near(pcmHandle, params, &bufferSize);
    snd_pcm_hw_params(pcmHandle, params);

    std::ifstream ifs("../wakeup.wav");
    if (ifs.is_open()) {
        std::string data;
        size_t size;
        char buffer[8192];
        while ((size = ifs.readsome(buffer, 8192)) > 0) {
            data.append(buffer, size);
        }
        snd_pcm_sframes_t err = snd_pcm_writei(pcmHandle, (const void *) data.c_str(),
                                               data.size()); 
        if (err < 0) {
            std::cerr << "Error: Failed to write PCM device" << std::endl;
        }
        ifs.close();
    }

    // 關(guān)閉PCM設(shè)備和文件
    snd_pcm_close(pcmHandle);
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(write_speaker)

set(CMAKE_CXX_STANDARD 11)

add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} asound)

三、知識(shí)補(bǔ)充

C++使用Alsa采集linux音頻

1、運(yùn)行時(shí)前先裝庫(kù),sudo apt-get install libalsa

2遍tab自動(dòng)提示出庫(kù)文件,選擇庫(kù),alsa-ocaml-dev,最終的命令行為:sudo apt-get install libalsa-ocaml-dev

2、編譯執(zhí)行腳本,gcc -o main main.c -lasound;

3、執(zhí)行 ./main

以下是代碼

#include <stdlib.h>
#include <stdio.h>
#include <alsa/asoundlib.h>
#include <signal.h>
static int recording;

void stop_record(int param)
{
recording = 0;
}
void InitCapture(snd_pcm_t ** handle,snd_pcm_hw_params_t ** params,snd_pcm_uframes_t* frames,char ** buffer,int* size)
{
int ret;
unsigned int val;
int dir;
//打開(kāi)設(shè)備
ret = snd_pcm_open(handle, “default”, SND_PCM_STREAM_CAPTURE, 0);
printf(“after open file\n”);
if (ret < 0)
{
fprintf(stderr, “unable to open device:%s\n”, snd_strerror(ret));
exit(1);
}
//分配一個(gè)硬件參數(shù)結(jié)構(gòu)體
snd_pcm_hw_params_alloca(params);

//使用默認(rèn)參數(shù)
snd_pcm_hw_params_any(*handle, *params);

//翻譯
    snd_pcm_hw_params_set_access(*handle, *params, SND_PCM_ACCESS_RW_INTERLEAVED);

//S16小端
snd_pcm_hw_params_set_format(*handle, *params, SND_PCM_FORMAT_S16_LE);

//雙通道,立體聲
snd_pcm_hw_params_set_channels(*handle, *params, 2);

//采樣率
val = 44100;
snd_pcm_hw_params_set_rate_near(*handle, *params,&val,&dir);

*frames = 32;
snd_pcm_hw_params_set_period_size_near(*handle, *params,frames,&dir);

//參數(shù)生效
ret = snd_pcm_hw_params(*handle, *params);
if (ret<0)
{
	fprintf(stderr, "unable to set hw parameters:%s\n", snd_strerror(ret));
		exit(1);
}
//得到一個(gè)周期的數(shù)據(jù)大小
snd_pcm_hw_params_get_period_size(*params, frames, &dir);

//16位雙通道,16位為2字節(jié),2字節(jié)*2通道=4,假如frames=1024,則size是1024*4 = 4096
*size = *frames * 4;
*buffer = (char*)malloc(*size); 

//設(shè)置一個(gè)周期的時(shí)間長(zhǎng)度
snd_pcm_hw_params_get_period_time(*params, &val, &dir);
}

void CaptureAudio(snd_pcm_t ** handle,snd_pcm_uframes_t* frames,char ** buffer,int* size,FILE ** pFile)
{
int ret;

recording = 1;
while (recording)
{
	ret = snd_pcm_readi(*handle, *buffer,*frames);
	if (ret == -EPIPE )
	{
		fprintf(stderr, "overrun occurred\n");
		snd_pcm_prepare(*handle);
	}
	else if (ret < 0)
	{
		fprintf(stderr, "error from read\n");
		snd_strerror(ret);
	}
	else if (ret != (int)(*frames))
	{
		fprintf(stderr, "short read %d frames\n",ret);
	}
	printf("write to file......%d\n", *size);
	//寫(xiě)到標(biāo)準(zhǔn)輸出中去
	ret = fwrite(*buffer, sizeof(char), *size, *pFile);
	if (ret != *size)
	{
		fprintf(stderr, "short write :write %d bytes\n", ret);
	}
	if (signal(SIGINT, stop_record)==SIG_ERR)
	{
		fprintf(stderr, "signal failed\n");
	}
}
}

void CloseCaptureDevice(FILE ** pFile,snd_pcm_t ** handle,char ** buffer)
{
printf(“write file exit\n”);
snd_pcm_drain(*handle);
snd_pcm_close(*handle);
free(*buffer);
fclose(*pFile);
}

int main()
{
FILE * pFile;
pFile = fopen(“test.pcm”, “wb”);
int size;
//給文件操作分配一個(gè)句柄
snd_pcm_t * handle;
//硬件參數(shù)
snd_pcm_hw_params_t * params;
//
snd_pcm_uframes_t frames;
char * buffer;
printf(“before open file\n”);
InitCapture(&handle,&params,&frames,&buffer,&size);
CaptureAudio(&handle,&frames,&buffer,&size,&pFile);
CloseCaptureDevice(&pFile,&handle,&buffer);
printf(“write file exit\n”);

return 0;
}

到此這篇關(guān)于C++使用alsa庫(kù)實(shí)現(xiàn)播放聲音文件的文章就介紹到這了,更多相關(guān)C++ alsa播放聲音文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言中長(zhǎng)度為0的數(shù)組詳解

    C語(yǔ)言中長(zhǎng)度為0的數(shù)組詳解

    這篇文章主要給大家介紹了關(guān)于C語(yǔ)言中長(zhǎng)度為0的數(shù)組,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-10-10
  • C++ 類(lèi)訪問(wèn)控制的條件總結(jié)

    C++ 類(lèi)訪問(wèn)控制的條件總結(jié)

    這篇文章主要介紹了C++ 類(lèi)訪問(wèn)控制的條件總結(jié)的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • C++20中的span容器及用法小結(jié)

    C++20中的span容器及用法小結(jié)

    std::span 是一個(gè)非常實(shí)用的工具,可以方便地對(duì)數(shù)據(jù)進(jìn)行訪問(wèn)和處理,同時(shí)也可以提高代碼的可讀性、可維護(hù)性和安全性,這篇文章主要介紹了C++20中的span容器,需要的朋友可以參考下
    2023-03-03
  • C語(yǔ)言動(dòng)態(tài)分配二維字符串?dāng)?shù)組的方法

    C語(yǔ)言動(dòng)態(tài)分配二維字符串?dāng)?shù)組的方法

    小編最近忙里偷閑,給大家整理一份教程關(guān)于C語(yǔ)言動(dòng)態(tài)分配二維字符串?dāng)?shù)組的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-10-10
  • C語(yǔ)言實(shí)現(xiàn)猜數(shù)字小游戲的示例代碼

    C語(yǔ)言實(shí)現(xiàn)猜數(shù)字小游戲的示例代碼

    猜數(shù)字小游戲是我們小時(shí)候喜歡我們一個(gè)經(jīng)典小游戲。本文將用C語(yǔ)言實(shí)現(xiàn)這一經(jīng)典游戲,文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2022-08-08
  • 帶你理解C語(yǔ)言中的漢諾塔公式

    帶你理解C語(yǔ)言中的漢諾塔公式

    大家好,本篇文章主要講的是帶你理解C語(yǔ)言中的漢諾塔公式,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-01-01
  • c語(yǔ)言實(shí)現(xiàn)MD5算法的項(xiàng)目實(shí)踐

    c語(yǔ)言實(shí)現(xiàn)MD5算法的項(xiàng)目實(shí)踐

    MD5用于確保信息傳輸完整一致,是計(jì)算機(jī)廣泛使用的雜湊算法之一,本文主要介紹了c語(yǔ)言實(shí)現(xiàn)MD5算法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-08-08
  • 淺談c++ vector和map的遍歷和刪除對(duì)象

    淺談c++ vector和map的遍歷和刪除對(duì)象

    下面小編就為大家?guī)?lái)一篇淺談c++ vector和map的遍歷和刪除對(duì)象。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-12-12
  • win32 api實(shí)現(xiàn)簡(jiǎn)單的消息窗口示例

    win32 api實(shí)現(xiàn)簡(jiǎn)單的消息窗口示例

    這篇文章主要介紹了使用win32 api實(shí)現(xiàn)簡(jiǎn)單的消息窗口示例,需要的朋友可以參考下
    2014-03-03
  • C++中function的實(shí)現(xiàn)原理詳解

    C++中function的實(shí)現(xiàn)原理詳解

    類(lèi)模版std::function是一種通用、多態(tài)的函數(shù)封裝。function的實(shí)例可以對(duì)任何可以調(diào)用的目標(biāo)實(shí)體進(jìn)行存儲(chǔ)、復(fù)制、和調(diào)用操作。本文主要聊聊它的實(shí)現(xiàn)原理,需要的可以參考一下
    2022-12-12

最新評(píng)論