效果圖:
使用了 BASS.dll、 BASS.NET.dll 和 PeakMeterCtrl.dll
前面兩個負責播放 最后一個負責繪制頻譜,本文重點講的是頻譜部分,播放音頻部分注意一點就是,下載的兩個 bass文件 bass.dll是直接丟在debug目錄,bass.net.dll是通過項目引入進來的。
這里直接省略了找官網下載步驟。
完整代碼:

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