c# bass入门学习

据说bass挺好用的,所以又搞了个音乐播放器

这是参考了别人的bass教学结合自己的理解写的bass操作类

public class BassHelper
    {
        private static BassHelper bassHelper;
        static string fileName;//全路径文件名
        static int stream = 0; //音频流句柄

        public static BassHelper BassInit(int deviceId, int rate, BASSInit bassInit, IntPtr intPtr)
        {
            if (bassHelper == null)
            {
                bassHelper = new BassHelper(deviceId, rate, bassInit, intPtr);
            }
            return bassHelper;
        }

        public BassHelper(int deviceId, int rate, BASSInit bassInit, IntPtr intPtr)
        {
            if (!Bass.BASS_Init(deviceId, rate, bassInit, intPtr))
            {
                throw new ApplicationException(" Bass初始化出错! " + Bass.BASS_ErrorGetCode().ToString());
            }
        }

        //创建音频流
        public static void CreateStream()
        {
            if (stream != 0)
            {
                if (Bass.BASS_ChannelIsActive(stream) == BASSActive.BASS_ACTIVE_PLAYING || Bass.BASS_ChannelIsActive(stream) == BASSActive.BASS_ACTIVE_PAUSED)
                {
                    Bass.BASS_ChannelStop(stream);
                }
                Bass.BASS_StreamFree(stream);
            }
            stream = Bass.BASS_StreamCreateFile(fileName, 0L, 0L, BASSFlag.BASS_MUSIC_FLOAT);
        }

        //全路径文件名
        public static string FileName
        {
            get { return fileName; }
            set { fileName = value; }
        }

        //播放
        public static void Play(bool restart)
        {
            Bass.BASS_ChannelPlay(stream, restart);
        }
        //停止
        public static void Stop()
        {
            if (stream != 0 && Bass.BASS_ChannelIsActive(stream) != BASSActive.BASS_ACTIVE_STOPPED)
            {
                Bass.BASS_ChannelStop(stream);
            }
        }
        //暂停
        public static void Puase()
        {
            if (Bass.BASS_ChannelIsActive(stream) == BASSActive.BASS_ACTIVE_PLAYING)
            {
                Bass.BASS_ChannelPause(stream);
            }
        }
        //总时间
        public static double Duration
        {
            get { return Bass.BASS_ChannelBytes2Seconds(stream, Bass.BASS_ChannelGetLength(stream)); }
        }

        //当前时间
        public static double CurrentPosition
        {
            get { return Bass.BASS_ChannelBytes2Seconds(stream, Bass.BASS_ChannelGetPosition(stream)); }
            set { Bass.BASS_ChannelSetPosition(stream, value); }
        }

        //音量
        public static int Volume
        {
            get { return Bass.BASS_GetConfig(BASSConfig.BASS_CONFIG_GVOL_STREAM) / 100; }
            set { Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_GVOL_STREAM, value * 100); }
        }

        //歌曲信息
        public static MusicTags GetMusicTags(string fileName)
        {
            MusicTags mt = new MusicTags();
            mt.FileName = fileName;
            int channel = Bass.BASS_StreamCreateFile(fileName, 0, 0, BASSFlag.BASS_SAMPLE_FLOAT);
            string[] tags = Bass.BASS_ChannelGetTagsID3V1(channel);
            if (tags != null)
            {
                mt.Title = tags[0];
                mt.Artist = tags[1];
                mt.Album = tags[2];
                mt.Year = tags[3];
                mt.Comment = tags[4];
                if (!string.IsNullOrEmpty(tags[5]))
                {
                    int gId = 12;
                    int.TryParse(tags[5], out gId);
                    if (gId < 0 || gId >= MusicTags.ID3v1Genre.Length)
                    {
                        gId = 12;
                    }
                    mt.Genre = MusicTags.ID3v1Genre[gId];
                }
            }
            return mt;
        }


        //播放进度0—1
        public static double Schedule
        {
            get
            {
                double schedule = 0;//播放进度
                if (stream == 0 || Bass.BASS_ChannelBytes2Seconds(stream, Bass.BASS_ChannelGetPosition(stream)) == -1)
                {
                    schedule = 0;
                }
                else
                {
                    schedule = Bass.BASS_ChannelBytes2Seconds(stream, Bass.BASS_ChannelGetPosition(stream)) / Bass.BASS_ChannelBytes2Seconds(stream, Bass.BASS_ChannelGetLength(stream));
                }
                return schedule;
            }
            set
            {
                double temp = value * Bass.BASS_ChannelBytes2Seconds(stream, Bass.BASS_ChannelGetLength(stream));
                Bass.BASS_ChannelSetPosition(stream, Bass.BASS_ChannelSeconds2Bytes(stream, temp));
            }
        }

        // 获取FFT采样数据,返回512个浮点采样数据
        public static float[] GetFFTData()
        {
            float[] fft = new float[512];
            Bass.BASS_ChannelGetData(stream, fft, (int)BASSData.BASS_DATA_FFT1024);
            return fft;
        }


        // 当前播放状态
        public static PlayStates PlayState
        {
            get
            {
                PlayStates state = PlayStates.Stopped;
                switch (Bass.BASS_ChannelIsActive(stream))
                {
                    case BASSActive.BASS_ACTIVE_PAUSED:
                        state = PlayStates.Pause;
                        break;
                    case BASSActive.BASS_ACTIVE_PLAYING:
                        state = PlayStates.Play;
                        break;
                    case BASSActive.BASS_ACTIVE_STALLED:
                        state = PlayStates.Stalled;
                        break;
                    case BASSActive.BASS_ACTIVE_STOPPED:
                        state = PlayStates.Stopped;
                        break;
                }
                return state;
            }
        }

        //加载插件
        public static bool LoadBasic(string path)
        {
            int handle = Bass.BASS_PluginLoad(path);
            if (handle != 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public static void Dispose(object obj)
        {
            Bass.BASS_ChannelStop(stream);
            Bass.BASS_StreamFree(stream);
            Bass.BASS_Stop();    //停止
            Bass.BASS_Free();    //释放
            GC.SuppressFinalize(obj);
        }
    }
    /// <summary>
    /// 播放状态枚举
    /// </summary>
    public enum PlayStates
    {
        /// <summary>
        /// 正在播放
        /// </summary>
        Play = BASSActive.BASS_ACTIVE_PLAYING,
        /// <summary>
        /// 暂停
        /// </summary>
        Pause = BASSActive.BASS_ACTIVE_PAUSED,
        /// <summary>
        /// 停止
        /// </summary>
        Stopped = BASSActive.BASS_ACTIVE_STOPPED,
        /// <summary>
        /// 延迟
        /// </summary>
        Stalled = BASSActive.BASS_ACTIVE_STALLED,
    }
BassHelper

用之前要先初始化

BassHelper.BassInit(-1, 44100, BASSInit.BASS_DEVICE_CPSPEAKERS, this.Handle);

Win32

#region API声明
    class Win32
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct Size
        {
            public Int32 cx;
            public Int32 cy;

            public Size(Int32 x, Int32 y)
            {
                cx = x;
                cy = y;
            }
        }

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct BLENDFUNCTION
        {
            public byte BlendOp;
            public byte BlendFlags;
            public byte SourceConstantAlpha;
            public byte AlphaFormat;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct Point
        {
            public Int32 x;
            public Int32 y;

            public Point(Int32 x, Int32 y)
            {
                this.x = x;
                this.y = y;
            }
        }

        public const byte AC_SRC_OVER = 0;
        public const Int32 ULW_ALPHA = 2;
        public const byte AC_SRC_ALPHA = 1;

        [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern IntPtr CreateCompatibleDC(IntPtr hDC);

        [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern IntPtr GetDC(IntPtr hWnd);

        [DllImport("gdi32.dll", ExactSpelling = true)]
        public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObj);

        [DllImport("user32.dll", ExactSpelling = true)]
        public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);

        [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern int DeleteDC(IntPtr hDC);

        [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern int DeleteObject(IntPtr hObj);

        [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern int UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, ref Point pptDst, ref Size psize, IntPtr hdcSrc, ref Point pptSrc, Int32 crKey, ref BLENDFUNCTION pblend, Int32 dwFlags);

        [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern IntPtr ExtCreateRegion(IntPtr lpXform, uint nCount, IntPtr rgnData);
    }
    #endregion
Win32

 

还有几个问题:

1.加载的解码器插件不工作

原因:我用的是64位的,结果加载的是32位的

2.本来打算用UpdateLayeredWindow画不规则窗体的,结果控件都出不来了,用了简单的,结果好多毛边

解决:获得控件图片,再画上去,进度条当值改变时,就重新画一遍

3.进度条好难看,下次重写个

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace MusicBar
{
    public partial class MusicBar: UserControl
    {
        private Color backgroundColor = Color.White;//进度条背景颜色
        private Color foregroundColor = Color.Gray;//进度条前景颜色
        private Color setRectColor = Color.Black;//控制块颜色
        private Color borderColor = Color.Black;//边框颜色
        private int maximum = 100;//最大值
        private int minimum = 0;//最小值
        private double myValue = 0.0;//进度值
        private Rectangle foreRect;//前景方块
        private Rectangle backRect;//背景方块
        private Rectangle setRect;//控制方块
        protected EventHandler OnValueChanged;//当进度值改变事件
        private Point originPoint;//当前鼠标位置
        private Point originsetRectPoint;//当前控制块位置
        private bool setRectDown = false;//控制块是否点下

        public MusicBar()
        {
            InitializeComponent();

            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, true);

            this.MouseDown += new MouseEventHandler(this.MySlider_MouseDown);
            this.MouseMove += new MouseEventHandler(this.MySlider_MouseMove);
            this.MouseUp += new MouseEventHandler(this.MySlider_MouseUp);

            this.BackColor = Color.Transparent;
        }

        #region 属性

        [Category("进度条"), Description("进度条的最大值"), Browsable(true)]
        public int Maximum
        {
            get { return maximum; }
            set
            {
                maximum = value;
                Invalidate();
            }
        }

        [Category("进度条"), Description("进度条的最小值"), Browsable(true)]
        public int Minimum
        {
            get { return minimum; }
            set
            {
                minimum = value;
                Invalidate();
            }
        }

        [Category("进度条"), Description("进度条的背景色,总长度(底部白色矩形)"), Browsable(true)]
        public Color BackgroundColor
        {
            get { return backgroundColor; }
            set
            {
                this.backgroundColor = value;
                Invalidate();
            }
        }

        [Category("进度条"), Description("进度条的前景色,已加载长度(灰色矩形)"), Browsable(true)]
        public Color ForegroundColor
        {
            get { return foregroundColor; }
            set
            {
                this.foregroundColor = value;
                Invalidate();
            }
        }

        [Category("进度条"), Description("进度条控制块的颜色(黑色矩形)"), Browsable(true)]
        public Color SetRectColor
        {
            get { return setRectColor; }
            set
            {
                this.setRectColor = value;
                Invalidate();
            }
        }

        [Category("进度条"), Description("进度条边框的颜色(黑色)"), Browsable(true)]
        public Color SetBorderColor
        {
            get { return borderColor; }
            set
            {
                this.borderColor = value;
                Invalidate();
            }
        }

        [Category("General"), Description("控件的宽度"), Browsable(true)]
        public new int Width
        {
            get { return base.Width; }
            set
            {
                base.Width = value;
                setRect.Width = base.Height/10*9;
                foreRect.X = backRect.X = setRect.Width / 2;
                backRect.Width = base.Width - setRect.Width - (base.Height - setRect.Width);
                foreRect.Width = (int)(myValue / maximum * backRect.Width);
                setRect.X = foreRect.Width;

                Invalidate();
            }
        }

        [Category("General"), Description("控件的高度"), Browsable(true)]
        public new int Height
        {
            get { return base.Height; }
            set
            {
                base.Height = value;
                setRect.Height = base.Height / 10 * 9;
                setRect.Y = (base.Height - setRect.Height) / 2;
                foreRect.Height = backRect.Height = setRect.Height / 4;
                foreRect.Y = backRect.Y = (base.Height - backRect.Height) / 2;
                Invalidate();
            }
        }

        [Category("进度条"), Description("进度条的值"), Browsable(true)]
        public double Value
        {
            get { return myValue; }
            set
            {
                if (myValue < Minimum)
                    throw new ArgumentException("小于最小值");
                if (myValue > Maximum)
                    throw new ArgumentException("超过最大值");

                myValue = value;
                foreRect.Width = (int)(myValue / maximum * backRect.Width);

                if ((myValue - maximum) > 0)
                {
                    foreRect.Width = backRect.Width;
                }

                if ((myValue - minimum) < 0)
                {
                    foreRect.Width = 0;
                }

                setRect.X = foreRect.Width;

                //如果添加了响应函数,则执行该函数
                if (OnValueChanged != null)
                {
                    OnValueChanged(this, EventArgs.Empty);
                }

                Invalidate();
            }
        }

        #endregion

        public event EventHandler ValueChanged
        {
            add
            {
                if (OnValueChanged != null)
                {
                    foreach (Delegate d in OnValueChanged.GetInvocationList())
                    {
                        if (object.ReferenceEquals(d, value)) { return; }
                    }
                }
                OnValueChanged = (EventHandler)Delegate.Combine(OnValueChanged, value);
            }
            remove
            {
                OnValueChanged = (EventHandler)Delegate.Remove(OnValueChanged, value);
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            this.DrawRect(e.Graphics);
        }

        private void DrawRect(Graphics e)
        {
            Pen pen = new Pen(borderColor);
            e.FillRectangle((Brush)new SolidBrush(this.backgroundColor), this.backRect);
            e.DrawRectangle(pen, this.backRect);
            e.FillRectangle((Brush)new SolidBrush(this.foregroundColor), this.foreRect);
            e.DrawRectangle(pen, this.foreRect);
            e.FillEllipse((Brush)new SolidBrush(this.setRectColor), this.setRect);
            e.DrawEllipse(pen, this.setRect);
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            this.Width = this.Width;
            this.Height = this.Height;
            this.Invalidate();
        }

        private void MySlider_MouseUp(object sender, MouseEventArgs e)
        {
            this.setRectDown = false;
        }

        private void MySlider_MouseMove(object sender, MouseEventArgs e)
        {
            if (setRectDown)
            {
                //移动长度
                int dd = e.Location.X - originPoint.X;
                //百分比
                double percent = (double)(originsetRectPoint.X + dd - this.backRect.X) / this.backRect.Width;
                if (percent < 0)
                {
                    percent = 0;
                }
                else if (percent > 1)
                {
                    percent = 1;
                }
                this.Value = percent * maximum;
                this.foreRect.Width = (int)(percent * this.backRect.Width);
                //this.setRect.X = originsetRectPoint.X + dd;
                this.setRect.X = foreRect.Width;
                Invalidate();
            }
        }

        private void MySlider_MouseDown(object sender, MouseEventArgs e)
        {
            if (setRect.Contains(e.Location))
            {
                this.originPoint = e.Location;
                originsetRectPoint = this.setRect.Location;
                this.setRectDown = true;
            }
        }
    }
}
MusicBar

 

代码

http://pan.baidu.com/s/1o8tzUkE

参考

http://tieba.baidu.com/p/2643045626

 

 

界面效果

posted @ 2016-04-28 15:43  margin_gu  阅读(1868)  评论(1编辑  收藏  举报