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入门学习的更多相关文章
- vue入门学习(基础篇)
vue入门学习总结: vue的一个组件包括三部分:template.style.script. vue的数据在data中定义使用. 数据渲染指令:v-text.v-html.{{}}. 隐藏未编译的标 ...
- Hadoop入门学习笔记---part4
紧接着<Hadoop入门学习笔记---part3>中的继续了解如何用java在程序中操作HDFS. 众所周知,对文件的操作无非是创建,查看,下载,删除.下面我们就开始应用java程序进行操 ...
- Hadoop入门学习笔记---part3
2015年元旦,好好学习,天天向上.良好的开端是成功的一半,任何学习都不能中断,只有坚持才会出结果.继续学习Hadoop.冰冻三尺,非一日之寒! 经过Hadoop的伪分布集群环境的搭建,基本对Hado ...
- PyQt4入门学习笔记(三)
# PyQt4入门学习笔记(三) PyQt4内的布局 布局方式是我们控制我们的GUI页面内各个控件的排放位置的.我们可以通过两种基本方式来控制: 1.绝对位置 2.layout类 绝对位置 这种方式要 ...
- PyQt4入门学习笔记(一)
PyQt4入门学习笔记(一) 一直没有找到什么好的pyqt4的教程,偶然在google上搜到一篇不错的入门文档,翻译过来,留以后再复习. 原始链接如下: http://zetcode.com/gui/ ...
- Hadoop入门学习笔记---part2
在<Hadoop入门学习笔记---part1>中感觉自己虽然总结的比较详细,但是始终感觉有点凌乱.不够系统化,不够简洁.经过自己的推敲和总结,现在在此处概括性的总结一下,认为在准备搭建ha ...
- Retrofit 入门学习
Retrofit 入门学习官方RetrofitAPI 官方的一个例子 public interface GitHubService { @GET("users/{user}/repos&qu ...
- MyBatis入门学习教程-使用MyBatis对表执行CRUD操作
上一篇MyBatis学习总结(一)--MyBatis快速入门中我们讲了如何使用Mybatis查询users表中的数据,算是对MyBatis有一个初步的入门了,今天讲解一下如何使用MyBatis对use ...
- opengl入门学习
OpenGL入门学习 说起编程作图,大概还有很多人想起TC的#include <graphics.h>吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640 ...
随机推荐
- 【java手记】------------------------java中转发和重定向区别
转发: request.getRequestDispatcher("success.jsp").forward(request,response); 在服务器组件收到用户请求后.经 ...
- Retrieving Out Params From a Stored Procedure With Python
http://www.rodneyoliver.com/blog/2013/08/08/retrieving-out-params-from-a-stored-procedure-with-pytho ...
- Mockups Mockplus 网页原型设计
http://www.cocoachina.com/cms/wap.php?action=article&id=15319
- 一个bug
bug原因: maven的project重新更新了一下project name,然后在更新过程中,卡死了,就强制退出.结果,就再也进不去eclipse了.看了eclipse的启动日志,各种报错,找不到 ...
- phpcms 移植【添加相关文章】功能
添加相关文章功能相当有用,移植一个过来基本上可以实现比较复杂的页面内包含分类功能,做二次开发时可以省下不少力气. 用例:如果一个产品,属于一个厂家,而这个厂家是动态添加的,既不是一个分类,而是一个厂家 ...
- Guava学习笔记:Immutable(不可变)集合
不可变集合,顾名思义就是说集合是不可被修改的.集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变. 为什么要用immutable对象?immutable对象有以下的优点: 1.对不可靠的客 ...
- 字符串模板替换方法 MessageFormat.format
String content = "ab,cc,{名称},{密码},{日期},dd,ff"; String array[] = {userName, password, forma ...
- 百度地图跟angular的结合
我现在做的一个项目是angular,但是我用直接引用百度地图的方法引进js,写html,js代码,发现,我去,报错了,我一开始还以为是百度地图跟angular有冲突,然后我就去搜索啊,发现angula ...
- something
var colors=['red','green','yellow']; console.log(colors)//['red','green','yellow'] console.log(color ...
- 从0开始学angularjs-笔记01
一.angularjs简介 AngularJS 是一个为动态WEB应用设计的结构框架.它能让你使用HTML作为模板语言,通过扩展HTML的语法,让你能更清楚.简洁地构建你的应用组件.它的创新点在于,利 ...