Нужна помощь в работе с файлами WAV (RIFF) на уровне байтов

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

Я использую NAudio для записи файлов и спрашивал на их форумах также о том, как читать и писать теги 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 файла.альтернативный текст

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

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

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

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

1 ответ

Решение

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

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

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

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

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

Другие вопросы по тегам