Мне нужно читать как можно быстрее волновые файлы. Что я сейчас делаю, так это следующее:
SFINFO sfinfo;
SNDFILE *wavFilefd = sf_open ("mySong.wav", SFM_READ, &sfinfo);
int readBlockSize = 1024*1024; // 1MB
if( sfinfo.frames * 2 < readBlockSize )
{
// actually I don't know where this factor two comes from, but it work's for me
readBlockSize = sfinfo.frames * 2;
}
short tmpSignal[readBlockSize];
int readcount = -1;
std::vector< short > wavVector;
while ((readcount = sf_readf_short (wavFilefd, tmpSignal, readBlockSize)) > 0)
{
++nRead;
wavVector.reserve( (nRead-1) * readBlockSize + nRead);
wavVector.insert( wavVector.end(), tmpSignal, tmpSignal+readcount);
}
sf_close(wavFilefd);
Этот код хорошо работает до сих пор.
Проблема: Когда я увеличиваю значение readBlockSize, скажем, в 10 раз, а затем пытаюсь прочитать волновой файл размером 115212164 байта, я получаю ошибку сегментации при выполнении sf_readf_short
,
От Помогите я получил «Функции sf_readf_XXXX возвращают количество прочитанных кадров. Если конец файла не был достигнут во время чтения, возвращаемое значение должно равняться количеству запрошенных кадров. Попытки чтения после конца файла не приведут к ошибке, но приведет к тому, что функции sf_readf_XXXX вернут меньше, чем количество запрошенных кадров, или 0, если уже в конце файла. «
Поэтому я ожидал, что это будет работать и для 10 МБ.
Спасибо за любую подсказку.
Из документации libsndfile:
sf_count_t sf_readf_short (SNDFILE *sndfile, short *ptr, sf_count_t frames) ;
Функции считывания кадров файла заполняют массив, на который указывает ptr:
запрашиваемое количество кадров данных. Массив должен быть достаточно большим
провести произведение кадров и количество каналов.Необходимо следить за тем, чтобы в массиве было достаточно места
на что указывает ptr, чтобы взять (кадры * каналы) количество элементов
(шорты, целые, плавающие или двойные).
readBlockSize
укажите количество кадров, но вы должны выделить память для количества кадров * количество каналов.
Я не знаю, как вы на самом деле выделить tmpSignal
буфер, но вы должны сделать это с readBlockSize
* количество каналов (предположительно 2). (Или разделите на 2 количество кадров, указанное для readBlockSize
вызов функции).
Проблема заключается в размере стека, поэтому при доступе к переменной `tmpSignal ‘, выделенной
//..
short tmpSignal[readBlockSize];
//..
Я получаю ошибку сегментации.
Это поведение может быть воспроизведено (по крайней мере на моей машине)
short tmp[10485760];
for(unsigned int i = 0; i < 10485760; ++i )
{
tmp[i] = 0;
}