zoukankan      html  css  js  c++  java
  • 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

    界面效果

  • 相关阅读:
    hdu 1524
    hdu 1536
    转载一篇博弈博弈入门的好文章
    nim 博弈
    WPF 从Main函数启动
    C# map network drive sample
    Predicate 学习
    WPF 绑定到附加属性 绑定到只读属性
    WPF 带有watermark的文本输入框
    使用Windows服务发布WCF服务
  • 原文地址:https://www.cnblogs.com/margin-gu/p/5442917.html
Copyright © 2011-2022 走看看