日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux播放到设备,linux - 将字节流式传输到ALSA播放设备 - 堆栈内存溢出

發布時間:2024/7/23 linux 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux播放到设备,linux - 将字节流式传输到ALSA播放设备 - 堆栈内存溢出 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我在使用libasound將隨機字節寫入ALSA播放設備時遇到了很多麻煩。 最終,我的目標是能夠通過網絡路由回放流并讓它在遠程設備上播放。

此問題中提供的代碼將WAV文件讀入內存并通過snd_pcm_writei將其寫入驅動程序并且可以正常工作。 但是,這段代碼與我正在嘗試做的事情之間的關鍵區別在于我沒有立即獲得所有數據。 我希望在數據可用時對其進行流式處理。

調整上面的示例代碼以滿足我的需求,我最終得到了這樣的結論:

#include

#include

#include

static snd_pcm_t *PlaybackHandle;

int init_playback(const char *device, int samplerate, int channels) {

int err;

printf("Init parameters: %s %d %d\n", device, samplerate, channels);

if((err = snd_pcm_open(&PlaybackHandle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {

printf("Can't open audio %s: %s\n", device, snd_strerror(err));

return -1;

}

if ((err = snd_pcm_set_params(PlaybackHandle, SND_PCM_FORMAT_S16, SND_PCM_ACCESS_RW_INTERLEAVED, channels, samplerate, 1, 500000)) < 0) {

printf("Can't set sound parameters: %s\n", snd_strerror(err));

return -1;

}

return 0;

}

int play_bytes(const void *bytes, int len) {

snd_pcm_uframes_t frames, count;

snd_pcm_uframes_t bufsize, period_size;

frames = 0;

count = 0;

snd_pcm_prepare(PlaybackHandle);

snd_pcm_get_params(PlaybackHandle, &bufsize, &period_size);

printf("bufsize=%d\n", (int) bufsize);

do {

int remaining = len - count;

int buflen = remaining < bufsize ? remaining : bufsize;

frames = snd_pcm_writei(PlaybackHandle, bytes + count, buflen);

// If an error, try to recover from it

if (frames == -EPIPE) {

printf("EPIPE\n");

snd_pcm_prepare(PlaybackHandle);

}

if (frames < 0) {

printf("Recovering\n");

frames = snd_pcm_recover(PlaybackHandle, frames, 0);

}

if (frames < 0)

{

printf("Error playing wave: %s\n", snd_strerror(frames));

break;

}

// Update our pointer

count += frames;

//printf("count=%d len=%d\n", (int)count, len);

} while (count < len);

// Wait for playback to completely finish

if (count == len)

snd_pcm_drain(PlaybackHandle);

return 0;

}

int close_playback() {

snd_pcm_close(PlaybackHandle);

return 0;

}

int main(int argc, char **argv) {

if(argc < 1) {

printf("Usage: %s \n", argv[0]);

return -1;

}

int fd;

unsigned long long len;

fd = open(argv[1], O_RDONLY);

// Find the length

len = lseek(fd, 0, SEEK_END);

// Skip the first 44 bytes (header)

lseek(fd, 44, SEEK_SET);

len -= 44;

char *data = malloc(len);

read(fd, data, len);

init_playback("default", 44100, 2);

play_bytes(data, len);

close_playback();

return 0;

}

這段代碼可以用gcc playback.c -o playback -lasound 。 我正在使用的WAV文件可以在這里找到。

當我運行此代碼片段時,我根據bufsize對輸入數據進行分塊,根據塊大小,在播放中會重復播放音頻片段。 較大的塊大小產生的重復次數少于小塊大小。 將此與音頻的聲音結合起來,我相信在每個塊的末尾都會重復一個小片段。

我使用的參數是:

樣本:44100

頻道:2

為什么一次性發送整個WAV文件工作,而發送它的塊不起作用? 如何將音頻數據塊發送給驅動程序并使其正常播放?

總結

以上是生活随笔為你收集整理的linux播放到设备,linux - 将字节流式传输到ALSA播放设备 - 堆栈内存溢出的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。