MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Визуализация звука с помощью библиотеки BASS на C#"
Answer 746793
Для получения графического представления звука нужно использовать метод BASS_ChannelGetData с флагом
BASS_DATA_FFT...
Метод возвращает массив амплитуд для набора диапазонов частот. Из него нужно отбросить первый элемент (0 Гц - это постоянная составляющая), и построить график по относительным значениям амплитуды и частоты.Пример кода для вывода графика в Windows Forms (на форме нужно поместить элементы Button, Panel и Timer):
using System; using System.Collections.Generic; using System.Drawing; using System.Text; using System.Windows.Forms; using Un4seen.Bass; namespace BassTest { public partial class Form1 : Form { public Form1() { InitializeComponent(); } int chan = 0;//номер потока Single[] fft=null;//массив данных спектра private void button1_Click(object sender, EventArgs e) { int n=Bass.BASS_GetDevice();//получаем устройство по умолчанию if (Bass.BASS_Init(n, 44100, 0, IntPtr.Zero) == false) { MessageBox.Show("BASS_Init failed"); return; } chan = Bass.BASS_StreamCreateFile(@"C:\MP3\file.mp3", 0, 0, BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_SAMPLE_LOOP);//создаем поток в режиме FLOAT if (chan == 0) { MessageBox.Show("BASS_StreamCreateFile failed"); return; } bool f; f = Bass.BASS_ChannelPlay(chan, false);//воспроизводим поток if (f == false) { MessageBox.Show("BASS_ChannelPlay failed"); return; } } private void timer1_Tick(object sender, EventArgs e)//запускаем каждые 500 мс { if (chan == 0) return; if (Bass.BASS_ChannelIsActive(chan) != BASSActive.BASS_ACTIVE_PLAYING) return; fft = new Single[2048];//выделяем массив для данных Bass.BASS_ChannelGetData(chan, fft, (int)BASSData.BASS_DATA_FFT4096);//получаем спектр потока fft[0] = 0.0f;//избавляемся от постоянной составляющей panel1.Refresh();//перерисовка графика } private void panel1_Paint(object sender, PaintEventArgs e)//построение графика { if (fft == null) return; PointF p1,p2; float max_y = 0;//максимальное значение амплитуды float min_y=Single.MaxValue;//минимальное значение амплитуды float max_x = fft.Length - 1;//максимальная частота, для которой амплитуда ненулевая int i = 0; max_x = 0; foreach(float f in fft)//находим максимальные и минимальные значения { if (f > max_y) max_y = f; if (f < min_y) min_y = f; if (f > 0.001f) max_x = (float)i; i++; } /*меняем направление оси Y, чтобы она смотрела вверх*/ e.Graphics.ScaleTransform(1.0f,-1.0f); e.Graphics.TranslateTransform(0.0f, -1.0f * panel1.Height); System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath(); float y; p1 = new PointF(0.0f, 0.0f);//начальная точка for (float x = 1; x <= max_x; x++) { y = fft[(int)x]; /*вычисляем координату следующей точки по относительной амплитуде*/ p2 = new PointF((x / max_x) * panel1.Width, panel1.Height * (y - min_y) / (max_y - min_y)); path.AddLine(p1, p2);//добавляем линию в график p1 = p2; } e.Graphics.DrawPath(Pens.Black, path); } } }
Выглядит так (не настолько красиво, как в WMP, но уже что-то):
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.