SOUND FREQUENCY Problem

  • 13 years ago

    I'm using Visual Basic 4.0 ( Unable to upgrade for reasons, to lengthy to describe )

    and I'm having trouble generating sound frequencies. What I'm hoping for is to find

    some sort of code solution or tips, advice on this.

     

    A simple VB form, with a text box on it, a command button and the relevant code would be sufficient, thanks!

    There are two main things I'd like to be able to do, but I'd be happy to come across solutions for either.

    First;

    I have an application that generates a series of numbers and then dumps these to a text file. The numbers are hertz fequency values to four decimal places. The text file will generally be comma delimited, in a format similiar to;

    432.1298

    256.9887

    333.99

    2445.77

    and so on....

    A text file may contain as little as eight numeric frequency values or up to three thousand.

    What I want to do, is feed this text file of numbers into some sort of music generating tool, convert these numbers into actual musical frequencies and store these files as avi, mpeg, wav files, whatever. If I coudl do this in code without having to use a dedicated musical software program that would be great, but I'm open to other sorts

    of solutions too.

    I'd like to be able to set the time duration for how long each note in the file is played for, i.e. all note are played for 120 seconds, etc....

    A 'nice' thing to do also possibly, would be to choose some sort of instrumental sound, like chimes, flute, etc as the instrument the frequencies are to be played on.

     

    Secondly;


    I want to specify exact frequencies for play back, NOT just preset values for specific tones, such as one base freq for a given note, its sharp or flat.

    Want to play musical notes but NOT just on PC Speaker.

    What I'm hoping to figure out;

    -Allow any numeric value for frequency in hertz in the format of 888.88 as input into text box for VB application

    -Value of frequency in textbox saved to a variable

    -Variable passed to relevant routine or ocx component

    -Routine or component plays back specific tone frequency on Sound Card (Not PC Speaker)

    -Playback allows volume adjustment

    I just need something basic and simple to play with to see if it will work for me, all I need is for the sample code to; Allow any numeric value in the format of 888.88 as input into text box

    Value in textbox saved to a variable Variable passed to relevant component. Component plays back specific tone frequency Playback allows volume adjustment

    ==============

    I've received a lot fo different tips and advice on how to do all this but nothing that meets all the requirements, i.e.

     

    Hi,

    I've seen your software online and noticed you were using something called MMTools to play sounds with.

    I just need something basic and simple to play with to see if it will work for me, all I need is for the sample code to; Allow any numeric value in the format of 888.88 as input into text box

    Value in textbox saved to a variable Variable passed to relevant component. Component plays back specific tone frequency Playback allows volume adjustment


    I've listed some of the things I've already tried below and described why these won't work, and in summary they are;

    BeepAPI

    How to Emulate QuickBasic's SOUND Statement in Visual Basic

    midiOutShortMsg and related

     

    ===============

    Problem with MIDI;

    Also, I love this method, but after reading all the info it looks like it won't actually let me specify exact frequencies for play back, only preset values for specific tones, such as one base freq for a given note, its sharp or flat.

    Knowing how to do this is valuable in and of itself, I now can play back musical notes that sound a lot better than the PC Speaker sounds. Sadly this doesn't solve the problem I have though.... :(

    create wav file

    --------------------------------------------------------------------------------

    The following code works but won't let me specify exact frequencies, only tones

    This generates a wave file (no clicks or ticks... just clear sound ):

    (It makes a 1 second tone of 440 Hz)

    VB Code:

     

    Option Explicit

    Private Type tWAVEFORMATEX

    wFormatTag As Integer

    nChannels As Integer

    nSamplesPerSec As Long

    nAvgBytesPerSec As Long

    nBlockAlign As Integer

    wBitsPerSample As Integer

    cbSize As Integer

    ExtraData(1 To 32) As Byte ' makes the structure 50 bytes long

    End Type

    Private Type FileHeader

    lRiff As Long

    lFileSize As Long

    lWave As Long

    lFormat As Long

    lFormatLength As Long

    End Type

    Private Type WaveFormat

    wFormatTag As Integer

    nChannels As Integer

    nSamplesPerSec As Long

    nAvgBytesPerSec As Long

    nBlockAlign As Integer

    wBitsPerSample As Integer

    End Type

    Private Type ChunkHeader

    lType As Long

    lLen As Long

    End Type

    Private Sub Form_Load()

    Dim Buff(0 To 44100) As Integer

    GenerateTone 440, Buff, 1

    SaveWaveFile "C:\test_Wave.wav", Buff

    End Sub

    Private Sub GenerateTone(ByVal Frequency As Single, IntBuff() As Integer, Optional Amplitude As Single = 1, Optional SamplesPerSec As Long = 44100, Optional Startpos As Long = 0, Optional Length As Long = -1)

    Dim K As Long, V1 As Double

    Const PI As Double = 3.14159265358979

    V1 = SamplesPerSec / (PI * 2 * Frequency)

    If Length = -1 Then Length = UBound(IntBuff) - Startpos

    For K = Startpos To Startpos + Length

    IntBuff(K) = CInt(Fix(Sin(K / V1) * (32766.5 * Amplitude)))

    Next K

    End Sub

    Private Sub SaveWaveFile(ByVal WaveFileName As String, ByRef Buffer() As Integer, Optional SamplesPerSec As Long = 44100)

    Dim WF As tWAVEFORMATEX

    WF.wFormatTag = 1 'WAVE_FORMAT_PCM

    WF.nChannels = 1

    WF.wBitsPerSample = 16

    WF.nSamplesPerSec = SamplesPerSec

    WF.nBlockAlign = (WF.wBitsPerSample * WF.nChannels) \ 8

    WF.nAvgBytesPerSec = WF.nSamplesPerSec * WF.nBlockAlign

    Open WaveFileName For Binary Access Write Lock Write As #1

    WaveWriteHeader 1, WF

    Put #1, , Buffer

    WaveWriteHeaderEnd 1

    Close #1

    End Sub

    Private Sub WaveWriteHeader(ByVal OutFileNum As Integer, WaveFmt As tWAVEFORMATEX)

    Dim header As FileHeader

    Dim HdrFormat As WaveFormat

    Dim chunk As ChunkHeader

    With header

    .lRiff = &H46464952 ' "RIFF"

    .lFileSize = 0

    .lWave = &H45564157 ' "WAVE"

    .lFormat = &H20746D66 ' "fmt "

    .lFormatLength = Len(HdrFormat)

    End With

    With HdrFormat

    .wFormatTag = WaveFmt.wFormatTag

    .nChannels = WaveFmt.nChannels

    .nSamplesPerSec = WaveFmt.nSamplesPerSec

    .nAvgBytesPerSec = WaveFmt.nAvgBytesPerSec

    .nBlockAlign = WaveFmt.nBlockAlign

    .wBitsPerSample = WaveFmt.wBitsPerSample

    End With

    chunk.lType = &H61746164 ' "data"

    chunk.lLen = 0

    Put #OutFileNum, 1, header

    Put #OutFileNum, , HdrFormat

    Put #OutFileNum, , chunk

    End Sub

    Private Sub WaveWriteHeaderEnd(ByVal OutFileNum As Integer)

    Dim header As FileHeader

    Dim HdrFormat As WaveFormat

    Dim chunk As ChunkHeader

    Dim Lng As Long

    Lng = LOF(OutFileNum)

    Put #OutFileNum, 5, Lng

    Lng = LOF(OutFileNum) - (Len(header) + Len(HdrFormat) + Len(chunk))

    Put #OutFileNum, Len(header) + Len(HdrFormat) + 5, Lng

    End Sub

    ===========

    ===========

     

    This code works, but only allows me to generate sounds to the PC Speaker, which sounds horrible!

    Option Explicit

    Private Declare Function Beep Lib "kernel32.dll" (ByVal dwFreq As Long, ByVal dwDuration As Long) As Long

    Private Sub Command1_Click()

    Beep 432.8765, 1000

    End Sub

    ================

    =========================

     

    This code works for MIDI, but doesn't let me specify exact frequencies only preset musical tones

    ==================

    midiOutShortMsg

    The midiOutShortMsg function sends a short MIDI message to the specified MIDI output device.

    VB4-32,5,6

    Declare Function midiOutShortMsg Lib "winmm.dll" (ByVal hMidiOut As Long, ByVal dwMsg As Long) As Long

    Operating Systems Supported

    Requires Windows NT 3.1 or later; Requires Windows 95 or later

    =============

    PLAY NOTE:

    Private Declare Function midiOutClose Lib "winmm.dll" (ByVal hMidiOut As Long) As Long

    Private Declare Function midiOutOpen Lib "winmm.dll" (lphMidiOut As Long, ByVal uDeviceID As Long, ByVal dwCallback As Long, ByVal dwInstance As Long, ByVal dwFlags As Long) As Long

    Private Declare Function midiOutShortMsg Lib "winmm.dll" (ByVal hMidiOut As Long, ByVal dwMsg As Long) As Long

    Dim hMidiOut As Long

    Private Sub Form_Load()

    'KPD-Team 2000

    'URL: http://www.allapi.net/

    'E-Mail: [email protected]

    Dim T As Long

    midiOutOpen hMidiOut, 0, 0, 0, 0

    midiOutShortMsg hMidiOut, 6567325

    T = Timer

    Do: DoEvents: Loop Until Timer > T + 4

    midiOutClose hMidiOut

    End Sub

    ----------------------

    http://allapi.mentalis.org/apilist/midiOutShortMsg.shtml

    ===============================

    Again, this only works for the PC Speaker

     

    A better beep

    If you aren't satisfied with the standard Beep command (who is?) you can use the Beep API function instead, that lets you control both the frequency (in Hertz) and the duration (in milliseconds) of the beep. Note that you need an aliased Declare to avoid a name conflict with the VB command:

    Private Declare Function BeepAPI Lib "kernel32" Alias "Beep" (ByVal dwFrequency _

    As Long, ByVal dwMilliseconds As Long) As Long

    The standard Beep command has a frequency of 440 Hertz and a duration of 200 milliseconds (more or less), so you can produce a short beep with a higher pitch with the following statement:

    BeepAPI 600, 100

    And of course you can even produce more complex sounds, when a simple beep won't suffice:

    Dim i As Long

    For i = 100 To 1000 Step 10

    BeepAPI i, 20

    Next

     

Post a reply

No one has replied yet! Why not be the first?

Sign in or Join us (it's free).

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“I have always wished for my computer to be as easy to use as my telephone; my wish has come true because I can no longer figure out how to use my telephone” - Bjarne Stroustrup