据说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入门学习的更多相关文章

  1. vue入门学习(基础篇)

    vue入门学习总结: vue的一个组件包括三部分:template.style.script. vue的数据在data中定义使用. 数据渲染指令:v-text.v-html.{{}}. 隐藏未编译的标 ...

  2. Hadoop入门学习笔记---part4

    紧接着<Hadoop入门学习笔记---part3>中的继续了解如何用java在程序中操作HDFS. 众所周知,对文件的操作无非是创建,查看,下载,删除.下面我们就开始应用java程序进行操 ...

  3. Hadoop入门学习笔记---part3

    2015年元旦,好好学习,天天向上.良好的开端是成功的一半,任何学习都不能中断,只有坚持才会出结果.继续学习Hadoop.冰冻三尺,非一日之寒! 经过Hadoop的伪分布集群环境的搭建,基本对Hado ...

  4. PyQt4入门学习笔记(三)

    # PyQt4入门学习笔记(三) PyQt4内的布局 布局方式是我们控制我们的GUI页面内各个控件的排放位置的.我们可以通过两种基本方式来控制: 1.绝对位置 2.layout类 绝对位置 这种方式要 ...

  5. PyQt4入门学习笔记(一)

    PyQt4入门学习笔记(一) 一直没有找到什么好的pyqt4的教程,偶然在google上搜到一篇不错的入门文档,翻译过来,留以后再复习. 原始链接如下: http://zetcode.com/gui/ ...

  6. Hadoop入门学习笔记---part2

    在<Hadoop入门学习笔记---part1>中感觉自己虽然总结的比较详细,但是始终感觉有点凌乱.不够系统化,不够简洁.经过自己的推敲和总结,现在在此处概括性的总结一下,认为在准备搭建ha ...

  7. Retrofit 入门学习

    Retrofit 入门学习官方RetrofitAPI 官方的一个例子 public interface GitHubService { @GET("users/{user}/repos&qu ...

  8. MyBatis入门学习教程-使用MyBatis对表执行CRUD操作

    上一篇MyBatis学习总结(一)--MyBatis快速入门中我们讲了如何使用Mybatis查询users表中的数据,算是对MyBatis有一个初步的入门了,今天讲解一下如何使用MyBatis对use ...

  9. opengl入门学习

    OpenGL入门学习 说起编程作图,大概还有很多人想起TC的#include <graphics.h>吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640 ...

随机推荐

  1. android版高仿淘宝客户端源码V2.3

    android版高仿淘宝客户端源码V2.3,这个版本我已经更新到2.3了,源码也上传到源码天堂那里了,大家可以看一下吧,该应用实现了我们常用的购物功能了,也就是在手机上进行网购的流程的,如查看产品(浏 ...

  2. java servlet手机app访问接口(二)短信验证

    今天找了几个短信平台,其实最想使用的一个是sharesdk,使用它上面http api短信功能,不仅价格低,而且最少可以充值100RMB,但是审核过于严格,对应APP还必须集成他们的短信功能,而且要上 ...

  3. sp_get_menu函数使用分析

    function sp_get_menu($id="main",$effected_id="mainmenu",$filetpl="<span ...

  4. CI框架源码阅读笔记9 CI的自动加载机制autoload

    本篇并不是对某一组件的详细源码分析,而只是简单的跟踪了下CI的autoload的基本流程.因此,可以看做是Loader组件的分析前篇. CI框架中,允许你配置autoload数组,这样,在你的应用程序 ...

  5. static关键字详解

    首先,要了解一下这些东西的存放位置 堆区: 1.存储的全部是对象,每个对象都包含一个与之对应的class的信息.(class的目的是得到操作指令) 2.jvm只有一个堆区(heap)被所有线程共享,堆 ...

  6. Linux下安装DB2_v9.7详细教程

    一:平台 1:HP服务器 cpu:Inter (R) Xeon (R) E5606 2.13G 磁盘:本地磁盘外加存储 2:操作系统 RedHet 5.4 64位 内核:2.6.18-194.1.AX ...

  7. mesos 学习笔记1 -- mesos安装和配置

    参考资料: 官方文档:http://mesos.apache.org/documentation 中文翻译:http://mesos.mydoc.io/ GitHub:https://github.c ...

  8. C语言之字符串处理函数

    C语言中字符串处理函数介绍 下面介绍8种基本的常用的字符串处理函数,在数值数组中也常常用到(部分函数).所有的C语言编译系统中一般都提供这些函数. 1.puts函数——输出字符串的函数 一般的形式为p ...

  9. 使用 WordPress 插件模板开发高质量插件

    WordPress 插件样板是标准化的,有组织的,面向对象的基础,用于构建高品质的 WordPress 插件.样板遵循编码标准和文件标准,所以你不必自己学习这些,根据注释编写代码即可. 官方网站    ...

  10. C++11新特性 lambda表达式

    C++11 添加了了一个名为lambda表达式的功能,可以用于添加匿名函数 语法: [capture_block](parameter) mutable exception_specification ...