1

アプリでインターネットからのオーディオ ストリームを再生していて、グラフィック イコライザーを表示したいと考えています。ストリーミングに使用しているライブラリはFreeStreamer. 私が使用しているグラフィックイコライザーを描画するためにZLHistogramAudioPlot. これらの 2 つのライブラリは、私のニーズを満たす唯一のものです。問題は、それらを連携させることができないことです。

ZLHistogramAudioPlotビューを更新するには、buffer と bufferSize が必要です。更新方法は次のとおりです。

- (void)updateBuffer:(float *)buffer withBufferSize:(UInt32)bufferSize {
    [self setSampleData:buffer length:bufferSize];
}

残念ながら、FreeStreamerライブラリには、サウンド カードに出力される audiot 出力を読み取る方法が用意されていません。だから、私が必要としているのは、スピーカーから再生しようとしているオーディオ出力ストリームを読み取る方法です(インターネットからのバイトストリームではありません。これは、チャンクで受信されてからバッファリングされるためです。つまり、ヒストグラムは含まれませんリアルタイム)。

AURemoteIOfrom Apple のフレームワークを使用してこれを行うことができることを発見しましたCoreAudioが、Apple のサンプル プロジェクトは理解できないほど複雑であり、オンラインでの使用に関する例はほとんどありませんAURemoteIO

これはこれを達成するための最良の方法ですか?もしそうなら、役立つ情報/リンクは大歓迎です.

4

1 に答える 1

1

FreeStreamer ヘッダーを調べて考えられる答えを次に示します。

#define minForSpectrum 1024

@implementation MyClass {
    TPCircularBuffer SpectrumAnalyzerBuffer;
}

- (void)dealloc {
    TPCircularBufferCleanup(&SpectrumAnalyzerBuffer);
}

-(instancetype) init {
   self = [super init];
   if (self) {
      TPCircularBufferInit(&SpectrumAnalyzerBuffer, 16384);
      self.audioController.activeStream.delegate = self;
   }
   return self;
}

- (void)audioStream:(FSAudioStream *)audioStream samplesAvailable:(const int16_t *)samples count:(NSUInteger)count {
    // incoming data is integer

    SInt16 *buffer = samples;
    Float32 *floatBuffer = malloc(sizeof(Float32)*count);
    // convert to float
    vDSP_vflt16(buffer, 1, floatBuffer, 1, count);

    // scale
    static float scale = 1.f / (INT16_MAX/2);
    static float zero = 0.f;

    vDSP_vsmsa(floatBuffer, 1, &scale, &zero, floatBuffer, 1, count);

    TPCircularBufferProduceBytes(&SpectrumAnalyzerBuffer, floatBuffer, count*sizeof(Float32));

    free(floatBuffer);   
}

- (void) timerCallback: (NSTimer*) timer {

    Float32 *spectrumBufferData = TPCircularBufferTail(&SpectrumAnalyzerBuffer, &availableSpectrum);

    if (availableSpectrum >= minForSpectrum) {
        // note visualiser may want chunks of a fixed size if its doing fft
        [histogram updateBuffer: spectrumBufferData length: minForSpectrum];
        TPCircularBufferConsume(&SpectrumAnalyzerBuffer, minForSpectrum);
    }


}
于 2015-05-21T09:59:20.303 に答える