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


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

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

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

Я использовал потоки в C#, но всегда со всем потоком в однажды. Так что теперь я немного потерялся, что мне приходится рассматривать файл байт за байтом. В частности, как я буду удалять или вставлять байты в и из середины файла? Я попытался прочитать файл через поток файлов в массив байтов (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

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

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

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

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

1 2

1 ответ:

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

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

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

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

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