NAudio запись образца за образцом в файл



Я создаю приложение, которое записывает звук с микрофона в файл (. mp3). я хочу, чтобы мое приложение записывало данные в файл только при обнаружении достаточно высокой амплитуды. У меня возникли проблемы с сохранением выбранных данных. Все, что я получаю, - это быстрое искажение, даже близко не похожее на то, что было записано.



Вот мой код:



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using NAudio.Wave;

namespace NAudio_Testing
{
public partial class Form1 : Form
{
int counter = 0;
int passed = 0;
private BufferedWaveProvider bufferedWaveProvider;
WaveIn waveIn;
WaveFileWriter writer;
string output = "C:/Users/klein/AppData/Roaming/Microsoft/Windows/gravacao.mp3";
public Form1()
{
InitializeComponent();
waveIn = new WaveIn();
writer = new WaveFileWriter(output, waveIn.WaveFormat);

waveIn.DataAvailable += new EventHandler<WaveInEventArgs>(new_dataAvailable);

bufferedWaveProvider = new BufferedWaveProvider(waveIn.WaveFormat);
bufferedWaveProvider.DiscardOnBufferOverflow = true;
waveIn.StartRecording();
}

private void Form1_Load(object sender, EventArgs e)
{
timer1.Interval = 1000;
timer1.Start();
}

void new_dataAvailable(object sender, WaveInEventArgs e)
{
for (int i = 0; i < e.BytesRecorded; i+=2)
{
short sample = (short)((e.Buffer[i + 1] << 8) | e.Buffer[i + 0]);
float sample32 = sample / 32768f;
if (sample32 > 0.02) //0.02~0.03
{
writer.WriteSample(sample);
}
}
}

private void button1_Click(object sender, EventArgs e)
{
waveIn.StopRecording();
waveIn.Dispose();
waveIn = null;
writer.Close();
writer = null;
}

private void timer1_Tick(object sender, EventArgs e)
{
textBox1.Text = counter++.ToString();
}

}
}


EDIT: я могу записать аудио успешно, если я удаляю выборочное if и просто добавляю строки, проблема, конечно, в том, что тогда Я не могу записать или нет в зависимости от амплитуды звука:



writer.WriteByte(e.Buffer[i + 0]);
writer.WriteByte(e.Buffer[i + 1]);


Вот так:



void new_dataAvailable(object sender, WaveInEventArgs e)
{
for (int i = 0; i < e.BytesRecorded; i+=2)
{
short sample = (short)((e.Buffer[i + 1] << 8) | e.Buffer[i + 0]);
float sample32 = sample / 32768f;

writer.WriteByte(e.Buffer[i + 0]);
writer.WriteByte(e.Buffer[i + 1]);

}
}


Спасибо.

638   2  

2 ответов:

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

Вместо этого вам нужно измерить максимальный объем всех образцов за короткий промежуток времени (как долго это зависит от вас, но вы можете сделать 1 секунду за один раз). Если в течение этого времени какая-либо выборка будет громче указанной минимальное значение, то вы записываете весь блок.

Вторая проблема с вашим кодом заключается в том, что вы на самом деле не создаете MP3-файл. WaveFileWriter создает WAV-файл. Измените имя файла на конец WAV и слушайте его, чтобы услышать результаты вашей записи. Затем вам нужно будет конвертировать в MP3 в качестве второго шага после записи. (У меня есть статья о том, как конвертировать между форматами здесь).

Вы должны сравнить абсолютное значение выборки, так как выборки подписаны.

 if (Abs(sample32) > 0.02) //0.02~0.03
   {
      writer.WriteSample(sample);
   }

Comments

    Ничего не найдено.