【问题标题】:Combining libsndfile and RtAudio?结合 libsndfile 和 RtAudio?
【发布时间】:2016-03-12 03:24:26
【问题描述】:

所以,我一直在试验 RtAudio 和 libsndfile。

任务似乎很简单:

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

2.) 使用 RtAudio 播放样本

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

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

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

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

【问题讨论】:

    标签: c++ libsndfile rtaudio


    【解决方案1】:

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

    #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 ;
    
    }
    

    【讨论】:

      猜你喜欢
      • 2011-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-19
      • 1970-01-01
      • 2023-04-07
      • 2021-07-23
      相关资源
      最近更新 更多