public static void FreePlugin() { if (_pluginHandleFilePathDic == null || _pluginHandleFilePathDic.Count == 0) { return; } //这种方式一次性释放完,但是那个出错了就不知道了,所以还是用后面这种释放吧 //bool result = NativeMethods.BASS_PluginFree(0); //if (result) //{ // _pluginHandleFilePathDic.Clear(); //} //else //{ // throw new WavException(BassErrorCode.GetErrorInfo()); //} int[] pluginHandleArr = _pluginHandleFilePathDic.Keys.ToArray(); foreach (var pluginHandle in pluginHandleArr) { try { FreePlugin(pluginHandle); } catch (Exception ex) { WavLoger.OnRaiseLog(nameof(FreePlugin), $"释放插件{_pluginHandleFilePathDic[pluginHandle]}失败", ex); } } }
public static void LoadPlugin(string dllFilePath) { try { if (string.Equals(Path.GetFileName(dllFilePath), NativeMethods.BASS_DLL)) { //忽略bass.dll return; } FreePlugin(dllFilePath);//释放已加载的同名文件 int handle = NativeMethods.BASS_PluginLoad(dllFilePath, BASSFlag.BASS_UNICODE); //If successful, the loaded plugin's handle is returned, else 0 is returned. Use BASS_ErrorGetCode to get the error code. if (handle == 0) { int errCode = NativeMethods.BASS_ErrorGetCode(); if (errCode == BassErrorCode.BASS_ERROR_FILEFORM || errCode == BassErrorCode.BASS_ERROR_FILEOPEN) { //非bass插件 return; } throw new WavException(BassErrorCode.GetErrorInfo()); } _pluginHandleFilePathDic.Add(handle, dllFilePath); } catch (Exception ex) { WavLoger.OnRaiseLog(nameof(LoadPlugin), $"加载插件{dllFilePath}失败", ex); } }
protected virtual void FreeBASS() { try { if (this.HandleValid()) { WavHelper.StreamFree(this._handle); this._handle = WavConstant.NONE_HANDLE; } } catch (Exception ex) { WavLoger.OnRaiseLog(this, ex); } }
public static void LoadPlugins(string bassDllDir) { FreePlugin(); if (!Directory.Exists(bassDllDir)) { try { //尝试创建目录 Directory.CreateDirectory(bassDllDir); } catch { } return; } string[] pluginFiles = Directory.GetFiles(bassDllDir); if (pluginFiles == null || pluginFiles.Length == 0) { return; } //遍历并加载插件 foreach (string dllFilePath in pluginFiles) { try { if (string.Equals(Path.GetFileName(dllFilePath), NativeMethods.BASS_DLL)) { //忽略bass.dll continue; } LoadPlugin(dllFilePath); } catch (Exception ex) { WavLoger.OnRaiseLog(nameof(LoadPlugin), $"加载插件{dllFilePath}失败", ex); } } }
/// <summary> /// 获取解码后的线性byte数据 /// </summary> /// <returns>解码后的线性byte数据</returns> public static PcmDataInfo GetPcmDataByte(string filePath) { if (string.IsNullOrWhiteSpace(filePath)) { throw new ArgumentNullException(nameof(filePath)); } if (!File.Exists(filePath)) { throw new FileNotFoundException("源文件不存在", filePath); } int handle = WavHelper.StreamCreateFile(filePath, 0, 0, BASSFlag.BASS_UNICODE | BASSFlag.BASS_STREAM_DECODE); try { long byteLength = WavHelper.ChannelGetLength(handle, BASSMode.BASS_POS_BYTE); double durationSeconds = WavHelper.ChannelBytes2Seconds(handle, byteLength); byte[] pcmData = new byte[byteLength]; int count = WavHelper.ChannelGetData(handle, pcmData, (int)byteLength); if (count != byteLength) { WavLoger.OnRaiseLog(filePath, $"获取到文件长度:{byteLength},读取到数据长度:{count},二者不一致,根据实际读取进行拷贝"); byte[] pcmDataSrc = pcmData; pcmData = new byte[count]; Array.Copy(pcmDataSrc, pcmData, pcmData.Length); } BASS_CHANNELINFO_INTERNAL wavInfo = WavHelper.ChannelGetInfo(handle); return(new PcmDataInfo(wavInfo, durationSeconds, pcmData)); } finally { WavHelper.StreamFree(handle); } }
private int StreamProcCallback(int handle, IntPtr bufferPtr, int length, IntPtr user) { try { var func = this.CustomerPlayDataFunc; if (func != null) { return(func(length, bufferPtr)); } if (this._callbackData == null || this._callbackData.Length < length) { this._callbackData = new byte[length]; } if (this._wposCount > this._rposCount) { int modLength = this._buffer.Length - this._rpos; if (modLength >= length) { Array.Copy(this._buffer, this._rpos, this._callbackData, 0, length); this._rpos += length; //当在播放状态改变了AppendCover属性值,则可能出现死循环场景,此处多一个健壮性代码 //正常情况下这部分代码不需要 if (this._rpos >= this._buffer.Length) { this._rposCount++; this._rpos = this._rpos % this._buffer.Length; } } else { if (this._wpos + modLength < length) { //WavLoger.OnRaiseLog(this, $"{length}-0"); return(0); } Array.Copy(this._buffer, this._rpos, this._callbackData, 0, modLength); int modLength2 = length - modLength; Array.Copy(this._buffer, 0, this._callbackData, modLength, modLength2); this._rpos = modLength2; this._rposCount++; //WavLoger.OnRaiseLog(this, $"read rount count +1 _ {this._rposCount}"); } } else { int wpos = this._wpos; if (wpos >= this._rpos) { if (wpos - this._rpos < length) { //注:如果没有数据,则返回长度为0;千万不能用Thread.Sleep,因为播放是单线程.会把播放线程停止下来,所有通道都不会再播放 //WavLoger.OnRaiseLog(this, $"{length}-0"); return(0); } int modLength = this._buffer.Length - this._rpos; if (modLength >= length) { //剩余的数据长度足够 Array.Copy(this._buffer, this._rpos, this._callbackData, 0, length); this._rpos += length; } else { //剩余的数据长度不够 int offset; if (modLength > 0) { //先读取剩余部分 Array.Copy(this._buffer, this._rpos, this._callbackData, 0, modLength); offset = modLength; modLength = length - modLength; } else { offset = 0; modLength = length; } //再读取起始部分 Array.Copy(this._buffer, 0, this._callbackData, offset, modLength); this._rpos = modLength; this._rposCount++; } } else { WavLoger.OnRaiseLog(this, $"read error _ {this._rposCount}"); return(0); } } //WavLoger.OnRaiseLog(this, $"{length}-{length}"); Marshal.Copy(this._callbackData, 0, bufferPtr, length); return(length); } catch (Exception ex) { WavLoger.OnRaiseLog(this, "播放器获取播放数据发生异常", ex); return(0); } }