效果图:
使用了 BASS.dll、 BASS.NET.dll 和 PeakMeterCtrl.dll
前面两个负责播放 最后一个负责绘制频谱,本文重点讲的是频谱部分,播放音频部分注意一点就是,下载的两个 bass文件 bass.dll是直接丢在debug目录,bass.net.dll是通过项目引入进来的。
这里直接省略了找官网下载步骤。
完整代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Windows.Forms; 3 using Un4seen.Bass; 4 5 namespace WindowsFormsApp3 6 { 7 public partial class Form1 : Form 8 { 9 public Form1() 10 { 11 InitializeComponent(); 12 } 13 14 private void Form1_Load(object sender, EventArgs e) 15 { 16 //启动频谱(参数是响应延迟,数字越小,音柱回起速度越快) 17 peakMeterCtrl1.Start(1000 / Int32.Parse(cbo_fps.Text)); 18 19 //-1 表示 默认设备输出 20 //44100 表示 输出采样率 21 //BASS_DEVICE_CPSPEAKERS 表示输出模式 22 if (!Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_CPSPEAKERS, this.Handle)) 23 { 24 MessageBox.Show("出错了," + Bass.BASS_ErrorGetCode().ToString()); 25 } 26 27 Timer t = new Timer(); 28 t.Interval = 1; 29 t.Tick += T_Tick; 30 t.Start(); 31 } 32 33 string fileName; 34 int stream; 35 36 private void btn_open_Click(object sender, EventArgs e) 37 { 38 OpenFileDialog o = new OpenFileDialog(); 39 if (o.ShowDialog() == DialogResult.OK) 40 { 41 fileName = o.FileName; 42 43 //第一个参数是文件名, 44 //第二个参数是文件流开始位置, 45 //第三个是文件流长度 0为使用文件整个长度, 46 //最后一个是流的创建模式 47 stream = Bass.BASS_StreamCreateFile(fileName, 0L, 0L, BASSFlag.BASS_SAMPLE_FLOAT); 48 } 49 } 50 51 52 private void btn_play_Click(object sender, EventArgs e) 53 { 54 Bass.BASS_ChannelPlay(stream, true); //开始播放 55 } 56 57 private void btn_pause_Click(object sender, EventArgs e) 58 { 59 Bass.BASS_ChannelPause(stream);//音乐暂停 60 } 61 62 private void btn_resume_Click(object sender, EventArgs e) 63 { 64 Bass.BASS_ChannelPlay(stream, false); 65 } 66 67 private void btn_stop_Click(object sender, EventArgs e) 68 { 69 Bass.BASS_ChannelStop(stream); //停止播放 70 } 71 72 private void btn_close_Click(object sender, EventArgs e) 73 { 74 Bass.BASS_Stop(); //停止所有输出 75 Bass.BASS_Free(); //释放所有资源 76 77 if (!Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_CPSPEAKERS, this.Handle)) 78 { 79 MessageBox.Show("出错了," + Bass.BASS_ErrorGetCode().ToString()); 80 } 81 } 82 83 private void btn_test_Click(object sender, EventArgs e) 84 { 85 this.peakMeterCtrl1.SetRange(33, 66, 100); 86 } 87 88 private void Form1_FormClosing(object sender, FormClosingEventArgs e) 89 { 90 Bass.BASS_ChannelStop(stream); //停止播放 91 Bass.BASS_StreamFree(stream); //释放音频流 92 Bass.BASS_Stop(); //停止所有输出 93 Bass.BASS_Free(); //释放所有资源 94 } 95 96 const int BandsCount = 128; 97 int[] FFTPeacks = new int[BandsCount]; 98 int[] FFTFall = new int[BandsCount]; 99 int rate = 1500; 100 101 /// <summary> 102 /// 用计时器绘制频谱(如果有更好的思路欢迎留言) 103 /// </summary> 104 /// <param name="sender"></param> 105 /// <param name="e"></param> 106 private void T_Tick(object sender, EventArgs e) 107 { 108 if (Bass.BASS_ChannelIsActive(stream) != BASSActive.BASS_ACTIVE_PLAYING) return; 109 int[] FFTFall = Array.ConvertAll<float, int>(GetFFTData(), delegate (float f) { return (int)Math.Abs(f * rate); }); 110 this.peakMeterCtrl1.SetData(FFTFall, 0, FFTFall.Length); 111 } 112 113 // 获取FFT采样数据,返回128个浮点采样数据 114 public float[] GetFFTData() 115 { 116 float[] fft = new float[BandsCount]; 117 Bass.BASS_ChannelGetData(stream, fft, (int)BASSData.BASS_DATA_FFT256); 118 return fft; 119 } 120 121 private void cbo_fps_SelectedIndexChanged(object sender, EventArgs e) 122 { 123 peakMeterCtrl1.Stop(); 124 peakMeterCtrl1.Start(1000 / Int32.Parse(cbo_fps.Text)); //fps 125 } 126 127 private void numericUpDown1_ValueChanged(object sender, EventArgs e) 128 { 129 rate = Int32.Parse(numericUpDown1.Value.ToString()); //增益效果 130 } 131 132 private void txt_LEDCount_TextChanged(object sender, EventArgs e) 133 { 134 peakMeterCtrl1.LEDCount = Convert.ToInt32(txt_LEDCount.Text);//纵向格子数量 135 } 136 137 private void txt_BANDSCount_TextChanged(object sender, EventArgs e) 138 { 139 peakMeterCtrl1.BandsCount = Convert.ToInt32(txt_BANDSCount.Text); //横向格子数量 140 } 141 142 private void cheb_ShowGrid_CheckedChanged(object sender, EventArgs e) 143 { 144 peakMeterCtrl1.ShowGrid = cheb_ColoredGrid.Enabled = cheb_ShowGrid.Checked; //显示背景格子 145 } 146 147 private void cheb_ColoredGrid_CheckedChanged(object sender, EventArgs e) 148 { 149 peakMeterCtrl1.ColoredGrid = cheb_ColoredGrid.Checked; //显示彩色背景格子 150 } 151 152 private void cheb_FalloffEffect_CheckedChanged(object sender, EventArgs e) 153 { 154 peakMeterCtrl1.FalloffEffect = cheb_FalloffEffect.Checked; //显示回落效果 155 } 156 } 157 158 159 160 }
最后附上网盘下载地址:https://pan.baidu.com/s/1xQI2YTeYN-SUghhC1gCH_g 提取码: iirb