Pregunta

Me gustaría crear un sistema de visualización de sonido usando el lenguaje C # y .NET Framework. Esto podría ser similar en la aplicación Winamp. Tal vez existan biblioteca libre o algunos artículos interesantes que describen cómo hacerlo? Ejemplo: texto alt http://img44.imageshack.us/img44/9982/examplel.png

¿Fue útil?

Solución

Puede probar estos enlaces

OpenVP (es una plataforma libre y de código abierto para el desarrollo de visualizaciones de música, escrito en C #), consulte la OpenVP Imágenes .

visualizador de sonido en C #

Play y visualizar archivos WAV utilizando Managed Direct Sound

adiós.

Otros consejos

Aquí hay un script que calcula la FFT de cualquier sonido que se reproduce en el ordenador utilizando la API WASAPI. Utiliza CPuntuacion y su WinformsVisualization ejemplo:

using CSCore;
using CSCore.SoundIn;
using CSCore.Codecs.WAV;
using WinformsVisualization.Visualization;
using CSCore.DSP;
using CSCore.Streams;
using System;

public class SoundCapture
{

    public int numBars = 30;

    public int minFreq = 5;
    public int maxFreq = 4500;
    public int barSpacing = 0;
    public bool logScale = true;
    public bool isAverage = false;

    public float highScaleAverage = 2.0f;
    public float highScaleNotAverage = 3.0f;



    LineSpectrum lineSpectrum;

    WasapiCapture capture;
    WaveWriter writer;
    FftSize fftSize;
    float[] fftBuffer;

    SingleBlockNotificationStream notificationSource;

    BasicSpectrumProvider spectrumProvider;

    IWaveSource finalSource;

    public SoundCapture()
    {

        // This uses the wasapi api to get any sound data played by the computer
        capture = new WasapiLoopbackCapture();

        capture.Initialize();

        // Get our capture as a source
        IWaveSource source = new SoundInSource(capture);


        // From https://github.com/filoe/cscore/blob/master/Samples/WinformsVisualization/Form1.cs

        // This is the typical size, you can change this for higher detail as needed
        fftSize = FftSize.Fft4096;

        // Actual fft data
        fftBuffer = new float[(int)fftSize];

        // These are the actual classes that give you spectrum data
        // The specific vars of lineSpectrum here aren't that important because they can be changed by the user
        spectrumProvider = new BasicSpectrumProvider(capture.WaveFormat.Channels,
                    capture.WaveFormat.SampleRate, fftSize);

        lineSpectrum = new LineSpectrum(fftSize)
        {
            SpectrumProvider = spectrumProvider,
            UseAverage = true,
            BarCount = numBars,
            BarSpacing = 2,
            IsXLogScale = false,
            ScalingStrategy = ScalingStrategy.Linear
        };

        // Tells us when data is available to send to our spectrum
        var notificationSource = new SingleBlockNotificationStream(source.ToSampleSource());

        notificationSource.SingleBlockRead += NotificationSource_SingleBlockRead;

        // We use this to request data so it actualy flows through (figuring this out took forever...)
        finalSource = notificationSource.ToWaveSource();

        capture.DataAvailable += Capture_DataAvailable;
        capture.Start();
    }

    private void Capture_DataAvailable(object sender, DataAvailableEventArgs e)
    {
        finalSource.Read(e.Data, e.Offset, e.ByteCount);
    }

    private void NotificationSource_SingleBlockRead(object sender, SingleBlockReadEventArgs e)
    {
        spectrumProvider.Add(e.Left, e.Right);
    }

    ~SoundCapture()
    {
        capture.Stop();
        capture.Dispose();
    }

    public float[] barData = new float[20];

    public float[] GetFFtData()
    {
        lock (barData)
        {
            lineSpectrum.BarCount = numBars;
            if (numBars != barData.Length)
            {
                barData = new float[numBars];
            }
        }

        if (spectrumProvider.IsNewDataAvailable)
        {
            lineSpectrum.MinimumFrequency = minFreq;
            lineSpectrum.MaximumFrequency = maxFreq;
            lineSpectrum.IsXLogScale = logScale;
            lineSpectrum.BarSpacing = barSpacing;
            lineSpectrum.SpectrumProvider.GetFftData(fftBuffer, this);
            return lineSpectrum.GetSpectrumPoints(100.0f, fftBuffer);
        }
        else
        {
            return null;
        }
    }

    public void ComputeData()
    {


        float[] resData = GetFFtData();

        int numBars = barData.Length;

        if (resData == null)
        {
            return;
        }

        lock (barData)
        {
            for (int i = 0; i < numBars && i < resData.Length; i++)
            {
                // Make the data between 0.0 and 1.0
                barData[i] = resData[i] / 100.0f;
            }

            for (int i = 0; i < numBars && i < resData.Length; i++)
            {
                if (lineSpectrum.UseAverage)
                {
                    // Scale the data because for some reason bass is always loud and treble is soft
                    barData[i] = barData[i] + highScaleAverage * (float)Math.Sqrt(i / (numBars + 0.0f)) * barData[i];
                }
                else
                {
                    barData[i] = barData[i] + highScaleNotAverage * (float)Math.Sqrt(i / (numBars + 0.0f)) * barData[i];
                }
            }
        }

    }
}

A continuación, al recuperar la barData de un guión diferente se recomienda para bloquearlo primero desde este se modifica en un hilo separado.

No estoy seguro de dónde saqué GetSpectrumPoints ya que no parece estar en el Github Repo , pero aquí está. Sólo pega esto en ese archivo y mi código debería funcionar.

public float[] GetSpectrumPoints(float height, float[] fftBuffer)
{
    SpectrumPointData[] dats = CalculateSpectrumPoints(height, fftBuffer);
    float[] res = new float[dats.Length];
    for (int i = 0; i < dats.Length; i++)
    {
        res[i] = (float)dats[i].Value;
    }

    return res;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top