libsndfile sf_readf_short максимальное количество кадров

Мне нужно считывать волновые файлы как можно быстрее. В настоящее время я делаю следующее:

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 МБ.

Спасибо за любую подсказку.


person ezdazuzena    schedule 20.06.2013    source источник
comment
Как вы получаете компиляцию строки short tmpSignal[readBlockSize];? Невозможно выделить массив в C++ с размером константы, отличной от времени компиляции.   -  person Gonmator    schedule 20.06.2013
comment
Откуда вы взяли ошибку сегментации? Я предполагаю в sf_readf_short, я прав?   -  person Gonmator    schedule 20.06.2013
comment
@Gonmator: точно. Я обновил свой пост.   -  person ezdazuzena    schedule 20.06.2013
comment
Требуется ли sf_readf_short() в качестве третьего параметра число shorts или количество байтов? Кроме того, возвращает ли он количество shorts или количество байтов?   -  person Gonmator    schedule 20.06.2013
comment
@Gonmator: в справке говорится: функции чтения кадров файла заполняют массив, на который указывает ptr, запрошенным количеством кадров данных. Массив должен быть достаточно большим, чтобы вместить произведение кадров и количество каналов. .. ?   -  person ezdazuzena    schedule 20.06.2013


Ответы (2)


Из документации libsndfile:

sf_count_t  sf_readf_short   (SNDFILE *sndfile, short *ptr, sf_count_t frames) ;

Функции чтения фреймов файла заполняют массив, на который указывает ptr, запрошенным количеством фреймов данных. Массив должен быть достаточно большим, чтобы вместить произведение кадров и количество каналов.

Необходимо следить за тем, чтобы в массиве, на который указывает ptr, было достаточно места для размещения (кадров * каналов) количества элементов (шорты, целые числа, числа с плавающей запятой или двойные числа).

readBlockSize укажите количество кадров, но вам надо выделить память на количество кадров * количество каналов.

Я не знаю, как вы действительно выделяете tmpSignal буфер, но вы должны сделать это с readBlockSize * количеством каналов (предположительно 2). (Или разделить на 2 количество кадров, указанное для readBlockSize вызова функции).

person Gonmator    schedule 20.06.2013
comment
Используемый мной волновой файл имеет только один канал. - person ezdazuzena; 20.06.2013
comment
@ezdazuzena: В таком случае это не решение, извините! - person Gonmator; 20.06.2013

Проблема заключается в размере стека, поэтому при доступе к переменной `tmpSignal', выделенной

//..
short tmpSignal[readBlockSize];
//..

Я получаю ошибку сегментации.

Это поведение можно воспроизвести (по крайней мере, на моей машине) с помощью

short tmp[10485760];
for(unsigned int i = 0; i < 10485760; ++i ) 
{
    tmp[i] = 0;
}
person ezdazuzena    schedule 21.06.2013