This project has moved. For the latest updates, please go here.

Control volume of two mp3 files

Aug 25, 2012 at 10:14 AM
Edited Aug 25, 2012 at 10:17 AM

Hello Mark,

thank you for creating this avesome possibility to play audio files.

I am currently working on a project that has to "fade" between two mp3 files. To accomplish that I created an array of two WaveOut´s in order to play the two files simultaneously and increase the volume of the first WaveOut respectively decrease the volume of the second.

Obviously I misunderstood the use of WaveOut - Setting the volume of one of the WaveOut-Objects leads into changing the "master"-volume of the program.

Is there any way to change the volume of the "streams" ?

This is my current code (VB 2010):

 

Option Strict Off
Option Explicit On
Imports Microsoft.Win32
Imports NAudio
Imports NAudio.Wave

Module globPlayFile
    Public Player(2) As WaveOut
    Public Stream(2) As WaveStream
    Public volumeStream(2) As WaveChannel32
    Public inputStream(2) As WaveChannel32
    Public mainOutputStream(2) As WaveStream
    Public Function MP3_Play(ByVal sFile As String, ByVal sIndex As Short) As Boolean
        'On Error Resume Next
        If Not Player(sIndex) Is Nothing Then
            Player(sIndex).Dispose()
            Player(sIndex) = Nothing
        End If

        If Not Stream(sIndex) Is Nothing Then
            Stream(sIndex).Dispose()
            Stream(sIndex) = Nothing
        End If
        mainOutputStream(sIndex) = CreateInputStream(sFile, sIndex)
        Player(sIndex) = New WaveOut()
        Player(sIndex).Init(mainOutputStream(sIndex))
        Player(sIndex).Play()
    End Function
    Private Function CreateInputStream(ByVal fileName As String, ByVal sIndex As Short) As WaveStream
        Stream(sIndex) = New Mp3FileReader(fileName)
        inputStream(sIndex) = New WaveChannel32(Stream(sIndex))
        volumeStream(sIndex) = inputStream(sIndex)
        Return volumeStream(sIndex)
    End Function

    Public Sub MP3_SetVolume(ByVal sIndex As Short, ByVal nVolume As Single)
        'On Error Resume Next
        If Not Player(sIndex) Is Nothing Then
            Player(sIndex).Volume = nVolume
        End If
    End Sub
End Module

 

Now I am using a timer to increase the volume of one WaveOut (via MP3_SetVolume) while deresing the volume of the other one.

Thank you in advance!

Greetings from Germany!

Sebastian

Aug 25, 2012 at 8:39 PM

Hi,

I am getting closer. Another discussion entry gave me the idea of changing the Volume on the input streams. Now I can handle the volume of the two MP3-files seperately.

Unfortunately this brings me to another Problem: When I init the second WaveOut, I get a short mute on all other playing MP3-Files. This delay is just a split second but you can hear the short moment of silence.

Any idea how to remove this error?

Thank you in advance!

Sebastian

Imports NAudio
Imports NAudio.Wave
Public Class Form1
    Public Player(2) As WaveOut
    Public Stream(2) As WaveStream
    Public volumeStream(2) As WaveChannel32
    Public inputStream(2) As WaveChannel32
    Public mainOutputStream(2) As WaveStream
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        OpenFileDialog1.Title = "Choose MP3 file to play!"
        OpenFileDialog1.ShowDialog()
    End Sub
    Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
        OpenFileDialog2.Title = "Choose MP3 file to play!"
        OpenFileDialog2.ShowDialog()
    End Sub
    Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click
        Player(1).Play()
        Button3.Enabled = False
        Button5.Enabled = True
    End Sub
    Private Sub Button4_Click(sender As System.Object, e As System.EventArgs) Handles Button4.Click
        Player(2).Play()
        Button4.Enabled = False
        Button6.Enabled = True
    End Sub
    Private Sub Button5_Click(sender As System.Object, e As System.EventArgs) Handles Button5.Click
        If Not Player(1) Is Nothing Then
            Player(1).Stop()
            Player(1).Dispose()
            Player(1) = Nothing
        End If

        If Not Stream(1) Is Nothing Then
            Stream(1).Dispose()
            Stream(1) = Nothing
        End If

        If Not volumeStream(1) Is Nothing Then
            volumeStream(1).Dispose()
            volumeStream(1) = Nothing
        End If

        If Not inputStream(1) Is Nothing Then
            inputStream(1).Dispose()
            inputStream(1) = Nothing
        End If

        If Not mainOutputStream(1) Is Nothing Then
            mainOutputStream(1).Dispose()
            mainOutputStream(1) = Nothing
        End If
        Button5.Enabled = False
        Button1.Enabled = True
    End Sub
    Private Sub Button6_Click(sender As System.Object, e As System.EventArgs) Handles Button6.Click
        If Not Player(2) Is Nothing Then
            Player(2).Stop()
            Player(2).Dispose()
            Player(2) = Nothing
        End If

        If Not Stream(2) Is Nothing Then
            Stream(2).Dispose()
            Stream(2) = Nothing
        End If

        If Not volumeStream(2) Is Nothing Then
            volumeStream(2).Dispose()
            volumeStream(2) = Nothing
        End If

        If Not inputStream(2) Is Nothing Then
            inputStream(2).Dispose()
            inputStream(2) = Nothing
        End If

        If Not mainOutputStream(2) Is Nothing Then
            mainOutputStream(2).Dispose()
            mainOutputStream(2) = Nothing
        End If
        Button6.Enabled = False
        Button2.Enabled = True
    End Sub
    Private Sub OpenFileDialog1_FileOk(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles OpenFileDialog1.FileOk
        mainOutputStream(1) = CreateInputStream(OpenFileDialog1.FileName.ToString, 1)
        Player(1) = New WaveOut()
        Player(1).Init(mainOutputStream(1))
        Button3.Enabled = True
        Button1.Enabled = False
    End Sub
    Private Sub OpenFileDialog2_FileOk(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles OpenFileDialog2.FileOk
        mainOutputStream(2) = CreateInputStream(OpenFileDialog2.FileName.ToString, 2)
        Player(2) = New WaveOut()
        Player(2).Init(mainOutputStream(2)) 'This leads into the short silence on the track playing on Player(1)
        Button4.Enabled = True
        Button2.Enabled = False
    End Sub
    Private Function CreateInputStream(ByVal fileName As String, ByVal sIndex As Short) As WaveStream
        Stream(sIndex) = New Mp3FileReader(fileName)
        inputStream(sIndex) = New WaveChannel32(Stream(sIndex))
        volumeStream(sIndex) = inputStream(sIndex)
        Return volumeStream(sIndex)
    End Function
    Private Sub TrackBar1_ValueChanged(sender As Object, e As System.EventArgs) Handles TrackBar1.ValueChanged
        If Not inputStream(1) Is Nothing Then
            Dim tmpVolume As Single
            tmpVolume = TrackBar1.Value / 100
            inputStream(1).Volume = tmpVolume
        End If
    End Sub
    Private Sub TrackBar2_ValueChanged(sender As Object, e As System.EventArgs) Handles TrackBar2.ValueChanged
        If Not inputStream(2) Is Nothing Then
            Dim tmpVolume As Single
            tmpVolume = TrackBar2.Value / 100
            inputStream(2).Volume = tmpVolume
        End If
    End Sub
End Class

Coordinator
Aug 27, 2012 at 8:52 PM

that's strange. Could it be the garbage collector kicking in momentarily perhaps? An alternative approach is to have just one WaveOut and mix the MP3s to be sent to it in software. This is a more complicated solution in terms of code though.