コード例 #1
0
        protected void UpdatePlaySpeed()
        {
            int?speed = this._speed;

            if (!speed.HasValue)
            {
                return;
            }

            float offset   = (float)Math.Abs(speed.Value) / _PLAY_SPEED_ZOOM_MULIT;
            var   waveInfo = this.WaveInfo;

            if (waveInfo == null)
            {
                throw new WavException("句柄已释放");
            }

            var   sampleRate = waveInfo.SampleRate;
            float playSampleRate;

            if (speed.Value < 0)
            {
                playSampleRate = sampleRate * (1 - offset);
            }
            else if (speed.Value == 0)
            {
                playSampleRate = sampleRate;
            }
            else
            {
                playSampleRate = sampleRate * (1 + offset);
            }

            WavHelper.ChannelSetSpeed(this._handle, playSampleRate);
        }
コード例 #2
0
        /// <summary>
        /// 开始录音
        /// </summary>
        /// <param name="freq">录音采样率,默认48000</param>
        /// <param name="chans">声道数[1-6],默认1</param>
        /// <param name="period">录音数据输出间隔,单位/毫秒,默认100.最小值5ms,the maximum the maximum is half the BASS_CONFIG_REC_BUFFER setting.
        /// If the period specified is outside this range, it is automatically capped. The default is 100ms</param>
        /// <param name="sampleType">采样类型,建议默认值16位</param>
        public void Start(int freq = 48000, int chans = 1, int period = 100, SampleType sampleType = SampleType.Sample16Bit)
        {
            BASSFlag flags = this.SampleTypeToBASSFlag(sampleType);

            this._recordFlag = true;
            this._handle     = RecordHelper.RecordStart(freq, chans, flags, period, this._recordPro, IntPtr.Zero);
            WavHelper.ChannelPlay(this._handle, false);
        }
コード例 #3
0
 protected override void FreeBASS()
 {
     this._waveInfo = null;
     base.FreeBASS();
     if (base.HandleValid())
     {
         WavHelper.BASS_ChannelRemoveSync(base._handle, this._playEndSyncHandle);
     }
 }
コード例 #4
0
 /// <summary>
 /// 播放
 /// </summary>
 public void Play()
 {
     if (this.ValidatePPSOperate(SoundPlayerStatus.Playing))
     {
         this._status = SoundPlayerStatus.StartPlaying;
         WavHelper.ChannelPlay(this._handle, this.Status == SoundPlayerStatus.Stoped);
         this._status = SoundPlayerStatus.Playing;
         this.OnPlayStatusChanged();
     }
 }
コード例 #5
0
 /// <summary>
 /// 停止
 /// </summary>
 public void Stop()
 {
     if (this.ValidatePPSOperate(SoundPlayerStatus.Stoped))
     {
         this._status = SoundPlayerStatus.Stoping;
         WavHelper.ChannelStop(this._handle);
         this._status = SoundPlayerStatus.Stoped;
         this.OnPlayStatusChanged();
     }
 }
コード例 #6
0
 /// <summary>
 /// 暂停
 /// </summary>
 public void Pause()
 {
     if (this.ValidatePPSOperate(SoundPlayerStatus.Paused))
     {
         this._status = SoundPlayerStatus.Pausing;
         WavHelper.ChannelPause(this._handle);
         this._status = SoundPlayerStatus.Paused;
         this.OnPlayStatusChanged();
     }
 }
コード例 #7
0
 /// <summary>
 /// 获取音频文件信息
 /// </summary>
 /// <returns>音频文件信息</returns>
 public BASS_CHANNELINFO_INTERNAL GetWavInfo()
 {
     if (this.HandleValid())
     {
         return(WavHelper.ChannelGetInfo(this._handle));
     }
     else
     {
         throw new WavException("未加载音频数据");
     }
 }
コード例 #8
0
        /// <summary>
        /// 声音淡入淡出
        /// </summary>
        /// <param name="volValue">音量目标值</param>
        /// <param name="duration">持续时间,单位/毫秒</param>
        public void VoiceSlide(float volValue, int duration)
        {
            if (!this.HandleValid())
            {
                return;
            }

            //float value = 0.2f;
            //int duration=2*1000;
            WavHelper.ChannelSlideAttribute(this._handle, BASSAttribute.BASS_ATTRIB_VOL, volValue, duration);
        }
コード例 #9
0
 /// <summary>
 /// 获取实时FFT数据,float类型
 /// </summary>
 /// <param name="fftData">FFT数据存放数据</param>
 /// <returns>获取到的FFT数据长度</returns>
 public int GetFFTDataFloat(float[] fftData)
 {
     if (this.HandleValid())
     {
         return(WavHelper.ChannelGetData(this._handle, fftData, fftData.Length));
     }
     else
     {
         throw new ArgumentException("句柄无效");
     }
 }
コード例 #10
0
        /// <summary>
        /// 播放状态改变通知
        /// </summary>
        protected override void OnPlayStatusChanged()
        {
            base.OnPlayStatusChanged();

            var state = WavHelper.ChannelIsActive(base._handle);

            if (state != BASSActive.BASS_ACTIVE_PAUSED &&
                state != BASSActive.BASS_ACTIVE_PAUSED_DEVICE &&
                state != BASSActive.BASS_ACTIVE_PLAYING)
            {
                this._waveInfo = null;
            }
        }
コード例 #11
0
 protected virtual void FreeBASS()
 {
     try
     {
         if (this.HandleValid())
         {
             WavHelper.StreamFree(this._handle);
             this._handle = WavConstant.NONE_HANDLE;
         }
     }
     catch (Exception ex)
     {
         WavLoger.OnRaiseLog(this, ex);
     }
 }
コード例 #12
0
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="waveInfo">音频信息</param>
        /// <param name="bufferCapcity">缓存容量,小于等于0自动计算</param>
        public StreamSoundPlayer(WaveInfo waveInfo, int bufferCapcity = -1)
            : base(SoundPlayerType.Stream)
        {
            this._waveInfo = waveInfo;
            int bitByteCount;


            BASSFlag flags;

            switch (waveInfo.SampleBit)
            {
            case SampleType.Sample8Bit:
                flags        = BASSFlag.BASS_DEFAULT | BASSFlag.BASS_SAMPLE_8BITS;
                bitByteCount = 1;
                break;

            case SampleType.Sample16Bit:
                flags        = BASSFlag.BASS_DEFAULT;
                bitByteCount = 2;
                break;

            case SampleType.Sample32Bit:
                flags        = BASSFlag.BASS_DEFAULT | BASSFlag.BASS_SAMPLE_FLOAT;
                bitByteCount = 4;
                break;

            default:
                throw new NotImplementedException($"未实现的采样类型:{waveInfo.SampleBit.ToString()}");
            }

            if (bufferCapcity == -1)
            {
                bufferCapcity = waveInfo.SampleRate * waveInfo.ChannelCount * bitByteCount * 10;//默认缓存10秒数据
            }

            if (bufferCapcity > 0)
            {
                this._buffer = new byte[bufferCapcity];
            }

            this._streamProc = new STREAMPROC(this.StreamProcCallback);
            base._handle     = WavHelper.StreamCreate(waveInfo.SampleRate, waveInfo.ChannelCount, flags, this._streamProc, IntPtr.Zero);
            //base._device = WavHelper.ChannelGetDevice(base._handle);
        }
コード例 #13
0
        /// <summary>
        /// 加载音频文件
        /// </summary>
        /// <param name="filePath">音频路径</param>
        public void LoadWav(string filePath)
        {
            if (string.IsNullOrEmpty(filePath))
            {
                throw new ArgumentNullException(nameof(filePath), "文件路径不能为空或null");
            }

            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException("音频文件不存在", filePath);
            }

            this._fileName = filePath;
            this.FreeBASS();
            base._handle            = WavHelper.StreamCreateFile(filePath);
            this._playEndSyncHandle = WavHelper.ChannelSetSync(this._handle, BASSSync.BASS_SYNC_END, -1, this._playEndNotifyCallback, IntPtr.Zero);
            //WavHelper.ChannelSetSync(this._handle, BASSSync.BASS_SYNC_MIXTIME, -1, this._playPositionChangedNotifyCallback, IntPtr.Zero);
            this.SetPlayerAttribute();
        }
コード例 #14
0
ファイル: WavHelper.cs プロジェクト: windygu/UtilZ.DotnetEx
        /// <summary>
        /// 获取设备数
        /// </summary>
        /// <returns>设备数</returns>
        public static int GetDeviceCount()
        {
            int deviceCount = 0;
            BASS_DEVICEINFO_INTERNAL info = new BASS_DEVICEINFO_INTERNAL();

            for (int i = 0; ; i++)
            {
                if (WavHelper.GetDeviceInfo(i, ref info))
                {
                    deviceCount++;
                }
                else
                {
                    break;
                }
            }

            return(deviceCount);
        }
コード例 #15
0
        /// <summary>
        /// 获取解码后的线性short数据
        /// </summary>
        /// <returns>解码后的线性short数据</returns>
        public static PcmDataInfo GetPcmDataShort(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);

                int     shortCount = (int)(byteLength);
                short[] pcmData    = new short[shortCount];
                int     count      = WavHelper.ChannelGetData(handle, pcmData, shortCount);

                //注:结果数据长度之所以除以2,是因为short=2byte,bass获取数据时必须使用字节长度,否则数据会少一半;
                //但是使用字节长度获取数据后,后一半数据又全是0,需要截取掉

                count = count / 2;
                short[] pcmDataSrc = pcmData;
                pcmData = new short[count];
                Array.Copy(pcmDataSrc, pcmData, count);

                BASS_CHANNELINFO_INTERNAL wavInfo = WavHelper.ChannelGetInfo(handle);
                return(new PcmDataInfo(wavInfo, durationSeconds, pcmData));
            }
            finally
            {
                WavHelper.StreamFree(handle);
            }
        }
コード例 #16
0
        /// <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);
            }
        }
コード例 #17
0
 /// <summary>
 /// 初始化声音输出设备
 /// </summary>
 /// <param name="device"> -1 = default device, 0 = no sound, 1 = first real output device. BASS_GetDeviceInfo can be used to enumerate the available devices. </param>
 /// <param name="freq">输出率</param>
 /// <param name="flags">A combination of these flags</param>
 public static void InitDevice(int device, int freq, BASSInit flags)
 {
     WavHelper.Init(device, freq, flags);
 }
コード例 #18
0
 protected void UpdateVolume()
 {
     WavHelper.ChannelSetVolume(this._handle, this._volume.Value);
 }
コード例 #19
0
 protected void UpdateBalance()
 {
     WavHelper.ChannelSetAttribute(this._handle, BASSAttribute.BASS_ATTRIB_PAN, this._balance.Value);
 }
コード例 #20
0
 /// <summary>
 /// Frees all resources used by the output device, including all its samples, streams and MOD musics
 /// </summary>
 public static void Free()
 {
     WavHelper.Free();
 }