C#-Naudio-如何将float []转换为iSampleProvider?

发布于 2025-01-25 07:23:22 字数 897 浏览 3 评论 0原文

我正在编码我的第一个音频应用程序,并且我正在努力尝试将float []格式的缓冲区转换为IsampleProvider。我需要进一步将几片音频粘合在一起。 我该怎么做?代码:

    float dt;//= 1f / nSamplesPerSec;
    int nChannels = 1;
    int duration = 30;
    int nSamplesPerChannel;//= nSamplesPerSec * duration / 1000;
    float[] buffer;

    void CreateBuffer()
    {
        dt = 1f / nSamplesPerSec;
        nSamplesPerChannel = nSamplesPerSec * duration / 1000;
        d = nSamplesPerChannel * dt;
        buffer = new float[nSamplesPerChannel];

        float f = 800;//frequency
        generate(f, 0);
    }

    void generate(float f, float p)
    {
        double koef = 0.22;
        int newSamples = (int)(nSamplesPerChannel * koef);

        for (int i = 0; i < nSamplesPerChannel; i++)
        {
            double AmpRamp = 1.0D;
            buffer[i] = (float)(AmpRamp*Math.Sin(2 * Math.PI * (f * dt * i + p)));
        }
    }

I'm coding my first audio application, and I'm struggling for hours on trying to convert a buffer in float[] format to ISampleProvider. I need this for further gluing together several pieces of audio.
How do I do this? Code:

    float dt;//= 1f / nSamplesPerSec;
    int nChannels = 1;
    int duration = 30;
    int nSamplesPerChannel;//= nSamplesPerSec * duration / 1000;
    float[] buffer;

    void CreateBuffer()
    {
        dt = 1f / nSamplesPerSec;
        nSamplesPerChannel = nSamplesPerSec * duration / 1000;
        d = nSamplesPerChannel * dt;
        buffer = new float[nSamplesPerChannel];

        float f = 800;//frequency
        generate(f, 0);
    }

    void generate(float f, float p)
    {
        double koef = 0.22;
        int newSamples = (int)(nSamplesPerChannel * koef);

        for (int i = 0; i < nSamplesPerChannel; i++)
        {
            double AmpRamp = 1.0D;
            buffer[i] = (float)(AmpRamp*Math.Sin(2 * Math.PI * (f * dt * i + p)));
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

伏妖词 2025-02-01 07:23:22

Isample -provider是一个接口,因此您不能像类那样直接创建一个接口。但是,我们可以创建自己的类,该类实现Isample -provider接口,然后创建该类的实例,以用作WaveOutEvent或您需要的任何其他内容。

using NAudio.Wave;
using System;
using System.Threading;
public class CustomSampleProvider : ISampleProvider
{
    private float[] _samples; //A private readonly copy of the samples
    private WaveFormat _waveFormat; //A private copy readonly copy of the WaveFormat
    private long _position; //A long to store how far through the audio clip we currently are

    //We need a publicly accessable WaveFormat as part of the ISampleProvider interface.
    public WaveFormat WaveFormat
    {
        get
        {
            //Return a copy of the waveFormat not the original to prevent others from modifying our format.
            return WaveFormat.CreateCustomFormat(_waveFormat.Encoding, _waveFormat.SampleRate, _waveFormat.Channels, _waveFormat.AverageBytesPerSecond, _waveFormat.BlockAlign, _waveFormat.BitsPerSample);
        }
    }

    //A constructor which takes in the samples and a WaveFormat from the user.
    public CustomSampleProvider(float[] samples, WaveFormat waveFormat)
    {
        //Create a copy of the samples. We do this to prevent others from changing our samples.
        _samples = new float[samples.Length];
        Array.Copy(samples, 0, _samples, 0, samples.LongLength);

        //Create a copy of the format for the same reason as above.
        _waveFormat = WaveFormat.CreateCustomFormat(waveFormat.Encoding, waveFormat.SampleRate, waveFormat.Channels, waveFormat.AverageBytesPerSecond, waveFormat.BlockAlign, waveFormat.BitsPerSample);
    }

    public int Read(float[] buffer, int offset, int count)
    {
        //If the requested amount of samples would go off the end of our data then clamp the count so its smaller.
        if (_position + count >= _samples.LongLength)
        {
            count = (int)(_samples.LongLength - _position);
        }

        //Copy the requested number of samples from our internal data to the buffer.
        Array.Copy(_samples, _position, buffer, offset, count);

        //Dont forget to move the position furthar along by how many samples were read.
        _position += count;

        //Finally return how many samples were read.
        return count;
    }
}
public static class Program
{
    public static void Main()
    {
        //Replace this line with your real code for getting the samples and format.
        float[] samples = new float[0];
        WaveFormat waveFormat = new WaveFormat();

        //Create an instance of our CustomSampleProvider class.
        CustomSampleProvider sampleProvider = new CustomSampleProvider(samples, waveFormat);

        //Create a WaveOutEvent for playing our sampleProvider.
        WaveOutEvent waveOutEvent = new WaveOutEvent();

        //Tell the WaveOutEvent to get ready to play our sampleProvider.
        waveOutEvent.Init(sampleProvider);

        waveOutEvent.Play();

        //Wait until the WaveOutEvent is done playing by checking if it's done every 100 miliseconds.
        while (waveOutEvent.PlaybackState == PlaybackState.Playing)
        {
            Thread.Sleep(100);
        }

        //Finally exit the program
        Environment.Exit(0);
    }
}

ISampleProvider is an interface so you can't directly create one like you would a class. However we can create our own class which implements the ISampleProvider interface then create an instance of that class to use as the source for a WaveOutEvent or anything else you need.

using NAudio.Wave;
using System;
using System.Threading;
public class CustomSampleProvider : ISampleProvider
{
    private float[] _samples; //A private readonly copy of the samples
    private WaveFormat _waveFormat; //A private copy readonly copy of the WaveFormat
    private long _position; //A long to store how far through the audio clip we currently are

    //We need a publicly accessable WaveFormat as part of the ISampleProvider interface.
    public WaveFormat WaveFormat
    {
        get
        {
            //Return a copy of the waveFormat not the original to prevent others from modifying our format.
            return WaveFormat.CreateCustomFormat(_waveFormat.Encoding, _waveFormat.SampleRate, _waveFormat.Channels, _waveFormat.AverageBytesPerSecond, _waveFormat.BlockAlign, _waveFormat.BitsPerSample);
        }
    }

    //A constructor which takes in the samples and a WaveFormat from the user.
    public CustomSampleProvider(float[] samples, WaveFormat waveFormat)
    {
        //Create a copy of the samples. We do this to prevent others from changing our samples.
        _samples = new float[samples.Length];
        Array.Copy(samples, 0, _samples, 0, samples.LongLength);

        //Create a copy of the format for the same reason as above.
        _waveFormat = WaveFormat.CreateCustomFormat(waveFormat.Encoding, waveFormat.SampleRate, waveFormat.Channels, waveFormat.AverageBytesPerSecond, waveFormat.BlockAlign, waveFormat.BitsPerSample);
    }

    public int Read(float[] buffer, int offset, int count)
    {
        //If the requested amount of samples would go off the end of our data then clamp the count so its smaller.
        if (_position + count >= _samples.LongLength)
        {
            count = (int)(_samples.LongLength - _position);
        }

        //Copy the requested number of samples from our internal data to the buffer.
        Array.Copy(_samples, _position, buffer, offset, count);

        //Dont forget to move the position furthar along by how many samples were read.
        _position += count;

        //Finally return how many samples were read.
        return count;
    }
}
public static class Program
{
    public static void Main()
    {
        //Replace this line with your real code for getting the samples and format.
        float[] samples = new float[0];
        WaveFormat waveFormat = new WaveFormat();

        //Create an instance of our CustomSampleProvider class.
        CustomSampleProvider sampleProvider = new CustomSampleProvider(samples, waveFormat);

        //Create a WaveOutEvent for playing our sampleProvider.
        WaveOutEvent waveOutEvent = new WaveOutEvent();

        //Tell the WaveOutEvent to get ready to play our sampleProvider.
        waveOutEvent.Init(sampleProvider);

        waveOutEvent.Play();

        //Wait until the WaveOutEvent is done playing by checking if it's done every 100 miliseconds.
        while (waveOutEvent.PlaybackState == PlaybackState.Playing)
        {
            Thread.Sleep(100);
        }

        //Finally exit the program
        Environment.Exit(0);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文