c# bass入门学习

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

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

public class BassHelper
{
private static BassHelper bassHelper;
static string fileName;//全路径文件名
static int stream = ; //音频流句柄 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 != )
{
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 != && 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) / ; }
set { Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_GVOL_STREAM, value * ); }
} //歌曲信息
public static MusicTags GetMusicTags(string fileName)
{
MusicTags mt = new MusicTags();
mt.FileName = fileName;
int channel = Bass.BASS_StreamCreateFile(fileName, , , BASSFlag.BASS_SAMPLE_FLOAT);
string[] tags = Bass.BASS_ChannelGetTagsID3V1(channel);
if (tags != null)
{
mt.Title = tags[];
mt.Artist = tags[];
mt.Album = tags[];
mt.Year = tags[];
mt.Comment = tags[];
if (!string.IsNullOrEmpty(tags[]))
{
int gId = ;
int.TryParse(tags[], out gId);
if (gId < || gId >= MusicTags.ID3v1Genre.Length)
{
gId = ;
}
mt.Genre = MusicTags.ID3v1Genre[gId];
}
}
return mt;
} //播放进度0—1
public static double Schedule
{
get
{
double schedule = ;//播放进度
if (stream == || Bass.BASS_ChannelBytes2Seconds(stream, Bass.BASS_ChannelGetPosition(stream)) == -)
{
schedule = ;
}
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[];
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 != )
{
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(-, , 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 = )]
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 = ;
public const Int32 ULW_ALPHA = ;
public const byte AC_SRC_ALPHA = ; [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 = ;//最大值
private int minimum = ;//最小值
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/*;
foreRect.X = backRect.X = setRect.Width / ;
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 / * ;
setRect.Y = (base.Height - setRect.Height) / ;
foreRect.Height = backRect.Height = setRect.Height / ;
foreRect.Y = backRect.Y = (base.Height - backRect.Height) / ;
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) > )
{
foreRect.Width = backRect.Width;
} if ((myValue - minimum) < )
{
foreRect.Width = ;
} 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 < )
{
percent = ;
}
else if (percent > )
{
percent = ;
}
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

界面效果

c# bass入门学习

上一篇:ESP8266 TCP传输AT指令顺序


下一篇:vue的指令绑定、事件、冒泡