说明

  本文发布较早,查看 TypeScript 版本了解最新动态。(2021 年 5 月 注)

UWP简单示例(一):快速合成音乐MV

在线演示: 音频可视化(TypeScript)

准备

  IDE:Visual Studio

  Nuget包:SharpDx.XAudio2

  Nuget包:Win2D.UWP

  了解学习:Win2D 官方博客

  了解学习:Win2D 官方示例

第一节 波形

  获取实时时域数据。

UWP简单示例(一):快速合成音乐MV
Imports SharpDX.Multimedia
Imports SharpDX.XAudio2
Public Class AudioPlayer
    Public Event WavePlaying(e As WavePlayingEventArgs)
    Public Property Device As XAudio2
    Public Property Voice As SourceVoice
    Private CurrentFormat As WaveFormat
    Private CurrentBuffer As AudioBuffer
    Private PacketsInfo As UInteger()
    Public Sub New()
        Device = New XAudio2()
        Device.StartEngine()
        Dim mv As New MasteringVoice(Device)
    End Sub
    Public Async Function LoadFile(fileName As String) As Task(Of Boolean)
        Try
            Voice = Await CreateVoiceFromFile(Device, fileName)
            LoadBuffer()
            Return True
        Catch
            Return False
        End Try
    End Function
    Public Sub Play(Optional volume As Single = 1.0F)
        Voice?.SetVolume(volume)
        Voice?.Start()
        ReadBuffer()
    End Sub
    Public Sub [Stop]()
        Voice?.Stop()
    End Sub
    Protected Async Function CreateVoiceFromFile(device As XAudio2, fileName As String) As Task(Of SourceVoice)
        Dim file = Await Package.Current.InstalledLocation.GetFileAsync(fileName)
        Dim streamWithContentType = Await file.OpenReadAsync()
        Dim st = streamWithContentType.AsStreamForRead()
        Using stream = New SoundStream(st)
            CurrentFormat = stream.Format
            CurrentBuffer = New AudioBuffer() With {
            .Stream = stream.ToDataStream(),
            .AudioBytes = CInt(stream.Length),
            .Flags = BufferFlags.EndOfStream
        }
            PacketsInfo = stream.DecodedPacketsInfo
        End Using
        Dim sourceVoice = New SourceVoice(device, CurrentFormat, True)
        Return sourceVoice
    End Function
    Protected Sub LoadBuffer()
        Voice?.FlushSourceBuffers()
        Voice?.SubmitSourceBuffer(CurrentBuffer, PacketsInfo)
    End Sub
    ''' <summary>
    ''' 从流中读取当前播放的数据
    ''' </summary>
    Private Async Sub ReadBuffer()
        Try
            Dim count As Integer = CurrentFormat?.AverageBytesPerSecond / 10
            While Voice.State.BuffersQueued > 0
                If Voice.State.SamplesPlayed * CurrentFormat.BlockAlign > CurrentBuffer.Stream.Position + count Then
                    Dim byteArr(count - 1) As Byte
                    Await CurrentBuffer.Stream.ReadAsync(byteArr, 0, count)
                    RaiseEvent WavePlaying(New WavePlayingEventArgs(byteArr, CurrentFormat))
                Else
                    Await Task.Delay(10)
                End If
            End While
        Catch
            Return
        End Try
    End Sub
    Public Function Position() As Integer
        Return Voice.State.SamplesPlayed / CurrentFormat.SampleRate
    End Function
    Protected Overrides Sub Finalize()
        Try
            Dispose(False)
        Finally
            MyBase.Finalize()
        End Try
    End Sub
    Public Sub Dispose()
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
    Private Sub Dispose(isDisposing As Boolean)
        If Not isDisposing Then
            Return
        End If
        Voice.DestroyVoice()
        Voice.Dispose()
        CurrentBuffer.Stream.Dispose()
    End Sub
End Class
VB.NET

相关文章:

  • 2021-08-20
  • 2021-08-19
  • 2021-10-07
  • 2021-06-22
  • 2022-12-23
  • 2021-06-04
  • 2021-12-28
  • 2022-02-08
猜你喜欢
  • 2021-10-17
  • 2021-11-13
  • 2021-12-16
  • 2021-12-06
  • 2021-12-16
  • 2021-10-10
相关资源
相似解决方案