Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Sound Effects Generator (+ Save option)
#1
Hi. During my work I created this interesting sound generator, so I added a save option for you. It is a simple program with the option to save the output to a WAV 16bit mono file.


Code: (Select All)

Const PI = 3.14159265359

' Parametry signálu     Signal parameters
Dim Shared Frequency As Single: Frequency = 440
Dim Shared SampleRate As Single: SampleRate = _SndRate
Dim Shared Duration As Single: Duration = 2

' Parametry efektu        Effects parameters
Dim Shared DistortionLevel As Single: DistortionLevel = 0.8
Dim Shared HarmonicStrength As Single: HarmonicStrength = 0.3
Dim Shared VibratoDepth As Single: VibratoDepth = 10
Dim Shared VibratoRate As Single: VibratoRate = 6

' Generování zvuku          Generate Sound
Dim SAMPLES As Long: SAMPLES = SampleRate * Duration
Dim Shared Signal(SAMPLES - 1) As Single

For f = 1 To 1000
    begin:
    Frequency = 50 + 300 * Rnd
    For j = 0 To SAMPLES - 1
        Signal(j) = 0
    Next
    GenerateGuitarTone Signal()
    Duration = 1 + Rnd * 3
    DistortionLevel = .6 + (1 + Rnd * 3) / 10
    VibratoDepth = 15 + Rnd * 40
    VibratoRate = 1 + Rnd * 150

    start:
    ' P°ehrßnÝ zvuku        Playing the sound
    For i = 0 To SAMPLES - 1
        _SndRaw Signal(i), Signal(i)
    Next i

    Do While _SndRawLen > 0
    Loop
    answ:
    Input "[P]lay again, [Q]uit, [N]ext, [S]ave to file"; msg$
    Select Case UCase$(msg$)
        Case "P": GoTo start
        Case "Q": System
        Case "N": GoTo begin
        Case "S": To$ = _SaveFileDialog$("Save effect", _CWD$, "*.WAV", "Wavetable files")
            NormalizeSignal Signal()
            SndMonoSave16 Signal(), To$
            GoTo answ
        Case Else
            GoTo answ
    End Select



Next f


Sub GenerateGuitarTone (Signal() As Single)
    Dim i As Long

    For i = 0 To UBound(Signal)
        ' Základní sinusová vlna
        Dim VibratoOffset As Single
        VibratoOffset = VibratoDepth * Sin(2 * PI * VibratoRate * i / SampleRate)
        Signal(i) = Sin(2 * PI * (Frequency + VibratoOffset) * i / SampleRate)

        ' Přidání harmonických složek       harmonical waves
        Signal(i) = Signal(i) + HarmonicStrength * Sin(2 * PI * (2 * Frequency) * i / SampleRate) ' Oktáva
        Signal(i) = Signal(i) + HarmonicStrength / 2 * Sin(2 * PI * (3 * Frequency) * i / SampleRate) ' Kvinta
        Signal(i) = Signal(i) + HarmonicStrength / 4 * Sin(2 * PI * (4 * Frequency) * i / SampleRate) ' Další

        ' Zkreslení (hard clipping)
        Signal(i) = Signal(i) * (1 + DistortionLevel)
        If Signal(i) > 1 Then Signal(i) = 1
        If Signal(i) < -1 Then Signal(i) = -1

        ' Wave shaping
        Signal(i) = Signal(i) + 0.5 * Signal(i) ^ 2 - 0.2 * Signal(i) ^ 3

        ' Tlumení      damping
        Signal(i) = Signal(i) * (1 - i / UBound(Signal))
    Next i
End Sub


'---------------------------------------------------------------------
Sub NormalizeSignal (arr() As Single)
    Dim maxVal As Single
    Dim i As Long

    ' Najít maximální absolutní hodnotu  Find maximal value in signal
    maxVal = 0
    For i = LBound(arr) To UBound(arr)
        If Abs(arr(i)) > maxVal Then maxVal = Abs(arr(i))
    Next

    ' Pokud je maximální hodnota větší než 1.0, normalizovat signál        if maximal value is bigger than 1, normalize signal
    If maxVal > 1.0 Then
        For i = LBound(arr) To UBound(arr)
            arr(i) = arr(i) / maxVal
        Next
    End If
End Sub

Sub SndMonoSave16 (arr() As Single, file As String)
    Type head16
        chunk As String * 4 '      4 bytes  (RIFF)
        size As _Unsigned Long '              4 bytes  (file size)  velikost souboru
        fomat As String * 4 '      4 bytes  (WAVE)
        sub1 As String * 4 '        4 bytes  (fmt )
        subchunksize As Long '      4 bytes  (lo / hi), $00000010 for PCM audio
        format As Integer '        2 bytes  (0001 = standard PCM, 0101 = IBM mu-law, 0102 = IBM a-law, 0103 = IBM AVC ADPCM)
        channels As Integer '      2 bytes  (1 = mono, 2 = stereo)
        rate As Long '              4 bytes  (sample rate, standard is 44100)
        ByteRate As Long '          4 bytes  (= sample rate * number of channels * (bits per channel /8))
        Block As Integer '          2 bytes  (block align = number of channels * bits per sample /8)
        Bits As Integer '          2 bytes  (bits per sample. 8 = 8, 16 = 16)
        subchunk2 As String * 4 '  4 bytes  ("data")  contains begin audio samples
        lenght As _Unsigned Long '            4 bytes  Data block size
    End Type '                    44 bytes  total

    Dim H16 As head16
    ch = FreeFile

    H16.chunk = "RIFF"
    H16.size = 44 + UBound(arr) * 2 ' 2 byte (integer)
    H16.fomat = "WAVE"
    H16.sub1 = "fmt "

    H16.subchunksize = 16

    H16.format = 1
    H16.channels = 1
    H16.rate = _SndRate
    H16.Bits = 16

    H16.ByteRate = (_SndRate * 1 * H16.Bits) / 8
    H16.Block = (1 * H16.Bits) / 8

    H16.subchunk2 = "data"
    H16.lenght = UBound(arr) * 2 ' 2 Byte
    If _FileExists(file$) Then Kill file$

    Open file$ For Binary As #ch
    Put #ch, , H16
    Dim Value As Integer
    For s = 0 To UBound(arr)
        Value = arr(s) * 32767
        Put #ch, , Value
    Next
    Close ch
    _SndPlayFile file$
End Sub

Function ConvertOffset&& (value As _Offset)
    $Checking:Off
    Dim m As _MEM 'Define a memblock
    m = _Mem(value) 'Point it to use value
    $If 64BIT Then
            'On 64 bit OSes, an OFFSET is 8 bytes in size.  We can put it directly into an Integer64
            _MEMGET m, m.OFFSET, ConvertOffset&& 'Get the contents of the memblock and put the values there directly into ConvertOffset&&
    $Else
        'However, on 32 bit OSes, an OFFSET is only 4 bytes.  We need to put it into a LONG variable first
        _MemGet m, m.OFFSET, temp& 'Like this
        ConvertOffset&& = temp& 'And then assign that long value to ConvertOffset&&
    $End If
    _MemFree m 'Free the memblock
    $Checking:On
End Function


Reply
#2
Good stuff. Reminds me of sfxr.

+1
Reply




Users browsing this thread: 4 Guest(s)