Кодировка Libsox - PullRequest
       8

Кодировка Libsox

0 голосов
/ 06 февраля 2009

Почему я получаю искаженный вывод, если я конвертирую wav-файл с помощью libsox в:

&in->encoding.encoding = SOX_ENCODING_UNSIGNED;
&in->encoding.bits_per_sample = 8;

используя вышеуказанный код?

Входной файл имеет bits_per_sample = 16.

1 Ответ

0 голосов
/ 06 февраля 2009

Итак, вы говорите, что говорите SOX прочитать 16-битный пример файла WAV как 8-битный пример файла? Ничего не зная о SOX, я ожидал бы, что он будет читать каждый 16-битный сэмпл как два 8-битных сэмпла ... байт старшего разряда и байт младшего разряда, например:

Для простоты мы будем называть старшие байтовые сэмплы 'A' сэмплами. Сэмплы 'A' несут оригинальный звук с меньшим динамическим диапазоном, потому что младший байт с дополнительной точностью был обрезан.

Мы будем называть младшие байтовые сэмплы "B samples". Они будут примерно случайными и закодируют шум.

Таким образом, в результате мы получим оригинальный звук, сэмплы «А», сдвинутые по частоте на половину. Это связано с тем, что между каждой выборкой «А» имеется выборка «В», что вдвое снижает частоту выборок «А». Сэмплы «B» добавляют шум к оригинальному звуку. Таким образом, у нас будет оригинальный звук, смещенный вдвое, с шумом.

Это то, что вы слышите?

Редактировать Гость отметил, что целью является преобразование WAV в 8-битный звук. Считая справочную страницу для SoX , похоже, что SoX всегда использует 32-битный звук в памяти в результате sox_read (). Передача этого формата только попытается прочитать из этого формата.

Для преобразования в памяти используйте SOX_SAMPLE_TO_SIGNED_8BIT или SOX_SAMPLE_TO_UNSIGNED_8BIT из sox.h, то есть:

sox_format_t ft = sox_open_read("/file/blah.wav", NULL, NULL);
if( ft ) {
    sox_ssample_t buffer[100];
    sox_size_t amt = sox_read(ft, buffer, sizeof(buffer));
    char 8bitsample = SOX_SAMPLE_TO_SIGNED_8BIT(buffer[0], ft->clips);
}

для вывода преобразованного с понижением частоты файла, используйте 8-битный формат при записи, а не при чтении.

...