[英]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;
}
如果您想用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.