VS 2017 Console.Beep Application-VBForums
Results 1 to 17 of 17

Thread: Console.Beep Application

  1. #1

    Thread Starter
    Member
    Join Date
    Aug 2011
    Posts
    32

    Console.Beep Application

    Please forgive me as it has been years since I have messed with any of this stuff.

    I have made a simple application with one button. A press of the button generates a tone of 500hz for 1 second, and 1000 hz for 1 second. The only issue I have is how come when the program changes from the first tone to the second there is a short gap between them. Is there anyway to resolve this or at least make it "smoother"?

    Code:
    Public Class Form1
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Console.Beep(500, 1000)
            Console.Beep(1000, 1000)
        End Sub
    End Class
    Also how would I go about making two text boxes(tone1 and tone2) on the form and substituting their values into the frequency?

    Code:
    Console.Beep(textbox1, 1000)
    Console.Beep(textbox2, 1000)
    Again forgive me for the ignorance as it has been ages since I have messed with programming at all. I just need to catch on again.

  2. #2

    Thread Starter
    Member
    Join Date
    Aug 2011
    Posts
    32

    Re: Console.Beep Application

    And also, how would I handle playing the tone as long as the mouse is clicked?

    Code:
    Private Sub Button2_mousedown(sender As Object, e As EventArgs) Handles Button2.MouseDown
            Console.Beep(1000, timepresseddown)
    
        End Sub
        Private Sub Button2_mouseup(sender As Object, e As EventArgs) Handles Button2.MouseUp
           
        End Sub

  3. #3
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    30,830

    Re: Console.Beep Application

    You're about right on the second part of this. I'd use a NumericUpDown rather than a textbox, though. A textbox ONLY has text, which means it may be a number...or it may not be a number. If you changed the code to this:

    Console.Beep(textbox1.Text,1000)

    then the code will run as long as Option Strict is OFF, and the value in the textbox really is a number. If the textbox is empty, or the text isn't a number, then the code will crash. If Option Strict is ON (which it should be, since it prevents you from encountering that crash), then the code won't even compile, because of the invalid conversion of a string to an integer. There are ways to solve that, but the best and easiest is to use NumericUpDown controls, which ONLY have numbers. That would look like this:

    Console.Beep(CInt(yourNUD1.Value),1000)

    With Option Strict OFF, you wouldn't need the CInt(), but Option Strict is always a good idea except for the rare case where it doesn't work at all.

    As for the first question, I have no answer. Beep is ANCIENT!! I have no idea how it works under the hood.
    My usual boring signature: Nothing

  4. #4
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    30,830

    Re: Console.Beep Application

    You probably can't use Beep to play as long as the mouse button is pressed. You could figure out how long the button was pressed, and play it after the mouse was released, but having it play as the button is pressed is probably not possible. Beep predates the mouse.
    My usual boring signature: Nothing

  5. #5

    Thread Starter
    Member
    Join Date
    Aug 2011
    Posts
    32

    Re: Console.Beep Application

    Being that it is ancient, is there a more modern way to generate a sound wave? I just need the program to generate a tone for the frequency and duration I determine. I just found console.beep from quick research. If there is a better way I am open to it.

  6. #6
    PowerPoster Jenner's Avatar
    Join Date
    Jan 2008
    Location
    Mentor, OH
    Posts
    3,666

    Re: Console.Beep Application

    Most any audio library out there can generate tones. NAudio works really well for this.
    My CodeBank Submissions: TETRIS using VB.NET2010 and XNA4.0, Strong Encryption Class, Hardware ID Information Class, Generic .NET Data Provider Class, Lambda Function Example, Lat/Long to UTM Conversion Class, Audio Class using BASS.DLL

    Remember to RATE the people who helped you and mark your forum RESOLVED when you're done!

    "Two things are infinite: the universe and human stupidity; and I'm not sure about the universe. "
    - Albert Einstein

  7. #7
    PowerPoster Jenner's Avatar
    Join Date
    Jan 2008
    Location
    Mentor, OH
    Posts
    3,666

    Re: Console.Beep Application

    ...in fact, since it's been ages since I last used it. I decided to whip up a quick tone-generator with NAudio.

    Make a new Windows Forms project.
    Add the NuGet package "NAudio" from "Project->Manage NuGet Packages" then Browse for NAudio.

    First, add a new Class to your project. Call it "SineWaveProvider"
    Open it.
    Copy in this code:
    Code:
    'The class below is my tone generator.  It makes SINE waves
    Public Class SineWaveProvider
        Inherits NAudio.Wave.WaveProvider32
    
        Private sample As Integer
    
        Public Frequency As Single
        Public Amplitude As Single
    
        Public Overrides Function Read(buffer() As Single, offset As Integer, sampleCount As Integer) As Integer
            Dim sampleRate As Integer = WaveFormat.SampleRate
            For i As Integer = 0 To sampleCount
                buffer(i + offset) = Convert.ToSingle(Amplitude * Math.Sin((2 * Math.PI * sample * Frequency) / sampleRate)) 'The formula for a sine wave.
                sample += 1
                If sample >= sampleRate Then sample = 0
            Next
            Return sampleCount
        End Function
    End Class
    Go to your main form, drop in the following:

    Code:
    Public Class Form1
        Private provider As New SineWaveProvider With {.Amplitude = 1, .Frequency = 2600} 'This is my tone generator, I'm setting it at 2600 hz
        Private out As New NAudio.Wave.WaveOut(NAudio.Wave.WaveCallbackInfo.FunctionCallback) 'This is the thing that plays the tones
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            out.Init(provider) 'Set up my audio tone so it's ready to be triggered
        End Sub
    
        Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
            out.Volume = 0.25 'Set Volume between 0 and 1 - 0.25 is so I don't blow my eardrums!
            out.Play() 'Play as long as the mouse button is held down
        End Sub
    
        Private Sub Form1_MouseUp(sender As Object, e As MouseEventArgs) Handles Me.MouseUp
            out.Stop() 'Stop playing when it is let up
        End Sub
    End Class
    Run the project. You should hear a 2600hz tone when you press the mouse button on your form.

    No Imports were used so you can see where each object is coming from, though using them will clean up the code a bit.
    Enjoy!
    My CodeBank Submissions: TETRIS using VB.NET2010 and XNA4.0, Strong Encryption Class, Hardware ID Information Class, Generic .NET Data Provider Class, Lambda Function Example, Lat/Long to UTM Conversion Class, Audio Class using BASS.DLL

    Remember to RATE the people who helped you and mark your forum RESOLVED when you're done!

    "Two things are infinite: the universe and human stupidity; and I'm not sure about the universe. "
    - Albert Einstein

  8. #8

    Thread Starter
    Member
    Join Date
    Aug 2011
    Posts
    32

    Re: Console.Beep Application

    Jenner, thanks a lot this works wonderfully.

    How would I incorporate multiple different tone frequencies? Like above the press of a button generated two tones one 500hz the next 1000hz. In other words, can NAudio be written to generate a tone sequence like Console.Beep did?

    Code:
       Console.Beep(500, 1000)
       Console.Beep(1000, 1000

  9. #9
    PowerPoster Jenner's Avatar
    Join Date
    Jan 2008
    Location
    Mentor, OH
    Posts
    3,666

    Re: Console.Beep Application

    Of course. There's many ways to do it. You could write it into the SineGenerator for example:
    Close Encounters of the Third Kind anyone? (really sloppy example, but it's for demonstration)
    Code:
    Public Class SineWaveProvider
        Inherits NAudio.Wave.WaveProvider32
    
        Private sample As Integer
        Private totaltime As Integer
        Private seconds As Integer
    
        Public Frequency As Single
        Public Amplitude As Single
    
        Public Overrides Function Read(buffer() As Single, offset As Integer, sampleCount As Integer) As Integer
            Dim sampleRate As Integer = WaveFormat.SampleRate
    
            For i As Integer = 0 To sampleCount
                totaltime = Convert.ToInt32((seconds + (sample / sampleRate)) * 1000)
                Select Case totaltime
                    Case > 4200
                        seconds = 0
                        Frequency = 466.16
                    Case > 3200
                        Frequency = 311.13
                    Case > 2200
                        Frequency = 207.65
                    Case > 1200
                        Frequency = 415.3
                    Case > 600
                        Frequency = 523.25
                    Case Else
                        Frequency = 466.16
                End Select
                buffer(i + offset) = Convert.ToSingle(Amplitude * Math.Sin((2 * Math.PI * sample * Frequency) / sampleRate)) 'The formula for a sine wave.
                sample += 1
    
                If sample >= sampleRate Then
                    seconds += 1
                    sample = 0
                End If
            Next
            Return sampleCount
        End Function
    End Class
    Or... you can just make a bunch of provider objects and trigger them off on the main form (again, sloppy, but just an example)
    Code:
    Public Class Form1
        Private provider As New SineWaveProvider With {.Amplitude = 1, .Frequency = 500} 'This is my tone generator, I'm setting it at 500 hz
        Private provider2 As New SineWaveProvider With {.Amplitude = 1, .Frequency = 1000} 'This is my tone generator, I'm setting it at 1000 hz
        Private provider3 As New SineWaveProvider With {.Amplitude = 1, .Frequency = 2000} 'This is my tone generator, I'm setting it at 2000 hz
    
        Private out As New NAudio.Wave.WaveOut(NAudio.Wave.WaveCallbackInfo.FunctionCallback) 'This is the thing that plays the tones
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            'Set up my audio tone so it's ready to be triggered
        End Sub
    
        Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
            out.Init(provider)
            out.Volume = 0.25 'Set Volume between 0 and 1 - 0.25 is so I don't blow my eardrums!
            out.Play() 'Play as long as the mouse button is held down
            Threading.Thread.Sleep(1000)
            out.Stop()
            out.Init(provider2)
            out.Play() 'Play as long as the mouse button is held down
            Threading.Thread.Sleep(1000)
            out.Stop()
            out.Init(provider3)
            out.Play() 'Play as long as the mouse button is held down
            Threading.Thread.Sleep(1000)
            out.Stop()
        End Sub
    
        Private Sub Form1_MouseUp(sender As Object, e As MouseEventArgs) Handles Me.MouseUp
            out.Stop() 'Stop playing when it is let up
        End Sub
    End Class
    My CodeBank Submissions: TETRIS using VB.NET2010 and XNA4.0, Strong Encryption Class, Hardware ID Information Class, Generic .NET Data Provider Class, Lambda Function Example, Lat/Long to UTM Conversion Class, Audio Class using BASS.DLL

    Remember to RATE the people who helped you and mark your forum RESOLVED when you're done!

    "Two things are infinite: the universe and human stupidity; and I'm not sure about the universe. "
    - Albert Einstein

  10. #10
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    30,830

    Re: Console.Beep Application

    This line:
    Code:
     Private provider As New SineWaveProvider With {.Amplitude = 1, .Frequency = 2600} 'This is my tone generator, I'm setting it at 2600 hz
    creates the provider with a frequency (and an Amplitude). You should be able to create as many as you want with as many tones as you want by creating more Naudio.Wave.WaveOut objects (the 'out' variable). So, you might create a Dictionary(of Integer, NAudio.Wave.WaveOut), then build up the dictionary with a frequency as the key and the output as the value. Might look something like this:
    Code:
    Private myTones As New Dictionary(of Integer, NAudio.Wave.WaveOut)
    
    'Then, down in load you might do this.
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            out.Init(provider) 'Set up my audio tone so it's ready to be triggered
    dim out As SineWaveProvider 
    dim wavOut as NAudio.Wave.WaveOut
    for x=500 to 3000 Step 500
     out = New SineWaveProvider  With {.Amplitude = 1, .Frequency = 2600}
     wavOunt = New NAudio.Wave.WaveOut(NAudio.Wave.WaveCallbackInfo.FunctionCallback)
     myTones.Add(x, wavOut)
     wavOut.Init(out)
    Next
    End Sub
    
    'Then to play one it may be:
        Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
            out.Volume = 0.25 'Set Volume between 0 and 1 - 0.25 is so I don't blow my eardrums!
            myTones(500).Play() 'Play as long as the mouse button is held down
        End Sub
    In theory, this will create a dictionary of tones from 500 to 3000 for every 500 Hz difference. In practice, this may gobble up resources if the dictionary got too large. As it is, it's only six tones, so it probably would work fine. Of course, it can be refined. For one thing, this is just freehand code. Another point is that the only tone I'm playing is 500 Hz. You'd probably want to have some means to input a frequency. Also, this only generates the tones found in the dictionary. If you wanted to create a more dynamic tone generator, then you'd have to be creating and disposing the objects on some event, rather than creating them all on form load.

    EDIT: I was too slow.
    My usual boring signature: Nothing

  11. #11
    PowerPoster Jenner's Avatar
    Join Date
    Jan 2008
    Location
    Mentor, OH
    Posts
    3,666

    Re: Console.Beep Application

    Haha, in all fairness, I looked up the tones and messed around with editing the SineWaveProvider to hum the 5 tones from Close Encounters not long after I posted my first reply...

    Probably to give my brain some subconscious time to process my own problem in the thread I made.
    My CodeBank Submissions: TETRIS using VB.NET2010 and XNA4.0, Strong Encryption Class, Hardware ID Information Class, Generic .NET Data Provider Class, Lambda Function Example, Lat/Long to UTM Conversion Class, Audio Class using BASS.DLL

    Remember to RATE the people who helped you and mark your forum RESOLVED when you're done!

    "Two things are infinite: the universe and human stupidity; and I'm not sure about the universe. "
    - Albert Einstein

  12. #12

    Thread Starter
    Member
    Join Date
    Aug 2011
    Posts
    32

    Re: Console.Beep Application

    Thank you both for the help.

    This will sort of go along with what y’all are trying to explain but like above can I use the NumericUpDown as an input for the frequency? Sorry to make it even more complicated, as if it wasn’t complicated enough.

  13. #13
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    30,830

    Re: Console.Beep Application

    You SHOULD use NumericUpDown as the entry control for any number.

    You can re-write the initial example such that it is taking the value from the NUD and putting it in frequency. Of course, the code can't be in the Load event any longer, so you'd probably want to add it to either the ValueChanged event for the NUD, or have a button that you click whenever you change the frequency. You might also want one for the volume, while you're at it.

    What I can't say is how much overhead you will get from the objects being created. If these objects are trivial as far as resources, then you can just make up as many of them as you want. If they are expensive in terms of resources, then you'd want to be explicitly disposing of the ones you are done with whenever you make new ones for the new frequency.
    My usual boring signature: Nothing

  14. #14

    Thread Starter
    Member
    Join Date
    Aug 2011
    Posts
    32

    Re: Console.Beep Application

    You mean this :

    Code:
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            out.Init(provider) 'Set up my audio tone so it's ready to be triggered
        End Sub
    I tried putting it in the value changed event however I do not always need to change the frequency from the default.

    I tried this but I get an error: System.NullReferenceException: 'Object reference not set to an instance of an object.'

    Code:
     Private provider As New SineWaveProvider With {.Amplitude = 1, .Frequency = CInt(NumericUpDown1.Value)}

  15. #15
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    30,830

    Re: Console.Beep Application

    Where did you try that? Since you use Private, it looks like you tried that at form scope, which won't work. No controls are created by the time that code runs. All controls are created in the InitializeComponents method, which is the first line in the constructor, which has yet to run by the time a form level variable is filled in, hence the exception.

    You may want one provider for the default, but it looks like you'll need to create a new provider and new WaveOut every time you change the NUD value.

    I started writing this an hour ago, then got called away. I wonder if it is still relevant?
    My usual boring signature: Nothing

  16. #16
    PowerPoster Jenner's Avatar
    Join Date
    Jan 2008
    Location
    Mentor, OH
    Posts
    3,666

    Re: Console.Beep Application

    You can use one provider and just change the Frequency

    In your NumericUpDown_Changed event handler, just put:
    provider.Frequency = NumericUpDown1.Value
    My CodeBank Submissions: TETRIS using VB.NET2010 and XNA4.0, Strong Encryption Class, Hardware ID Information Class, Generic .NET Data Provider Class, Lambda Function Example, Lat/Long to UTM Conversion Class, Audio Class using BASS.DLL

    Remember to RATE the people who helped you and mark your forum RESOLVED when you're done!

    "Two things are infinite: the universe and human stupidity; and I'm not sure about the universe. "
    - Albert Einstein

  17. #17
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    30,830

    Re: Console.Beep Application

    That's even easier.
    My usual boring signature: Nothing

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width

Survey posted by VBForums.