gpt4 book ai didi

c++ - 结合 libsndfile 和 RtAudio?

转载 作者:行者123 更新时间:2023-11-30 03:46:18 25 4
gpt4 key购买 nike

因此,我一直在尝试使用 RtAudio 和 libsndfile。

任务看起来很简单:

1.) 使用 libsndfile 将一些样本读入缓冲区(使用 SndfileHandle 类和 readf())

2.) 使用 RtAudio 播放样本

但是,出于某种原因,我得到的只是噪音和大量失真……我尝试将样本读取为 16 位 PCM(使用短缓冲区),并使用 RTAUDIO_SINT16 格式进行播放。没有成功......事实上,我尝试了很多不同的组合,但只有噪音......

我最接近实际播放的是使用 int16_t 作为缓冲区和 RTAUDIO_SINT16。看起来合乎逻辑,对吧?无论如何,它仍然像使用 bitcrusher 一样。尝试了 JACK 和 ALSA,以及缓冲区大小的许多不同组合,但无济于事......

关于如何结合这两者的任何提示?

我使用静态缓冲区会不会有问题(只是为了实验,当然不会在最终产品中这样做......)?

最佳答案

好的,在这里回答我自己的问题,这只是一些参数之间的混淆,主要是帧和样本......而样本只是单个样本,帧是所有 channel 的样本......

#include <iostream>
#include <sndfile.hh>
#include "RtAudio.h"

/*
* Audio-Wiedergabe mit RtAudio und libsndfile !
*/

// Call
int fplay( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
double streamTime, RtAudioStreamStatus status, void *userData )
{


int16_t *buffer = (int16_t *) outputBuffer;

// ok, i know this is not the best way to do file i/o in the audio thread, but
// this is just for demonstration purposes ...
SndfileHandle *sndfile = reinterpret_cast<SndfileHandle*>(userData);

// Error handling !
if ( status ){
std::cout << "Stream underflow detected!" << std::endl;
}


// 'readf()' liest frames
// 'read()' liest einzelne Samples !
// ACHTUNG! Frames != Samples
// ein Frame = Samples für alle Kanäle
// d.h. |Samples| = Kanäle * Frames !
sndfile->readf(buffer, nBufferFrames);

return 0;
}

int main () {
// Damit das Programm funktioniert, muss eine 16Bit PCM Wave-Datei im
// gleichen Ordner liegen !
const char * fname = "test.wav" ;

// Soundfile-Handle aus der libsndfile-Bibliothek
SndfileHandle file = SndfileHandle (fname) ;

// Alle möglichen Infos über die Audio-Datei ausgeben !
std::cout << "Reading file: " << fname << std::endl;
std::cout << "File format: " << file.format() << std::endl;
std::cout << "PCM 16 BIT: " << (SF_FORMAT_WAV | SF_FORMAT_PCM_16) << std::endl;
std::cout << "Samples in file: " << file.frames() << std::endl;
std::cout << "Samplerate " << file.samplerate() << std::endl;
std::cout << "Channels: " << file.channels() << std::endl;

// Die RtAudio-Klasse ist gleichermassen dac und adc, wird hier aber nur als dac verwendet !
RtAudio dac;
if ( dac.getDeviceCount() < 1 ) {
std::cout << "\nNo audio devices found!\n";
return 0;
}

// Output params ...
RtAudio::StreamParameters parameters;
parameters.deviceId = dac.getDefaultOutputDevice();
parameters.nChannels = 2;
parameters.firstChannel = 0;
unsigned int sampleRate = 44100;

// ACHTUNG! Frames != Samples
// ein Frame = Samples für alle Kanäle
// d.h. |Samples| = Kanäle*Frames !
unsigned int bufferFrames = 1024;


try {
dac.openStream( &parameters, NULL, RTAUDIO_SINT16,
sampleRate, &bufferFrames, &fplay, (void *)&file);
dac.startStream();
}
catch ( RtAudioError& e ) {
e.printMessage();
return 0;
}

char input;
std::cout << "\nPlaying ... press <enter> to quit.\n";
std::cin.get( input );
try {
// Stop the stream
dac.stopStream();
}
catch (RtAudioError& e) {
e.printMessage();
}
if ( dac.isStreamOpen() ) dac.closeStream();

return 0 ;

}

关于c++ - 结合 libsndfile 和 RtAudio?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34135031/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com