Нужна помощь в работе с файлами WAV (RIFF) на уровне байтов - PullRequest
2 голосов
/ 12 апреля 2010

Я пишу приложение на C #, которое будет записывать аудиофайлы (* .wav) и автоматически помечать и присваивать им имена. Волновые файлы - это файлы RIFF (например, AVI), которые могут содержать фрагменты метаданных в дополнение к фрагментам данных сигнала. Поэтому теперь я пытаюсь понять, как читать и записывать метаданные RIFF в записанные волновые файлы и из них.

Я использую NAudio для записи файлов и спросил на их форумах как , а на SO - способ чтения и записи тегов RIFF. Хотя я получил много хороших ответов, ни одно из решений не позволяло читать фрагменты RIFF и так легко, как хотелось бы.

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

Я использовал потоки в C #, но всегда со всем потоком сразу. Так что теперь я немного растерян, что мне нужно рассматривать файл побайтно. В частности, как бы я хотел удалить или вставить байты в и из середины файла? Я попытался прочитать файл через FileStream в байтовый массив (byte []), как показано в коде ниже.

System.IO.FileStream waveFileStream = System.IO.File.OpenRead(@"C:\sound.wav");
byte[] waveBytes = new byte[waveFileStream.Length];
waveFileStream.Read(waveBytes, 0, waveBytes.Length);

И я мог видеть через отладчик Visual Studio, что первые четыре байта являются заголовком RIFF файла. alt text

Но с массивами трудно справиться при выполнении действий, которые меняют свой размер, например, вставляя или удаляя значения. Поэтому я подумал, что смогу затем перевести байт [] в список вроде этого.

List<byte> list = waveBytes.ToList<byte>();

Что значительно упростит любые манипуляции с байтом файла, но я боюсь, что мне может не хватать чего-то похожего на класс в пространстве имен System.IO, что сделало бы все это еще проще. Я на правильном пути, или есть лучший способ сделать это? Я должен также упомянуть, что я не очень обеспокоен производительностью и предпочел бы не иметь дело с указателями или небезопасными блоками кода, такими как этот парень .

Если это поможет, вот хорошая статья о формате файла RIFF / WAV.

1 Ответ

1 голос
/ 12 апреля 2010

Я не писал на C #, но могу указать на некоторые места, которые плохи с моей точки зрения:

1) Не читайте целые файлы WAV в памяти, если только эти файлы не являются вашими собственными файлами и имеют заведомо небольшой размер.

2) Нет необходимости вставлять данные в память. Вы можете, например, сделать следующее: проанализировать исходный файл, сохранить смещения чанков и прочитать метаданные в памяти; представить метаданные для редактирования в диалоге; при сохранении записывают заголовок RIFF-WAV, блок fmt, переносят аудиоданные из исходного файла (путем чтения и записи блоков), добавляют метаданные; обновить заголовок RIFF-WAV.

3) Попробуйте сохранить метаданные в хвосте файла. Это приведет к тому, что чередующийся только тег не потребует перезаписи всего файла.

Похоже, что некоторые источники, касающиеся работы с файлами RIFF в C #, присутствуют здесь .

...