C# 声音时频图绘制

作者 : admin 本文共5846个字,预计阅读时间需要15分钟 发布时间: 2024-06-5 共3人阅读

C# 声音时频图绘制

C# 声音时频图绘制插图

采集PCM音频数据

音频原来自麦克风

音频源来自录音文件

处理PCM音频数据

使用 FftSharp.FFT 将PCM数据进行傅里叶变换

安装FftSharp框架

在Nuget包管理器中搜索FftSharp并安装C# 声音时频图绘制插图(1)

傅里叶变换

将采集到的PCM数据进行傅里叶变换

      // 傅里叶变换
      System.Numerics.Complex[] spectrum = FftSharp.FFT.Forward(audio);
      double[] ys = FftSharp.FFT.Magnitude(spectrum);

绘制时频图

采用自定义控件的方式来绘制时频图,核心代码如下:

/// 
/// 声音时频图
/// 
public class SoundTimeFreqControl : Control
{

    private const int MarginLeft = 40;
    private const int GradientWidth = 16;


    /// 
    /// 一共有多少格
    /// 
    private const int MaxColumn = 128;

    /// 
    /// 权重
    /// 
    private const int Weight = 0;

    private const int Amplitude = 23;

    // 创建一个画笔
    private Pen pen = new Pen(Brushes.Blue, 1);
    public Brush TextBrush = new SolidColorBrush(Colors.Gainsboro);
    public LinearGradientBrush GradientBrush;

    public double MaxFrequency { get; set; } = 24000;


    public SoundTimeFreqControl()
    {
        dbList = new Queue(MaxColumn);

        // 创建渐变色值
        GradientBrush = new LinearGradientBrush();
        GradientBrush.StartPoint = new Point(0, 0);
        GradientBrush.EndPoint = new Point(1, 1);

        // 添加渐变色值
        GradientStop gradientStop3 = new GradientStop(Colors.Yellow, 0);
        GradientStop gradientStop2 = new GradientStop(Colors.Red, 0.5);
        GradientStop gradientStop1 = new GradientStop(Colors.Blue, 1);
        GradientBrush.GradientStops.Add(gradientStop1);
        GradientBrush.GradientStops.Add(gradientStop2);
        GradientBrush.GradientStops.Add(gradientStop3);
    }

    public void Clear()
    {

    }

    public void Refresh()
    {
        this.InvalidateVisual();
    }


    // 数据源,用于存储折线图的数据
    private Queue dbList;

    public void AddDataList(double[] audio)
    {
        var data = new double[audio.Length / 4];

        int take = 1;
        for (int i = 0; take 

其他拓展类

FormatUtil

internal class FormatUtil
 {
     public static string Frequency(double freq)
     {
         if (freq < 1000)
         {
             return string.Format("{0}Hz", (int)freq);
         }
         else
         {
             var value = Math.Floor(freq / 1000);
             return string.Format("{0}kHz", value);
         }

     }
 }

DrawingContextExt

public static class DrawingContextExt
{
    public static void DrawRect(this DrawingContext drawingContext, Brush color, double x, double y, double w, double h)
    {
        drawingContext.DrawRectangle(null, new Pen(color, 1), new System.Windows.Rect(x, y, w, h));
    }

    public static void DrawLine(this DrawingContext drawingContext, Brush color, double x, double y, double x2, double y2)
    {
        drawingContext.DrawLine(new Pen(color, 1), new Point(x, y), new Point(x2, y2));
    }





    public static void FillEllipse(this DrawingContext drawingContext, Brush brush, double x, double y, double w, double h)
    {
        var radiusX = w / 2;
        var radiusY = h / 2;
        drawingContext.DrawEllipse(brush, null, new Point(x - radiusX, y - radiusY), radiusX, radiusY);
    }



    public static void DrawText(this DrawingContext drawingContext, string data, Brush brush, double x, double y, double emSize = 10)
    {
        // 创建FormattedText对象以设置文字的样式、位置和对齐方式
        FormattedText formattedText = new FormattedText(
            data,
            System.Globalization.CultureInfo.CurrentCulture,
            FlowDirection.LeftToRight,
            new Typeface("Arial"),
            emSize, brush);

        // 设置文字在 (50, 50) 的位置水平和垂直居中

        // 计算绘制点的坐标,使文本居中绘制
        Point drawPoint = new Point(x - formattedText.Width / 2, y - formattedText.Height / 2);

        // 绘制文字
        drawingContext.DrawText(formattedText, drawPoint);

    }
}
本站无任何商业行为
个人在线分享 » C# 声音时频图绘制
E-->