У меня есть приложение .net для Mac, и все, что ему нужно сделать, это записать звук, а затем записать его в файл WAV.
Я использую оболочку C# для PortAudio для записи звука. Мне удалось успешно записать и записать WAV-файл для 1-канального звука, то же самое для 2-канального. Но когда я пытаюсь записать 2-канальный звук, а затем записать его как 1-канальный звук, он искажается. Комбинация двух каналов с одним осуществляется путем взятия чередующихся пар выборок, их сложения и последующего деления на 2. При этом предпринимаются шаги, чтобы избежать переполнения.
И все же при объединении каналов, конечный результат искажается. Я убежден, что это что-то элементарное и простое, что я делаю ужасно неправильно, но больше не могу этого заметить.
Код для записи:
Меня не слишком волнует потеря качества звука, главное, чтобы по нему можно было четко и легко понимать человеческую речь.
Пример искаженного звука: https://www.dropbox.com/scl/fi/5204zxtp ... xj8pm&dl=0
Приведенный выше код является конечной точкой после нескольких разных попыток.
В настоящее время частота дискретизации, которую мы записываем в WAV, составляет половину частоты, которую мы записываем. at, но без этого изменения длина звука уменьшается вдвое и воспроизводится с двойной скоростью.
Частота дискретизации раньше была 16000, и это, казалось, давало немного лучшие результаты, но, судя по всему, я Вы читали в Интернете, кажется, что 44100 — лучший выбор?
Изначально, когда я объединял каналы, он был просто статическим, но приведение сэмплов к 32-битному формату при объединении, кажется, помогает избежать переполнения.
Я пробовал разные форматы сэмплов, пробовал нечередующийся звук, но, похоже, это не делает ничего лучше или хуже.
Он определенно может хорошо работать при записи 2-канального звука и записи его в качестве 2-канального звука, поэтому я вполне уверен, что это не аппаратная проблема.
Основная причина, по которой я пытаюсь это сделать. объединить 2 канала звука в 1, мне нужно, чтобы конечный файл WAV был как можно меньше. Мне нужно хорошее качество звука, и то, что я могу сэкономить место, является бонусом, а объединение двух каналов в один приведет к значительному сокращению размера файла.
У меня есть приложение .net для Mac, и все, что ему нужно сделать, это записать звук, а затем записать его в файл WAV. Я использую оболочку C# для PortAudio для записи звука. Мне удалось успешно записать и записать WAV-файл для 1-канального звука, то же самое для 2-канального. Но когда я пытаюсь записать 2-канальный звук, а затем записать его как 1-канальный звук, он искажается. Комбинация двух каналов с одним осуществляется путем взятия чередующихся пар выборок, их сложения и последующего деления на 2. При этом предпринимаются шаги, чтобы избежать переполнения. И все же при объединении каналов, конечный результат искажается. Я убежден, что это что-то элементарное и простое, что я делаю ужасно неправильно, но больше не могу этого заметить. Код для записи: [code] private static readonly int _sampleRate = 44100; private static int _totalSamplesWritten = 0; private const ushort BIT_DEPTH = 16 ;
for (var i = 0; i < frameCount; i++) { var sampleL = samples[i]; var overflowSafeSampleL = Convert.ToInt32(sampleL); var sampleR = samples[i + 1]; var overflowSafeSampleR = Convert.ToInt32(sampleR);
var combinedSample = overflowSafeSampleL + overflowSafeSampleR; var dividedSample = Convert.ToInt16(combinedSample / 2);
_outputFileWriter.Write(dividedSample); i++; }
_totalSamplesWritten += (int)frameCount;
return StreamCallbackResult.Continue; }
_stream = new PortAudioSharp.Stream( inParams: param, outParams: null, sampleRate: _sampleRate, framesPerBuffer: 256, streamFlags: StreamFlags.ClipOff, callback: param.channelCount > 1 ? CallbackStereoInput : CallbackMonoInput, userData: IntPtr.Zero ); [/code] Код для записи заголовка WAV: [code]WriteWavHeader(_outputFileWriter, 1, BIT_DEPTH, _sampleRate / 2, _totalSamplesWritten);
private static void WriteWavHeader(BinaryWriter writer, ushort channelCount, ushort bitDepth, int sampleRate, int totalSampleCount) { writer.Seek(0, SeekOrigin.Begin); writer.Write(Encoding.ASCII.GetBytes("RIFF")); writer.Write((bitDepth / 8 * totalSampleCount) + 36); writer.Write(Encoding.ASCII.GetBytes("WAVE")); writer.Write(Encoding.ASCII.GetBytes("fmt ")); writer.Write(16); writer.Write((ushort)1); writer.Write(channelCount); writer.Write(sampleRate); writer.Write(sampleRate * channelCount * bitDepth / 8); writer.Write((ushort)(channelCount * bitDepth / 8)); writer.Write(bitDepth); writer.Write(Encoding.ASCII.GetBytes("data")); writer.Write(bitDepth / 8 * totalSampleCount); } [/code] Меня не слишком волнует потеря качества звука, главное, чтобы по нему можно было четко и легко понимать человеческую речь. Пример искаженного звука: https://www.dropbox.com/scl/fi/5204zxtpjkqa4ewxhph0j/Audio.wav?rlkey=9urdo4s0zqtyd3hxi1oscko9b&st=w02xj8pm&dl=0 Приведенный выше код является конечной точкой после нескольких разных попыток. [list] [*]В настоящее время частота дискретизации, которую мы записываем в WAV, составляет половину частоты, которую мы записываем. at, но без этого изменения длина звука уменьшается вдвое и воспроизводится с двойной скоростью. [*]Частота дискретизации раньше была 16000, и это, казалось, давало немного лучшие результаты, но, судя по всему, я Вы читали в Интернете, кажется, что 44100 — лучший выбор? [*]Изначально, когда я объединял каналы, он был просто статическим, но приведение сэмплов к 32-битному формату при объединении, кажется, помогает избежать переполнения. [*]Я пробовал разные форматы сэмплов, пробовал нечередующийся звук, но, похоже, это не делает ничего лучше или хуже. [*] Он определенно может хорошо работать при записи 2-канального звука и записи его в качестве 2-канального звука, поэтому я вполне уверен, что это не аппаратная проблема. [*]Основная причина, по которой я пытаюсь это сделать. объединить 2 канала звука в 1, мне нужно, чтобы конечный файл WAV был как можно меньше. Мне нужно хорошее качество звука, и то, что я могу сэкономить место, является бонусом, а объединение двух каналов в один приведет к значительному сокращению размера файла. [/list]