簡體   English   中英

如何創建與VST音頻緩沖區相同的指針數組的指針?

[英]How to create pointer to pointer array same as VST audio buffer?

在VST規范中,傳遞了多通道音頻數據的緩沖區。

MyClass::ProcessDoubleReplacing(double **inputs, double **outputs, int frames)
{
    //and accessed like this...
    outputs[channel][sample] = inputs[channel][sample]
}

我想創建一個類似的“ 2d指針數組”,但是沒有太大的成功。 我可以創建一個簡單的指針並遍歷它的讀/寫值。

double* samples;
samples[0] = aValue;

....但我正在參加一個速成節,試圖實現一些可以讓我...

samples[0][0] = aValue;

正確的方法是什么?

double* samples;
samples[0] = aValue;

真的很糟糕 :(請不要這樣做!“樣本”只是指向內存中某處的指針。它所指向的內存根本沒有分配,但是您正在寫入此內存...

您可以從堆或堆棧中分配一塊內存。 但是,堆棧有一個大小限制(在編譯器設置中配置)-因此,對於較大的塊(如音頻數據),通常會從堆中分配它。 但是您必須小心,不要從堆中泄漏內存-堆棧內存由變量的范圍自動管理,因此更容易開始。 在C / C ++中,您可以像這樣從堆棧分配內存:

double samples[512];

那么您可以執行以下操作:

samples[0] = aValue; // change value of 1st sample in sample buffer with 512 elements

要么

double* pointerToSample = samples[255]; // point to 256ths sample in the sample buffer
pointerToSample[127] = aValue;          // change value of 384ths sample (256+128) in our sample buffer with 512 elements

依此類推...但是,如果您這樣做,

double* pointerToSample;
pointerToSample[127] = aValue;

您實際上正在寫入未分配的內存! 您的指針指向某處,但后面沒有分配的內存。 小心點! 如果samples變量已經超出范圍,也永遠不要訪問pointerToSample:否則,將不再分配pointerToSample指向的內存。

要在C ++中從堆中分配內存,可以動態地使用關鍵字new(分配內存)和delete(隨后釋放內存)。

double *samples = new double[512];

將為您的樣本數據分配一塊內存。 但是使用它之后,您必須手動刪除它-否則會泄漏內存。 所以做:

delete[] samples;

完成后。

最后但並非最不重要的一點是回答您的問題,如何創建一個二維數組以調用方法ProcessDoubleReplacing()

int main(int argc, char ** argv){
  /* create 2 dimensional array */
  int** samplesIn = new int*[44100];
  int** samplesOut = new int*[44100];
  for(int i = 0; i < 44100; ++i){   // 1s @ 44.1Khz
    samplesIn[i] = new int[2];      // stereo
    samplesOut[i] = new int[2];      // stereo
  }
  /* TODO: fill your input buffer with audio samples from somewhere i.e. file */
  ProcessDoubleReplacing(samplesIn, samplesOut, 44100);

  /* cleanup */
  for(int i = 0; i < 44100; ++i) {
    delete [] samplesIn[i];
    delete [] samplesOut[i];
  }
  delete [] samplesIn;
  delete [] samplesOut;

  return 0;
}

@康斯坦丁的回答幾乎釘它,但我只是想補充一點,在你實現你應該在你的分配緩沖process()回調。 這樣做可能會導致您的插件花費太多時間,結果系統會丟棄音頻緩沖區,從而導致播放故障。

因此,這些緩沖區應該是主處理類的字段(即AEffect ),並且應該在構造函數中分配它們的大小。 切勿process()方法內部使用newdelete方法,否則您將遇到麻煩!

這是有關實時音頻編程的注意事項的很好指南

如果您想用C ++編寫一些東西來提供與您顯示的界面類似的界面,則可以使用std::vector來管理內存,如下所示:

vector<vector<double>> buffers (2,vector<double>(500));

這僅存儲數據。 對於指針數組,您需要一個指針數組。 :)

vector<double*> pointers;
pointers.push_back(buffers[0].data());
pointers.push_back(buffers[1].data());

這是可行的,因為std::vector可以保證所有元素都相鄰且線性存儲在內存中。 因此,您也可以這樣做:

double** p = pointers.data();
p[0][123] = 17;
p[1][222] = 29;

重要的是要注意,如果您調整其中一些向量的大小,則指針可能會變得無效,在這種情況下,您應該繼續操作並獲取新的指針。

請記住, data成員函數是C ++ 11功能。 如果您不想使用它,可以編寫

&some_vector[0] // instead of some_vector.data()

(除非向量為空)

您可能對直接通過引用傳遞緩沖區向量感興趣,而不是將double **傳遞給某些函數,但是,如果您希望您的接口與C兼容,那么這顯然將不起作用。 只是說。

編輯 :關於為什么我選擇std::vector不是new[]malloc :因為在現代C ++中這樣做是正確的! 在這種情況下,混亂的可能性較低。 您將不會有任何內存泄漏,因為矢量將負責管理內存。 這在C ++中尤其重要,因為您可能會遇到異常情況,因此可能在函數末尾使用delete[]之前提早退出函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM