2010-05-18 2 views
3

Я пишу утилиту сжатия файлов на C++, что я хочу поддерживать файлы WMA PCM, однако я хочу сохранить ее в кодировке PCM и просто преобразовать ее в более низкую частоту дискретизации и изменить ее из стерео в моно если применимо, чтобы получить более низкий размер файла.Программно конвертировать WAV

Я понимаю заголовок файла WAV, однако у меня нет опыта или знаний о том, как работают фактические звуковые данные. Поэтому мой вопрос: было бы относительно легко программным образом манипулировать суб-куском данных в WAV-файле, чтобы преобразовать его в другую частоту дискретизации и изменить номер канала, или мне будет намного лучше использовать существующую библиотеку для него ? Если да, то как это сделать? Заранее спасибо.

ответ

1

Я не думаю, что на самом деле нужно изобретать колесо (если вы не хотите сделать это для своего личного обучения). Например, вы можете использовать libsnd

+0

Как правило, я, по возможности, один из минимализма в своих программах, и было бы неплохо узнать немного формата. Мне кажется, что изменение частоты дискретизации и каналов было бы относительно легко сделать, но, конечно, я могу ошибаться. – kaykun

+0

Ваша программа не будет настолько «минимальной», как только вы перевернете свой собственный код обработки звука. Если вы используете библиотеку, скорее всего, у вас уже есть ее, и требуется несколько строк кода для вызова. –

4

PCM просто означает, что значение исходного сигнала отбирается на равноудаленных точках времени.

Для стерео, есть две последовательности этих значений. Чтобы преобразовать их в моно, вы просто принимаете кусочно среднее из двух последовательностей.

Повторная выборка сигнала при более низкой частоте дискретизации немного сложнее - вы должны отфильтровывать высокие частоты от сигнала, чтобы предотвратить создание псевдонима (ложный низкочастотный сигнал).

2

Я согласен с avakar и nico, но я хотел бы добавить немного больше объяснений. Понижение частоты дискретизации аудио PCM не является тривиальным, если две вещи не являются истинными:

  1. Вашего сигнал содержит только существенные частоты ниже, чем 1/2 новой частоту дискретизации (Nyquist rate). В этом случае вам не нужен фильтр сглаживания.

  2. Вы снижаете дискретизацию с помощью целочисленного значения. В этом случае для отмены выборки по N просто требуется сохранить каждый N-й образец и сбросить остальные.

Если это правда, вы можете просто отбросить образцы с регулярным интервалом до нижнего предела. Тем не менее, они оба, вероятно, неверны, если вы имеете дело с чем-то другим, кроме синтетического сигнала.

Чтобы решить проблему, вам необходимо будет отфильтровать звуковые сэмплы с фильтром нижних частот, чтобы убедиться, что результирующий сигнал содержит только частотный контент до 1/2 новой частоты дискретизации. Если этого не сделать, высокие частоты не будут точно представлены и будут возвращаться обратно на частоты, которые могут быть правильно представлены, что вызывает серьезные искажения. Ознакомьтесь с разделом critical frequency этой статьи в Википедии для объяснения сглаживания. В частности, см. Рисунок 7, в котором показаны 3 разных сигнала, которые невозможно отличить от образцов, потому что частота дискретизации слишком низкая.

Решение проблемы два может быть выполнено несколькими способами. Иногда это выполняется в два этапа: upsample, за которым следует понижающий диск, поэтому достигается рациональное изменение частоты дискретизации. Это также может быть сделано с использованием интерполяции или других методов. В основном проблема, которая должна быть решена, состоит в том, что образцы нового сигнала не выстраиваются во времени с образцами исходного сигнала.

Как вы можете видеть, передискретизация звука может быть довольно сложной, поэтому я бы взял совет nico и использовал существующую библиотеку. Для правильного выбора фильтра вам потребуется много узнать о обработке сигналов и частотном анализе.Вам не обязательно быть экспертом, но это займет некоторое время.

Смежные вопросы