65.9K
CodeProject 正在变化。 阅读更多。
Home

在声音中绘图

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.71/5 (27投票s)

2008年12月21日

CPOL

2分钟阅读

viewsIcon

115975

downloadIcon

5731

本文演示了如何在音频文件的频谱表示中绘制图形。

引言

这个想法是将图像绘制到声音中。特别是,将图像绘制到声音的频谱表示中。声音可以用多种方式表示。特别是,可以用振幅-时间表示 (波形)频率-时间表示 (频谱) 来绘制。前者显示声音在时间上的振幅

X 轴是时间,而 Y 轴是声音的振幅。另一种视图将音频信号显示为不同频率的组成部分

这里,X 轴是时间,而 Y 轴是频率。特别是,较浅的颜色(白色)表示特定频率分量的较高值,而较深的颜色(黑色)表示较低分量。在这里,可以看到声音在时间和频率上的变化。

快速傅里叶变换

傅里叶变换是一种将信号(在本例中为音频信号)转换为其频率域表示的操作。因此,可以查看输入信号中存在哪些频率。FFT 是一种有效地计算傅里叶变换的算法。

逆运算(逆快速傅里叶变换)从频率域获取数据,并给出时间域中的值。我们可以使用此算法来绘制声音。只需将绘制视为输入,就像它是信号的频谱表示一样。然后,我们应用 IFFT 算法,并检索音频波形,用于创建输出波文件。

程序

黑板是音频信号的频率-时间表示。可以使用开始按钮左侧的条形的颜色对其进行绘制。单击条形,可以更改颜色。使用较深的颜色(如深灰色)可以获得最佳效果。单击“开始”按钮后,IFFT 算法开始计算数据,并生成输出音频文件。

随便画点什么

我们可以使用 Cooledit 等程序查看结果。

Fig6.jpg

代码

该程序是用 C# 编写的。我们在这里使用两个基本库

  • Wave File Library 由 Garrett Hoofman 编写。该库已被用于生成 Wav 输出文件。
  • 一个实现 IFFT 算法的库。
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WaveLibrary;

namespace Img2Wav
{
    class Core_Img2Wav
    {
        
        private const double MAX_DATA = +50;
        private const double MIN_DATA = -50;

        private const String NoInputBitmap = "No input bitmap";

        public Bitmap InputBitmap { get; set; }
        public WaveFile OutputWav { get; set; }

        public void Start()
        {
            int NumSamples = InputBitmap.Width * InputBitmap.Height;
            byte[] Samples = new byte[NumSamples];
            OutputWav = new WaveFile(1, 16, 44000);
            if (InputBitmap == null) throw new Exception(NoInputBitmap);
            double[] data = new double[InputBitmap.Height];

            int w = 0;
            for (int i = 0; i < InputBitmap.Width; i++) 
            {
                for (int j = 0; j < InputBitmap.Height; j++)
                {
                    Color C = InputBitmap.GetPixel(i,j);
                    data[j] = (C.R + C.G + C.B ) / 3;
                }

                FFT_Img2Wav.inverse(data);
                                
                for (int x = 0; x < data.Length; x++)
                {
                    Samples[w] = (byte)(MAX_DATA * data[x]);
                    w++;
                }
            }

            OutputWav.SetData(Samples,NumSamples);
        }
    }
}
绘制到声音 - CodeProject - 代码之家
© . All rights reserved.