Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - chlorophyll-zz

Pages: [1]
1
Hi.

Repair row 18 in your last source code as:

DIM RawMusic(_CEIL(_SNDRATE * VAL(uWAVLen$))) AS SINGLE


Ah, now I see, when I press enter, the uWAVLen gets a DIM(0).
Now I put the DIM after the check.
Also, I implemented Pauses (5%)?

Code: QB64: [Select]
  1. Dim fm(88) As Double
  2. Dim tn(88) As String
  3. Dim Left As _MEM, Right As _MEM
  4.  
  5.  
  6.  
  7.  
  8. Print "Welcone to Random Tones and Chords Generator v0.1b"
  9. Input "Please specify Chord possibility in % (25):"; uaw$
  10. Input "Please set music time [sec] for generating WAV file (120):"; uWAVLen
  11. Input "Please set BPM (120):"; ubpm$
  12. Input "Please set Pauses possibility in % (5):"; up$
  13.  
  14. If uWAVLen$ = "" Or Val(uWAVLen$) < 0 Or Val(uWAVLen$) > 1000 Then
  15.     WAVLen = 120
  16. Else WAVLen = Val(uWAVLen$)
  17. Print "Music Time:"; LTrim$(Str$(WAVLen)); "s"
  18.  
  19. If uaw$ = "" Or Val(uaw$) < 0 Or Val(uaw$) > 100 Then
  20.     aw = 25
  21. Else aw = Val(uaw$)
  22. Print "Chords possibility:"; aw; "%"
  23.  
  24. If ubpm$ = "" Or Val(ubpm$) < 0 Or Val(ubpm$) > 1000 Then
  25.     bpm = 120
  26. Else bpm = Val(ubpm$)
  27. Print "BPM:"; bpm
  28.  
  29.  
  30. If up$ = "" Or Val(up$) < 0 Or Val(up$) > 100 Then
  31.     pperc = 5
  32. Else pperc = Val(up$)
  33. Print "Pauses:"; LTrim$(Str$(pperc)); "%"
  34.  
  35.  
  36. Dim RawMusic(_Ceil(_SndRate * WAVLen)) As Single
  37.  
  38. Left = _Mem(RawMusic())
  39. Right = _Mem(RawMusic()) 'mono signal, so both channels are the same
  40.  
  41.  
  42. 'bpm = 120
  43. 'interval 1 and 2 (semitones)
  44. int1 = 4
  45. int2 = 7
  46. 'interval possibility percent
  47. 'aw = 25
  48. 'tone minimum and maximum
  49. tmin = 35
  50. tmax = 47
  51. 'lengths min and max
  52. lmin = 2
  53. lmax = 4
  54. 'fill the tone names
  55. For i = 1 To 88
  56.     f = ((2 ^ ((i - 49) / 12)) * 440)
  57.     fm(i) = CInt(f)
  58.     Select Case i Mod 12
  59.         Case 1: tn(i) = "A"
  60.         Case 2: tn(i) = "A#"
  61.         Case 3: tn(i) = "B"
  62.         Case 4: tn(i) = "C"
  63.         Case 5: tn(i) = "C#"
  64.         Case 6: tn(i) = "D"
  65.         Case 7: tn(i) = "D#"
  66.         Case 8: tn(i) = "E"
  67.         Case 9: tn(i) = "F"
  68.         Case 10: tn(i) = "F#"
  69.         Case 11: tn(i) = "G"
  70.         Case 0: tn(i) = "G#"
  71.     End Select
  72.     'Select Case Int(i / 12)
  73.     '    Case 0: tn(i) = tn(i) + "0"
  74.  
  75.     'End Select
  76.     'DEBUG
  77.     'Print f; tn(i)
  78.     'If i > 24 Then Sleep
  79.  
  80. 'delete all sharp tones
  81. For i = 1 To 88
  82.     If Mid$(tn(i), 2, 1) = "#" Then
  83.         tn(i) = tn(i - 1)
  84.         fm(i) = fm(i - 1)
  85.     End If
  86. 'DEBUG fm(49)="A"
  87. 'Print fm(49)
  88.  
  89. 'fill the lengths
  90. For i = 1 To 7
  91.     lm(i) = 2 ^ i / 2
  92.     'DEBUG
  93.     'Print lm(i)
  94.  
  95.  
  96.     'tones between tmin and tmax
  97.     i = CInt((Rnd * (tmax - tmin)) + tmin)
  98.  
  99.     'Pauses
  100.     If Rnd < pperc / 100 Then p = 1 Else p = 0
  101.  
  102.     lr = lm(CInt(Rnd * (lmax - lmin)) + lmin) 'Length out of the lenght fields between 2 and 4
  103.     L = 1 / lr * 60 / bpm * 4 'Lenght is parts of a second from the length fields multiplied by bpm
  104.  
  105.     If Rnd < aw / 100 Then
  106.         akk = 1
  107.     Else akk = 0
  108.     End If
  109.  
  110.     t = 0
  111.     If akk = 1 And p = 0 Then
  112.         Print "1/"; LTrim$(Str$(lr)); " Tone:"; tn(i); "+"; tn(i + int1); "+"; tn(i + 7)
  113.     ElseIf akk = 0 And p = 0 Then Print "1/"; LTrim$(Str$(lr)); " Tone:"; tn(i)
  114.     ElseIf p = 1 Then Print "1/"; LTrim$(Str$(lr)); " Pause"
  115.     End If
  116.     Do
  117.         'queue some sound
  118.         Do While t < L 'you may wish to adjust this
  119.             sample1 = Sin(t * fm(i) * Atn(1) * 8) / 3 * 2
  120.             sample1 = sample1 * Exp(-t * L) / 3 * 2
  121.  
  122.             t = t + 1 / _SndRate
  123.  
  124.             If akk = 1 Then
  125.                 sample2 = Sin(t * fm(i + int1) * Atn(1) * 8) / 3 * 2
  126.                 sample2 = sample2 * Exp(-t * L) / 3 * 2
  127.                 sample1 = (sample1 + sample2) / 2
  128.  
  129.                 '_SndRaw sample2
  130.                 't = t + 1 / _SndRate
  131.                 sample3 = Sin(t * fm(i + int2) * Atn(1) * 8) / 3 * 2
  132.                 sample3 = sample3 * Exp(-t * L) / 3 * 2
  133.                 sample1 = (sample1 + sample3) / 2
  134.                 '_SndRaw sample
  135.                 't = t + 1 / _SndRate
  136.             End If
  137.             If p = 1 Then sample1 = 0
  138.             _SndRaw sample1
  139.             RawMusic(rwi) = sample1
  140.             rwi = rwi + 1
  141.  
  142.             If rwi > UBound(RawMusic) Then
  143.                 Print "Sound generated, saving to file generated.wav"
  144.                 _Delay .5
  145.                 SAVESOUND8S Left, Right, "generated.wav"
  146.                 _MemFree Left
  147.                 _MemFree Right
  148.                 Erase RawMusic
  149.                 System
  150.             End If
  151.         Loop
  152.  
  153.  
  154.     Loop While t < L 'play for l seconds
  155.  
  156.     Do While _SndRawLen > 0 'Finish any left over queued sound!
  157.     Loop
  158.  
  159.  
  160. Loop While in = ""
  161.  
  162.  
  163.  
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170.  
  171. Sub SAVESOUND8S (Left As _MEM, Right As _MEM, file As String) 'Left and Right memory blocks contains value -1 to 1 (_SNDRAW compatible)
  172.  
  173.     Size = OFFSET_to_I64(Left.SIZE) 'convertion is used for WAV file header, becuse offset value can not be used directly
  174.  
  175.     Type head8
  176.         chunk As String * 4 '       4 bytes  (RIFF)
  177.         size As Long '              4 bytes  (file size)
  178.         fomat As String * 4 '       4 bytes  (WAVE)
  179.         sub1 As String * 4 '        4 bytes  (fmt )
  180.         subchunksize As Long '      4 bytes  (lo / hi), $00000010 for PCM audio
  181.         format As Integer '         2 bytes  (0001 = standard PCM, 0101 = IBM mu-law, 0102 = IBM a-law, 0103 = IBM AVC ADPCM)
  182.         channels As Integer '       2 bytes  (1 = mono, 2 = stereo)
  183.         rate As Long '              4 bytes  (sample rate, standard is 44100)
  184.         ByteRate As Long '          4 bytes  (= sample rate * number of channels * (bits per channel /8))
  185.         Block As Integer '          2 bytes  (block align = number of channels * bits per sample /8)
  186.         Bits As Integer '           2 bytes  (bits per sample. 8 = 8, 16 = 16)
  187.         subchunk2 As String * 4 '   4 bytes  ("data")  contains begin audio samples
  188.         lenght As Long '            4 bytes  Data block size
  189.     End Type '                     44 bytes  total
  190.     Dim H8 As head8
  191.     ch = FreeFile
  192.  
  193.     H8.chunk = "RIFF"
  194.     H8.size = 44 + Size / 2
  195.  
  196.     H8.fomat = "WAVE"
  197.     H8.sub1 = "fmt "
  198.     H8.subchunksize = 16
  199.     H8.format = 1
  200.     H8.channels = 2
  201.     H8.rate = 44100
  202.     H8.ByteRate = 44100 * 2 * 8 / 8
  203.     H8.Block = 2
  204.     H8.Bits = 8
  205.     H8.subchunk2 = "data"
  206.     H8.lenght = Size / 2
  207.     If _FileExists(file$) Then Kill file$
  208.  
  209.     Open file$ For Binary As #ch
  210.     Put #ch, , H8
  211.  
  212.     Dim LeftChannel8 As _Byte, RightChannel8 As _Byte, RawLeft As Single, RawRight As Single
  213.     Dim Recalc As _MEM, size As _Offset
  214.  
  215.     size = Left.SIZE 'now this value is for memory size used by SINGLE ARRAY - WAV 8bit need 1 byte for 1 channel and 1 sample
  216.  
  217.     'recalculate audiodata to file - byte - values
  218.  
  219.     Recalc = _MemNew(size / 2) 'this is value used by WAV - size is 4 byte per sample, we recording stereo (2 x 1 byte) therefore is this divided by 2
  220.  
  221.     start& = 0: LRO& = 0
  222.     Do Until start& = Left.SIZE
  223.         RawLeft = _MemGet(Left, Left.OFFSET + start&, Single)
  224.         RawRight = _MemGet(Right, Right.OFFSET + start&, Single)
  225.  
  226.         LeftChannel8 = 128 - RawLeft * 128
  227.         RightChannel8 = 128 - RawRight * 128
  228.  
  229.         _MemPut Recalc, Recalc.OFFSET + s&, LeftChannel8
  230.         _MemPut Recalc, Recalc.OFFSET + s& + 1, RightChannel8
  231.         s& = s& + 2
  232.         start& = start& + 4
  233.     Loop
  234.  
  235.     'write audio data to file
  236.  
  237.     WAVeRAW$ = Space$(s&)
  238.     _MemGet Recalc, Recalc.OFFSET, WAVeRAW$
  239.     Put #ch, , WAVeRAW$
  240.  
  241.     'erase memory
  242.     _MemFree Recalc
  243.     WAVeRAW$ = ""
  244.     Close ch
  245.  
  246. Function OFFSET_to_I64 (value As _Offset)
  247.     Dim m As _MEM
  248.     $If 32BIT Then
  249.         DIM num AS LONG
  250.         m = _MEM(num)
  251.         _MEMPUT m,m.offset, value
  252.         Offset_to_i64 = num
  253.         _MEMFREE m
  254.     $Else
  255.         Dim num As _Integer64
  256.         m = _Mem(num)
  257.         _MemPut m, m.OFFSET, value
  258.         OFFSET_to_I64 = num
  259.         _MemFree m
  260.     $End If
  261.  

2
Repair row 18 in your last source code as:

DIM RawMusic(_CEIL(_SNDRATE * VAL(uWAVLen$))) AS SINGLE

No. uWAVLen is just the user input. Therefore the u Character in front. I capture it as a String to validate against "" (just pressing enter for default).
After the check for "" and below 0 and above 1000, the uWAVLen gets converted to WAVLen=VAL(uWAVLen). (Line 32)
It works like you intended. ;-)

3
I added an input check and default (120s) for WaveLen and added a BPM input with check and default (120bpm).
Do you think 120 Seconds is to short for WaveLen?

Code: QB64: [Select]
  1. Dim fm(88) As Double
  2. Dim tn(88) As String
  3. Dim Left As _MEM, Right As _MEM
  4.  
  5.  
  6.  
  7.  
  8. Print "Welcone to Random Tones and Chords Generator v0.1b"
  9. Input "Please specify Chord possibility in % (25)"; uaw$
  10. Input "Please set BPM (120)"; ubpm$
  11. Input "Please set music time [sec] for generating WAV file:(120)"; uWAVLen$
  12.  
  13. Dim RawMusic(_Ceil(_SndRate * WAVLen)) As Single
  14.  
  15. Left = _Mem(RawMusic())
  16. Right = _Mem(RawMusic()) 'mono signal, so both channels are the same
  17.  
  18. If uaw$ = "" Or Val(uaw$) < 0 Or Val(uaw$) > 100 Then
  19.     aw = 25
  20. Else aw = Val(uaw$)
  21. Print "Chords possibility:"; aw; "%"
  22.  
  23.  
  24. If uWAVLen$ = "" Or Val(uWAVLen$) < 0 Or Val(uWAVLen$) > 1000 Then
  25.     WAVLen = 120
  26. Else WAVLen = Val(uWAVLen$)
  27. Print "Music Time:"; LTrim$(Str$(WAVLen)); "s"
  28.  
  29. If ubpm$ = "" Or Val(ubpm$) < 0 Or Val(ubpm$) > 1000 Then
  30.     bpm = 120
  31. Else bpm = Val(ubpm$)
  32. Print "BPM:"; bpm
  33.  
  34.  
  35. 'bpm = 120
  36. 'interval 1 and 2 (semitones)
  37. int1 = 4
  38. int2 = 7
  39. 'interval possibility percent
  40. 'aw = 25
  41. 'tone minimum and maximum
  42. tmin = 35
  43. tmax = 47
  44. 'lengths min and max
  45. lmin = 2
  46. lmax = 4
  47. 'fill the tone names
  48. For i = 1 To 88
  49.     f = ((2 ^ ((i - 49) / 12)) * 440)
  50.     fm(i) = CInt(f)
  51.     Select Case i Mod 12
  52.         Case 1: tn(i) = "A"
  53.         Case 2: tn(i) = "A#"
  54.         Case 3: tn(i) = "B"
  55.         Case 4: tn(i) = "C"
  56.         Case 5: tn(i) = "C#"
  57.         Case 6: tn(i) = "D"
  58.         Case 7: tn(i) = "D#"
  59.         Case 8: tn(i) = "E"
  60.         Case 9: tn(i) = "F"
  61.         Case 10: tn(i) = "F#"
  62.         Case 11: tn(i) = "G"
  63.         Case 0: tn(i) = "G#"
  64.     End Select
  65.     'Select Case Int(i / 12)
  66.     '    Case 0: tn(i) = tn(i) + "0"
  67.  
  68.     'End Select
  69.     'DEBUG
  70.     'Print f; tn(i)
  71.     'If i > 24 Then Sleep
  72.  
  73. 'delete all sharp tones
  74. For i = 1 To 88
  75.     If Mid$(tn(i), 2, 1) = "#" Then
  76.         tn(i) = tn(i - 1)
  77.         fm(i) = fm(i - 1)
  78.     End If
  79. 'DEBUG fm(49)="A"
  80. 'Print fm(49)
  81.  
  82. 'fill the lengths
  83. For i = 1 To 7
  84.     lm(i) = 2 ^ i / 2
  85.     'DEBUG
  86.     'Print lm(i)
  87.  
  88.  
  89.     'tones between tmin and tmax
  90.     i = CInt((Rnd * (tmax - tmin)) + tmin)
  91.  
  92.     lr = lm(CInt(Rnd * (lmax - lmin)) + lmin) 'Length out of the lenght fields between 2 and 4
  93.     L = 1 / lr * 60 / bpm * 4 'Lenght is parts of a second from the length fields multiplied by bpm
  94.  
  95.     If Rnd < aw / 100 Then
  96.         akk = 1
  97.     Else akk = 0
  98.     End If
  99.  
  100.     t = 0
  101.     If akk = 1 Then
  102.         Print "Length 1/"; LTrim$(Str$(lr)); " Tone:"; tn(i); "+"; tn(i + int1); "+"; tn(i + 7)
  103.     Else Print "Length 1/"; LTrim$(Str$(lr)); " Tone:"; tn(i)
  104.     End If
  105.     Do
  106.         'queue some sound
  107.         Do While t < L 'you may wish to adjust this
  108.             sample1 = Sin(t * fm(i) * Atn(1) * 8) / 3 * 2
  109.             sample1 = sample1 * Exp(-t * L) / 3 * 2
  110.  
  111.             t = t + 1 / _SndRate
  112.  
  113.             If akk = 1 Then
  114.                 sample2 = Sin(t * fm(i + int1) * Atn(1) * 8) / 3 * 2
  115.                 sample2 = sample2 * Exp(-t * L) / 3 * 2
  116.                 sample1 = (sample1 + sample2) / 2
  117.                 '_SndRaw sample2
  118.                 't = t + 1 / _SndRate
  119.                 sample3 = Sin(t * fm(i + int2) * Atn(1) * 8) / 3 * 2
  120.                 sample3 = sample3 * Exp(-t * L) / 3 * 2
  121.                 sample1 = (sample1 + sample3) / 2
  122.                 '_SndRaw sample
  123.                 't = t + 1 / _SndRate
  124.             End If
  125.  
  126.             _SndRaw sample1
  127.             RawMusic(rwi) = sample1
  128.             rwi = rwi + 1
  129.  
  130.             If rwi > UBound(RawMusic) Then
  131.                 Print "Sound generated, saving to file generated.wav"
  132.                 _Delay .5
  133.                 SAVESOUND8S Left, Right, "generated.wav"
  134.                 _MemFree Left
  135.                 _MemFree Right
  136.                 Erase RawMusic
  137.                 System
  138.             End If
  139.         Loop
  140.  
  141.  
  142.     Loop While t < L 'play for l seconds
  143.  
  144.     Do While _SndRawLen > 0 'Finish any left over queued sound!
  145.     Loop
  146.  
  147.  
  148. Loop While in = ""
  149.  
  150.  
  151.  
  152.  
  153.  
  154.  
  155.  
  156.  
  157.  
  158.  
  159. Sub SAVESOUND8S (Left As _MEM, Right As _MEM, file As String) 'Left and Right memory blocks contains value -1 to 1 (_SNDRAW compatible)
  160.  
  161.     Size = OFFSET_to_I64(Left.SIZE) 'convertion is used for WAV file header, becuse offset value can not be used directly
  162.  
  163.     Type head8
  164.         chunk As String * 4 '       4 bytes  (RIFF)
  165.         size As Long '              4 bytes  (file size)
  166.         fomat As String * 4 '       4 bytes  (WAVE)
  167.         sub1 As String * 4 '        4 bytes  (fmt )
  168.         subchunksize As Long '      4 bytes  (lo / hi), $00000010 for PCM audio
  169.         format As Integer '         2 bytes  (0001 = standard PCM, 0101 = IBM mu-law, 0102 = IBM a-law, 0103 = IBM AVC ADPCM)
  170.         channels As Integer '       2 bytes  (1 = mono, 2 = stereo)
  171.         rate As Long '              4 bytes  (sample rate, standard is 44100)
  172.         ByteRate As Long '          4 bytes  (= sample rate * number of channels * (bits per channel /8))
  173.         Block As Integer '          2 bytes  (block align = number of channels * bits per sample /8)
  174.         Bits As Integer '           2 bytes  (bits per sample. 8 = 8, 16 = 16)
  175.         subchunk2 As String * 4 '   4 bytes  ("data")  contains begin audio samples
  176.         lenght As Long '            4 bytes  Data block size
  177.     End Type '                     44 bytes  total
  178.     Dim H8 As head8
  179.     ch = FreeFile
  180.  
  181.     H8.chunk = "RIFF"
  182.     H8.size = 44 + Size / 2
  183.  
  184.     H8.fomat = "WAVE"
  185.     H8.sub1 = "fmt "
  186.     H8.subchunksize = 16
  187.     H8.format = 1
  188.     H8.channels = 2
  189.     H8.rate = 44100
  190.     H8.ByteRate = 44100 * 2 * 8 / 8
  191.     H8.Block = 2
  192.     H8.Bits = 8
  193.     H8.subchunk2 = "data"
  194.     H8.lenght = Size / 2
  195.     If _FileExists(file$) Then Kill file$
  196.  
  197.     Open file$ For Binary As #ch
  198.     Put #ch, , H8
  199.  
  200.     Dim LeftChannel8 As _Byte, RightChannel8 As _Byte, RawLeft As Single, RawRight As Single
  201.     Dim Recalc As _MEM, size As _Offset
  202.  
  203.     size = Left.SIZE 'now this value is for memory size used by SINGLE ARRAY - WAV 8bit need 1 byte for 1 channel and 1 sample
  204.  
  205.     'recalculate audiodata to file - byte - values
  206.  
  207.     Recalc = _MemNew(size / 2) 'this is value used by WAV - size is 4 byte per sample, we recording stereo (2 x 1 byte) therefore is this divided by 2
  208.  
  209.     start& = 0: LRO& = 0
  210.     Do Until start& = Left.SIZE
  211.         RawLeft = _MemGet(Left, Left.OFFSET + start&, Single)
  212.         RawRight = _MemGet(Right, Right.OFFSET + start&, Single)
  213.  
  214.         LeftChannel8 = 128 - RawLeft * 128
  215.         RightChannel8 = 128 - RawRight * 128
  216.  
  217.         _MemPut Recalc, Recalc.OFFSET + s&, LeftChannel8
  218.         _MemPut Recalc, Recalc.OFFSET + s& + 1, RightChannel8
  219.         s& = s& + 2
  220.         start& = start& + 4
  221.     Loop
  222.  
  223.     'write audio data to file
  224.  
  225.     WAVeRAW$ = Space$(s&)
  226.     _MemGet Recalc, Recalc.OFFSET, WAVeRAW$
  227.     Put #ch, , WAVeRAW$
  228.  
  229.     'erase memory
  230.     _MemFree Recalc
  231.     WAVeRAW$ = ""
  232.     Close ch
  233.  
  234. Function OFFSET_to_I64 (value As _Offset)
  235.     Dim m As _MEM
  236.     $If 32BIT Then
  237.         DIM num AS LONG
  238.         m = _MEM(num)
  239.         _MEMPUT m,m.offset, value
  240.         Offset_to_i64 = num
  241.         _MEMFREE m
  242.     $Else
  243.         Dim num As _Integer64
  244.         m = _Mem(num)
  245.         _MemPut m, m.OFFSET, value
  246.         OFFSET_to_I64 = num
  247.         _MemFree m
  248.     $End If
  249.  
  250.  

4
That LIKE button, it would mean that you write in the field where the individual tones starts and ends (from which sample to which sample).

I would save the sequence of the last x transitions, so for one example if I have a transition from C4 to E4, I would write a transition of 2 full tones in the like field.
Or for a melody, I would write the transitions from the last x tones and prefer these transitions more.
For that, I would have to calculate a whole block with lengths and tones before the tone generation starts.
So I could pick up the sequence that the user liked, again.

5
@you can generate sound files

Wow, how cool is that! I could never accomplish writing a WAV file.

I also thought about adding a load and save function,
and saving or loading the tone names and Octaves and Chords in a Text-File.

Or for example (this is (for me )a huge project,) adding a "like-key",
so the Program would play the same chord transitions that you liked more often.

But now the chords are note gone.
Thank you!

6
I could not get the program to work with your  _SNDRAWOPEN method, it always failed on the first _SNDRAW
I reverted completely to your first method of adding the samples and dividing by 2.
This is the newest code. The Chords work and everything else too, so far.
Sometimes I have clicks, but I can live with that.

Code: QB64: [Select]
  1. Dim fm(88) As Double
  2. Dim tn(88) As String
  3.  
  4. Print "Welcone to Random Tones and Chords Generator v0.1b"
  5. Input "Please specify Chord possibility in % (25)"; uaw$
  6. If uaw$ = "" Or Val(uaw$) < 0 Or Val(uaw$) > 100 Then
  7.     aw = 25
  8. Else aw = Val(uaw$)
  9. Print "Chords possibility:"; aw; "%"
  10. bpm = 120
  11. 'interval 1 and 2 (semitones)
  12. int1 = 4
  13. int2 = 7
  14. 'interval possibility percent
  15. 'aw = 25
  16. 'tone minimum and maximum
  17. tmin = 35
  18. tmax = 47
  19. 'lengths min and max
  20. lmin = 2
  21. lmax = 4
  22. 'fill the tone names
  23. For i = 1 To 88
  24.     f = ((2 ^ ((i - 49) / 12)) * 440)
  25.     fm(i) = CInt(f)
  26.     Select Case i Mod 12
  27.         Case 1: tn(i) = "A"
  28.         Case 2: tn(i) = "A#"
  29.         Case 3: tn(i) = "B"
  30.         Case 4: tn(i) = "C"
  31.         Case 5: tn(i) = "C#"
  32.         Case 6: tn(i) = "D"
  33.         Case 7: tn(i) = "D#"
  34.         Case 8: tn(i) = "E"
  35.         Case 9: tn(i) = "F"
  36.         Case 10: tn(i) = "F#"
  37.         Case 11: tn(i) = "G"
  38.         Case 0: tn(i) = "G#"
  39.     End Select
  40.     'Select Case Int(i / 12)
  41.     '    Case 0: tn(i) = tn(i) + "0"
  42.  
  43.     'End Select
  44.     'DEBUG
  45.     'Print f; tn(i)
  46.     'If i > 24 Then Sleep
  47.  
  48. 'delete all sharp tones
  49. For i = 1 To 88
  50.     If Mid$(tn(i), 2, 1) = "#" Then
  51.         tn(i) = tn(i - 1)
  52.         fm(i) = fm(i - 1)
  53.     End If
  54. 'DEBUG fm(49)="A"
  55. 'Print fm(49)
  56.  
  57. 'fill the lengths
  58. For i = 1 To 7
  59.     lm(i) = 2 ^ i / 2
  60.     'DEBUG
  61.     'Print lm(i)
  62.  
  63.  
  64.     'tones between tmin and tmax
  65.     i = CInt((Rnd * (tmax - tmin)) + tmin)
  66.  
  67.     lr = lm(CInt(Rnd * (lmax - lmin)) + lmin) 'Length out of the lenght fields between 2 and 4
  68.     l = 1 / lr * 60 / bpm * 4 'Lenght is parts of a second from the length fields multiplied by bpm
  69.  
  70.     If Rnd < aw / 100 Then
  71.         akk = 1
  72.     Else akk = 0
  73.     End If
  74.  
  75.     t = 0
  76.     If akk = 1 Then
  77.         Print "Length 1/"; LTrim$(Str$(lr)); " Tone:"; tn(i); "+"; tn(i + int1); "+"; tn(i + 7)
  78.     Else Print "Length 1/"; LTrim$(Str$(lr)); " Tone:"; tn(i)
  79.     End If
  80.     Do
  81.         'queue some sound
  82.         Do While t < l 'you may wish to adjust this
  83.             sample1 = Sin(t * fm(i) * Atn(1) * 8) / 3 * 2
  84.             sample1 = sample1 * Exp(-t * l) / 3 * 2
  85.  
  86.             t = t + 1 / _SndRate
  87.  
  88.             If akk = 1 Then
  89.                 sample2 = Sin(t * fm(i + int1) * Atn(1) * 8) / 3 * 2
  90.                 sample2 = sample2 * Exp(-t * l) / 3 * 2
  91.                 sample1 = (sample1 + sample2) / 2
  92.                 '_SndRaw sample2
  93.                 't = t + 1 / _SndRate
  94.                 sample3 = Sin(t * fm(i + int2) * Atn(1) * 8) / 3 * 2
  95.                 sample3 = sample3 * Exp(-t * l) / 3 * 2
  96.                 sample1 = (sample1 + sample3) / 2
  97.                 '_SndRaw sample
  98.                 't = t + 1 / _SndRate
  99.             End If
  100.             _SndRaw sample1
  101.  
  102.         Loop
  103.  
  104.  
  105.     Loop While t < l 'play for l seconds
  106.  
  107.     Do While _SndRawLen > 0 'Finish any left over queued sound!
  108.     Loop
  109.  
  110.     in = InKey$
  111. Loop While in = ""
  112.  
  113.  
  114.  

7
Not. I always have a different sound if uncomment the previous two _SNDRAW commands. Please make sure that when using _SNDRAW you have turned off all sound effects such as dolby and surround sound, it has a direct effect on the _SNDRAW output.

First, I want to thank you for you for your compliment a few post before, I forgot that entirely.

Second, it turns out; You was right with _SNDRAWOPEN and I was wrong in my last post.
Please excuse me, I was in a hurry and had not the time to listen carefully.
Also, the 440+220+110 Hz example, was a bad example (from me).

I wrote the example Code now for C-Major (C-E-G),
and compared to this recording:



It turns out that the code from you produces indeed the right Chord.

Now I am editing my Melodies code to fit your good (and completely accurate) example.
Thank You for teaching me!

For completeness, this example code produces a C Major Chord in Octave 4 (C4-E4-G4)

Code: QB64: [Select]
  1. t = 0
  2. tmp$ = "Sample = ##.#####   Time = ##.#####"
  3. Locate 1, 60: Print "Rate:"; _SndRate
  4.  
  5.  
  6.     'queue some sound
  7.     Do Until t >= 3 'you may wish to adjust this
  8.         sample1 = Sin(t * 261.626 * Atn(1) * 8) '440Hz sine wave (t * 440 * 2?)
  9.         sample1 = sample1 * Exp(-t * 3) / 3 'fade out eliminates clicks after sound
  10.        
  11.         sample2 = Sin(t * 329.628 * Atn(1) * 8) '440Hz sine wave (t * 440 * 2?)
  12.         sample2 = sample2 * Exp(-t * 3) / 3 'fade out eliminates clicks after sound
  13.  
  14.         sample3 = Sin(t * 391.995 * Atn(1) * 8) '440Hz sine wave (t * 440 * 2?)
  15.         sample3 = sample3 * Exp(-t * 3) / 3 'fade out eliminates clicks after sound
  16.  
  17.         t = t + 1 / _SndRate
  18.         _SndRaw sample1, , S1
  19.         _SndRawDone
  20.         _SndRaw sample2, , S2
  21.         _SndRawDone
  22.         _SndRaw sample3, , S3
  23.         _SndRawDone
  24.  
  25.         Locate 1, 1: Print Using tmp$; sample; t
  26.  
  27.  
  28.     Loop
  29.  
  30.     _SndClose S1
  31.     _SndClose S2
  32.     _SndClose S3
  33.  
  34.     'do other stuff, but it may interrupt sound
  35.     Locate 1, 1: Print Using tmp$; sample; t
  36. Loop While t < 3.0 'play for 3 seconds
  37.  
  38. Do While _SndRawLen > 0 'Finish any left over queued sound!
  39.  
  40.  
  41.  


8
Well, I think I've found a solution.

...

Code: QB64: [Select]
  1. t = 0
  2. tmp$ = "Sample = ##.#####   Time = ##.#####"
  3. LOCATE 1, 60: PRINT "Rate:"; _SNDRATE
  4.  
  5.  
  6.     'queue some sound
  7.     DO UNTIL t >= 3 'you may wish to adjust this
  8.         sample1 = SIN(t * 440 * ATN(1) * 8) '440Hz sine wave (t * 440 * 2?)
  9.         sample1 = sample1 * EXP(-t * 3) 'fade out eliminates clicks after sound
  10.         '_SndRaw sample
  11.         ' t = t + 1 / _SNDRATE 'sound card sample frequency determines time
  12.  
  13.         sample2 = SIN(t * 110 * ATN(1) * 8) '440Hz sine wave (t * 440 * 2?)
  14.         sample2 = sample2 * EXP(-t * 3) 'fade out eliminates clicks after sound
  15.         '_SndRaw sample
  16.         ' t = t + 1 / _SndRate
  17.  
  18.         '  sample1 = (sample1 + sample2) / 2
  19.  
  20.         sample3 = SIN(t * 220 * ATN(1) * 8) '440Hz sine wave (t * 440 * 2?)
  21.         sample3 = sample3 * EXP(-t * 3) 'fade out eliminates clicks after sound
  22.  
  23.         ' sample1 = (sample1 + sample3) / 2
  24.  
  25.         t = t + 1 / _SNDRATE
  26.         _SNDRAW sample1, , S1
  27.         _SNDRAWDONE
  28.         _SNDRAW sample2, , S2
  29.         _SNDRAWDONE
  30.         _SNDRAW sample3, , S3
  31.         _SNDRAWDONE
  32.  
  33.         '   _SNDRAW sample1
  34.         '   _SNDRAW sample2
  35.         '   _SNDRAW sample3
  36.  
  37.         LOCATE 1, 1: PRINT USING tmp$; sample; t
  38.  
  39.  
  40.     LOOP
  41.  
  42.     _SNDCLOSE S1
  43.     _SNDCLOSE S2
  44.     _SNDCLOSE S3
  45.  
  46.     'do other stuff, but it may interrupt sound
  47.     LOCATE 1, 1: PRINT USING tmp$; sample; t
  48. LOOP WHILE t < 3.0 'play for 3 seconds
  49.  
  50. DO WHILE _SNDRAWLEN > 0 'Finish any left over queued sound!
  51.  
  52.  

This produces only the last Sample (3) of 220Hz, a bit distorted, unfortunately.
You can hear that yourself when you compare the sound of your code 
to the first and second _sndraw commented out.:

Code: QB64: [Select]
  1. t = 0
  2. tmp$ = "Sample = ##.#####   Time = ##.#####"
  3. LOCATE 1, 60: PRINT "Rate:"; _SNDRATE
  4.  
  5.  
  6.     'queue some sound
  7.     DO UNTIL t >= 3 'you may wish to adjust this
  8.         sample1 = SIN(t * 440 * ATN(1) * 8) '440Hz sine wave (t * 440 * 2?)
  9.         sample1 = sample1 * EXP(-t * 3) 'fade out eliminates clicks after sound
  10.         '_SndRaw sample
  11.         ' t = t + 1 / _SNDRATE 'sound card sample frequency determines time
  12.  
  13.         sample2 = SIN(t * 110 * ATN(1) * 8) '440Hz sine wave (t * 440 * 2?)
  14.         sample2 = sample2 * EXP(-t * 3) 'fade out eliminates clicks after sound
  15.         '_SndRaw sample
  16.         ' t = t + 1 / _SndRate
  17.  
  18.         '  sample1 = (sample1 + sample2) / 2
  19.  
  20.         sample3 = SIN(t * 220 * ATN(1) * 8) '440Hz sine wave (t * 440 * 2?)
  21.         sample3 = sample3 * EXP(-t * 3) 'fade out eliminates clicks after sound
  22.  
  23.         ' sample1 = (sample1 + sample3) / 2
  24.  
  25.         t = t + 1 / _SNDRATE
  26.         '_SNDRAW sample1, , S1
  27.         '_SNDRAWDONE
  28.         '_SNDRAW sample2, , S2
  29.         '_SNDRAWDONE
  30.         _SNDRAW sample3, , S3
  31.         _SNDRAWDONE
  32.  
  33.         '   _SNDRAW sample1
  34.         '   _SNDRAW sample2
  35.         '   _SNDRAW sample3
  36.  
  37.         LOCATE 1, 1: PRINT USING tmp$; sample; t
  38.  
  39.  
  40.     LOOP
  41.  
  42.     _SNDCLOSE S1
  43.     _SNDCLOSE S2
  44.     _SNDCLOSE S3
  45.  
  46.     'do other stuff, but it may interrupt sound
  47.     LOCATE 1, 1: PRINT USING tmp$; sample; t
  48. LOOP WHILE t < 3.0 'play for 3 seconds
  49.  
  50. DO WHILE _SNDRAWLEN > 0 'Finish any left over queued sound!
  51.  
  52.  

9
Well, I think I've found a solution.
I cant test right now, but this looks very promising. I will test and work your example code in my Program and write back to you. Later ;-)

10
Hi. Try, if this is repaired or is still broken:

The tones are now double the frequency and half the duration as they should.
But the Buzz is gone.

I edited your edits in to the example code. Is this right?
I think the t is only added 1/_SNDRATE because only one sample gets played.

This produces one tone, I think of 440 Hz.

Code: QB64: [Select]
  1. t = 0
  2. tmp$ = "Sample = ##.#####   Time = ##.#####"
  3. Locate 1, 60: Print "Rate:"; _SndRate
  4.     'queue some sound
  5.     Do While _SndRawLen < 3 'you may wish to adjust this
  6.         sample1 = Sin(t * 440 * Atn(1) * 8) '440Hz sine wave (t * 440 * 2π)
  7.         sample1 = sample1 * Exp(-t * 3) 'fade out eliminates clicks after sound
  8.         '_SndRaw sample
  9.         t = t + 1 / _SndRate 'sound card sample frequency determines time
  10.  
  11.         sample2 = Sin(t * 110 * Atn(1) * 8) '440Hz sine wave (t * 440 * 2π)
  12.         sample2 = sample2 * Exp(-t * 3) 'fade out eliminates clicks after sound
  13.         '_SndRaw sample
  14.         't = t + 1 / _SndRate
  15.  
  16.         sample1 = (sample1 + sample2) / 2
  17.  
  18.         sample3 = Sin(t * 220 * Atn(1) * 8) '440Hz sine wave (t * 440 * 2π)
  19.         sample3 = sample3 * Exp(-t * 3) 'fade out eliminates clicks after sound
  20.  
  21.         sample1 = (sample1 + sample3) / 2
  22.  
  23.         't = t + 1 / _SndRate
  24.         _SndRaw sample1
  25.     Loop
  26.  
  27.  
  28.     'do other stuff, but it may interrupt sound
  29.     Locate 1, 1: Print Using tmp$; sample; t
  30. Loop While t < 3.0 'play for 3 seconds
  31.  
  32. Do While _SndRawLen > 0 'Finish any left over queued sound!

11
I have edited the code, so it only play two tones in a chord (now without buzz).
I suggest 100% Chords possibility for maximal comfort, thats why I made it default ;-)

Code: QB64: [Select]
  1. Dim fm(88) As Double
  2. Dim tn(88) As String
  3.  
  4. Print "Welcone to Random Tones and Chords Generator v0.1b"
  5. Input "Please specify Chord possibility in % (25)"; uaw$
  6. If uaw$ = "" Or Val(uaw$) < 0 Or Val(uaw$) > 100 Then
  7.     aw = 100
  8. Else aw = Val(uaw$)
  9. Print "Chords possibility:"; aw; "%"
  10. bpm = 120
  11. 'interval 1 and 2 (semitones)
  12. int1 = 4
  13. int2 = 7
  14. 'interval possibility percent
  15. 'aw = 25
  16. 'tone minimum and maximum
  17. tmin = 35
  18. tmax = 47
  19. 'lengths min and max
  20. lmin = 2
  21. lmax = 4
  22. 'fill the tone names
  23. For i = 1 To 88
  24.     f = ((2 ^ ((i - 49) / 12)) * 440)
  25.     fm(i) = CInt(f)
  26.     Select Case i Mod 12
  27.         Case 1: tn(i) = "A"
  28.         Case 2: tn(i) = "A#"
  29.         Case 3: tn(i) = "B"
  30.         Case 4: tn(i) = "C"
  31.         Case 5: tn(i) = "C#"
  32.         Case 6: tn(i) = "D"
  33.         Case 7: tn(i) = "D#"
  34.         Case 8: tn(i) = "E"
  35.         Case 9: tn(i) = "F"
  36.         Case 10: tn(i) = "F#"
  37.         Case 11: tn(i) = "G"
  38.         Case 0: tn(i) = "G#"
  39.     End Select
  40.     'Select Case Int(i / 12)
  41.     '    Case 0: tn(i) = tn(i) + "0"
  42.  
  43.     'End Select
  44.     'DEBUG
  45.     'Print f; tn(i)
  46.     'If i > 24 Then Sleep
  47.  
  48. 'delete all sharp tones
  49. For i = 1 To 88
  50.     If Mid$(tn(i), 2, 1) = "#" Then
  51.         tn(i) = tn(i - 1)
  52.         fm(i) = fm(i - 1)
  53.     End If
  54. 'DEBUG fm(49)="A"
  55. 'Print fm(49)
  56.  
  57. 'fill the lengths
  58. For i = 1 To 7
  59.     lm(i) = 2 ^ i / 2
  60.     'DEBUG
  61.     'Print lm(i)
  62.  
  63.  
  64.     'tones between tmin and tmax
  65.     i = CInt((Rnd * (tmax - tmin)) + tmin)
  66.  
  67.     lr = lm(CInt(Rnd * (lmax - lmin)) + lmin) 'Length out of the lenght fields between 2 and 4
  68.     l = 1 / lr * 60 / bpm * 4 'Lenght is parts of a second from the length fields multiplied by bpm
  69.  
  70.     If Rnd < aw / 100 Then
  71.         akk = 1
  72.     Else akk = 0
  73.     End If
  74.     t = 1 / _SndRate
  75.     If akk = 1 Then
  76.         Print "Length 1/"; LTrim$(Str$(lr)); " Tone:"; tn(i); "+"; tn(i + int1) '; "+"; tn(i + 7)
  77.     Else Print "Length 1/"; LTrim$(Str$(lr)); " Tone:"; tn(i)
  78.     End If
  79.     Do
  80.         'queue some sound
  81.         Do While t < l 'you may wish to adjust this
  82.             sample = Sin(t * fm(i) * Atn(1) * 8) '440Hz sine wave (t * 440 * 2π)
  83.             sample = sample * Exp(-t * l) 'fade out eliminates clicks after sound
  84.             _SndRaw sample
  85.             t = t + 1 / _SndRate 'sound card sample frequency determines time
  86.  
  87.             If akk = 1 Then
  88.                 sample2 = Sin(t * fm(i + int1) * Atn(1) * 8)
  89.                 sample2 = sample2 * Exp(-t * l)
  90.                 _SndRaw sample2
  91.                 t = t + 1 / _SndRate
  92.                 'sample = Sin(t * fm(i + int2) * Atn(1) * 8)
  93.                 'sample = sample3 * Exp(-t * l)
  94.                 '_SndRaw sample
  95.                 't = t + 1 / _SndRate
  96.             End If
  97.  
  98.         Loop
  99.  
  100.  
  101.     Loop While t < l 'play for l seconds
  102.  
  103.     Do While _SndRawLen > 0 'Finish any left over queued sound!
  104.     Loop
  105.  
  106.  
  107.     in = InKey$
  108. Loop While in = ""
  109.  
  110.  

12
I think I discovered a bug. Even with a slighly modified example code from _SNDRAW Wiki, the buzz is there:
The Problem is not present with 2 Samples, but appears after 3 Samples and persists with any new Sample that you play after another.

Code: QB64: [Select]
  1. t = 0
  2. tmp$ = "Sample = ##.#####   Time = ##.#####"
  3. Locate 1, 60: Print "Rate:"; _SndRate
  4.     'queue some sound
  5.     Do While _SndRawLen < 3 'you may wish to adjust this
  6.         sample = Sin(t * 440 * Atn(1) * 8) '440Hz sine wave (t * 440 * 2π)
  7.         sample = sample * Exp(-t * 3) 'fade out eliminates clicks after sound
  8.         _SndRaw sample
  9.         t = t + 1 / _SndRate 'sound card sample frequency determines time
  10.         sample = Sin(t * 220 * Atn(1) * 8) '440Hz sine wave (t * 440 * 2π)
  11.         sample = sample * Exp(-t * 3) 'fade out eliminates clicks after sound
  12.         _SndRaw sample
  13.         t = t + 1 / _SndRate
  14.         sample = Sin(t * 220 * Atn(1) * 8) '440Hz sine wave (t * 440 * 2π)
  15.         sample = sample * Exp(-t * 3) 'fade out eliminates clicks after sound
  16.         _SndRaw sample
  17.         t = t + 1 / _SndRate
  18.  
  19.     Loop
  20.  
  21.     'do other stuff, but it may interrupt sound
  22.     Locate 1, 1: Print Using tmp$; sample; t
  23. Loop While t < 3.0 'play for 3 seconds
  24.  
  25. Do While _SndRawLen > 0 'Finish any left over queued sound!
  26.  
  27.  

13
Here's a good reference, Fellippe's tut on sound, there is something new to QB64 about capturing wave patterns:
https://www.qb64.org/forum/index.php?topic=3919.0
Thank you. I saw the Video a few days ago and that was the reason I discovered FM Synth Sample generation with _SNDRAW.
For the Video part with _SNDRAW, he basically covers the Example code from _SNDRAW in the Wiki,
which I also modified to get the samples. I think I will have to investigate further what it takes to generate a chord,
because I think I have made somehow a wrong assumption that I could just play the _SNDRAW samples after another to generate the Chords.

14
Are you talking about slight buzz I am getting on chords or do I have too many crumbs in/on my speakers?
Yes, the Buzz is the problem.

I looked in the Program you suggested, and that Program uses a slightly different method, _SNDPLAY, to play the sound of the Drum-Machine.
My Program uses _SNDRAW to generate the sound waves sample by sample, which it does obviously wrong in some way.


15
I have wrote a Program that Generates Melodies and Chords (in F-Major Intervals).
Most of the variable names come from Geman, but I translated the Prints to english.
How you like this? (Modifications are always welcome)

Code: QB64: [Select]
  1. Dim tonmat(30) As Integer
  2. Dim diff(30) As Integer
  3. Dim m(28) As String:
  4. m(1) = "V50O1C": m(2) = "V50O1D": m(3) = "V50O1E": m(4) = "V40O1F": m(5) = "V40O1G": m(6) = "V40O1A": m(7) = "V40O1B"
  5. m(8) = "V30O2C": m(9) = "V30O2D": m(10) = "V30O2E": m(11) = "V20O2F": m(12) = "V20O2G": m(13) = "V20O2A": m(14) = "V20O2B"
  6. m(15) = "V20O3C": m(16) = "V20O3D": m(17) = "V10O3E": m(18) = "V10O3F": m(19) = "V10O3G": m(20) = "V10O3A": m(21) = "V10O3B"
  7. Dim lm(7) As Integer
  8. lm(1) = 1: lm(2) = 2: lm(3) = 4: lm(4) = 8: lm(5) = 16: lm(6) = 32: lm(7) = 64
  9.  
  10. Print "<<<***---Welcome to Melodies and Chords v0.0.4beta by chlorophyll-zz---***>>>"
  11. Print "Values: Default in brackets,"
  12. Print "For default press Enter."
  13. Print "Were starting ;-)"
  14. start:
  15. Input "Automatic or Manual Mode? a/m (a)"; auto
  16. If auto <> "m" Then auto = "a"
  17. If auto = "a" Then Print "Automatic Mode" Else Print "Manual Mode"
  18. If auto = "m" Then
  19.     Input "Lowest Basetone? (C1 to B2) 1-14(1)"; minton: If minton < 1 Or minton > 14 Then minton = 1
  20.     Print
  21.     Input "Highest Basetone? (C1 to B2) 1-14(14)"; maxton: If maxton < 1 Or maxton > 14 Then maxton = 14
  22.     Print
  23. If auto = "a" Then
  24.     minton = 1
  25.     maxton = 14
  26. Print "Basetone from "; Mid$(m(minton), 5, 3); " to "; Mid$(m(maxton), 5, 3)
  27. If auto = "m" Then
  28.     Print "Maximum Duration of Tones? 1/ 1-2-4-8-16"
  29.     Input "                              1 2 3 4  5  1-6 (2) "; minlang
  30.     Print
  31.     If minlang < 1 Or minlang > 5 Then minlang = 2
  32.  
  33.     Print "Minimum Duration of Tones? 1/ 1-2-4-8-16"
  34.     Input "                              1 2 3 4  5  1-6 (4) "; maxlang
  35.     Print
  36.     If maxlang < 1 Or maxlang > 5 Then maxlang = 4
  37. If auto = "a" Then
  38.     minlang = 2
  39.     maxlang = 4
  40. Print "Duration 1/" + LTrim$(Str$(lm(minlang))) + " to 1/"; LTrim$(Str$(lm(maxlang)))
  41. If auto = "m" Then
  42.     Dim aws As String
  43.     Input "How much Chords Possibility in %? 0-100(25)"; aws: If aws = "" Or Val(aws) > 100 Then aws = "25"
  44.     Print
  45.     proz = Val(aws)
  46. If auto = "a" Then proz = 25
  47. Print LTrim$(Str$(proz)) + "% Chords Possibility"
  48. If auto = "m" Then
  49.     Input "1. Interval from Basetone? 1-7? (C-E=2) (2)"; intmin: If intmin < 1 Or intmin > 7 Then intmin = 2
  50.     Print
  51.     Input "2. Interval from Basetone? 1-7? (C-G=4) (4)"; intmax: If intmax < 1 Or intmax > 7 Then intmax = 4
  52.     Print
  53. If auto = "a" Then
  54.     intmin = 2
  55.     intmax = 4
  56. Print "1. Interval"; intmin; "Tones from Basetone, 2. Interval"; intmax; "Tones from Basetone"
  57.  
  58. debug = 0
  59.     anfang = anfang + 1
  60.     If anfang = 1 Then
  61.         For i = 20 To 1 Step -1
  62.             tonmat(i) = CInt(Rnd * (maxton - minton)) + minton
  63.             If debug = 1 Then Print ; Str$(i) + ". Tone:" + Str$(tonmat(i)) + ",";
  64.             diff(i) = tonmat(i) - tonmat(i + 1)
  65.             If debug = 1 Then Print "Difference " + Str$(i); ". "; diff(i)
  66.         Next i
  67.  
  68.     End If
  69.  
  70.     t = CInt(Rnd * (maxton - minton)) + minton
  71.     If debug = 1 And (t < 1 Or t > 28) Then Print "Tone below 1 or over 28 t="; t: Input t
  72.     n = m(t)
  73.  
  74.     l = CInt(Rnd * (maxlang - minlang)) + minlang
  75.     If debug = 1 And (l < 1 Or l > 7) Then Print "Duration below 1 or over 7 l="; l: Input l
  76.  
  77.  
  78.     lt = lm(l)
  79.  
  80.     rn = Rnd
  81.     If rn < (proz / 100) Then
  82.         akk = 1
  83.         n = n + "," + m(t + intmin) + "," + m(t + intmax)
  84.     End If
  85.  
  86.     If akk = 1 And l >= minlang + 1 And Rnd * .66 >= (proz / 100) Then
  87.         lt = lm(minlang)
  88.     End If
  89.     akk = 0
  90.  
  91.     If rn > (proz / 100) Then n = m(t)
  92.  
  93.     tone = "L" + LTrim$(Str$(lt)) + n
  94.  
  95.     z = z + 1
  96.     If z = 1 Then
  97.         Print "<<<*-For Restart press n-*>>>"
  98.         Print
  99.     End If
  100.     If z = 21 Then z = 0
  101.  
  102.     Print "Duration: 1/" + LTrim$(Str$(lt)) + Chr$(9) + "Note(s): ";
  103.     If Len(n) > 6 Then Print ; Mid$(n, 5, 2) + ", " + Mid$(n, 12, 2) + ", "; Mid$(n, 19, 2)
  104.     If Len(n) = 6 Then Print ; Mid$(n, 5, 2)
  105.     'V25O1C,V25O1G,V25A1
  106.     Print
  107.     Play tone
  108.  
  109.  
  110.  
  111.     For i = 20 To 1 Step -1
  112.         tonmat(i) = tonmat(i - 1)
  113.         If i = 1 Then tonmat(i) = t
  114.         If debug = 1 Then Print ; Str$(i) + ". Tone:" + Str$(tonmat(i)) + ",";
  115.         diff(i) = tonmat(i) - tonmat(i + 1)
  116.         If debug = 1 Then Print "Difference " + Str$(i); ". "; diff(i)
  117.     Next i
  118.  
  119.     If debug = 1 Then Sleep
  120.  
  121.     x = _KeyHit
  122.     If x Then
  123.         If x = -110 Then
  124.             x = 0
  125.             GoTo start:
  126.         End If
  127.     End If
  128.  

I have also rewrote the Program to have FM-Synth, because a tester suggested that.
First the Program did run as expected but then I edited something I forgot, and the Chords are now sounding garbled.
I think something is wrong about _SNDRAW or _SNDRAWLEN .
Could you have a quick look? Thank you in advance.

Code: QB64: [Select]
  1. Dim fm(88) As Double
  2. Dim tn(88) As String
  3.  
  4. Print "Welcone to Random Tones and Chords Generator v0.1b"
  5. Input "Please specify Chord possibility in % (25)"; uaw$
  6. If uaw$ = "" Or Val(uaw$) < 0 Or Val(uaw$) > 100 Then
  7.     aw = 25
  8. Else aw = Val(uaw$)
  9. Print "Chords possibility:"; aw; "%"
  10. bpm = 120
  11. 'interval 1 and 2 (semitones)
  12. int1 = 2
  13. int2 = 7
  14. 'interval possibility percent
  15. 'aw = 25
  16. 'tone minimum and maximum
  17. tmin = 35
  18. tmax = 47
  19. 'lengths min and max
  20. lmin = 2
  21. lmax = 4
  22. 'fill the tone names
  23. For i = 1 To 88
  24.     f = ((2 ^ ((i - 49) / 12)) * 440)
  25.     fm(i) = f
  26.     Select Case i Mod 12
  27.         Case 1: tn(i) = "A"
  28.         Case 2: tn(i) = "A#"
  29.         Case 3: tn(i) = "B"
  30.         Case 4: tn(i) = "C"
  31.         Case 5: tn(i) = "C#"
  32.         Case 6: tn(i) = "D"
  33.         Case 7: tn(i) = "D#"
  34.         Case 8: tn(i) = "E"
  35.         Case 9: tn(i) = "F"
  36.         Case 10: tn(i) = "F#"
  37.         Case 11: tn(i) = "G"
  38.         Case 0: tn(i) = "G#"
  39.     End Select
  40.     'Select Case Int(i / 12)
  41.     '    Case 0: tn(i) = tn(i) + "0"
  42.  
  43.     'End Select
  44.     'DEBUG
  45.     'Print f; tn(i)
  46.     'If i > 24 Then Sleep
  47.  
  48. 'delete all sharp tones
  49. For i = 1 To 88
  50.     If Mid$(tn(i), 2, 1) = "#" Then
  51.         tn(i) = tn(i - 1)
  52.         fm(i) = fm(i - 1)
  53.     End If
  54. 'DEBUG fm(49)="A"
  55. 'Print fm(49)
  56.  
  57. 'fill the lengths
  58. For i = 1 To 7
  59.     lm(i) = 2 ^ i / 2
  60.     'DEBUG
  61.     'Print lm(i)
  62.  
  63.  
  64.     'tones between tmin and tmax
  65.     i = CInt((Rnd * (tmax - tmin)) + tmin)
  66.  
  67.     lr = lm(CInt(Rnd * (lmax - lmin)) + lmin) 'Length out of the lenght fields between 2 and 4
  68.     l = 1 / lr * 60 / bpm * 4 'Lenght is parts of a second from the length fields multiplied by bpm
  69.  
  70.     If Rnd < aw / 100 Then
  71.         akk = 1
  72.     Else akk = 0
  73.     End If
  74.     t = 0
  75.     akk = 1
  76.     If akk = 1 Then
  77.         Print "Length 1/"; LTrim$(Str$(lr)); " Tone:"; tn(i); "+"; tn(i + 4); "+"; tn(i + 7)
  78.     Else Print "Length 1/"; LTrim$(Str$(lr)); " Tone:"; tn(i)
  79.     End If
  80.     Do
  81.         'queue some sound
  82.         Do While t < l 'you may wish to adjust this
  83.             sample = Sin(t * fm(i) * Atn(1) * 8) '440Hz sine wave (t * 440 * 2π)
  84.             sample = sample * Exp(-t * l) 'fade out eliminates clicks after sound
  85.             _SndRaw sample
  86.             t = t + 1 / _SndRate 'sound card sample frequency determines time
  87.  
  88.             If akk = 1 Then
  89.                 sample2 = Sin(t * fm(i + int1) * Atn(1) * 8)
  90.                 sample2 = sample2 * Exp(-t * l)
  91.                 _SndRaw sample2
  92.                 sample3 = Sin(t * fm(i + int2) * Atn(1) * 8)
  93.                 sample3 = sample3 * Exp(-t * l)
  94.                 _SndRaw sample3
  95.                 t = t + 2 / _SndRate
  96.             End If
  97.  
  98.  
  99.         Loop
  100.  
  101.  
  102.     Loop While t < l 'play for l seconds
  103.  
  104.     Do While _SndRawLen > 0 'Finish any left over queued sound!
  105.     Loop
  106.  
  107.     in = InKey$
  108. Loop While in = ""
  109.  

Pages: [1]