Author Topic: ConvertOffset, Please read it, try it and... who is bug? THX :)  (Read 3776 times)

0 Members and 1 Guest are viewing this topic.

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
ConvertOffset, Please read it, try it and... who is bug? THX :)
« on: October 16, 2021, 03:09:34 pm »
@SMcNeill

Hi Steve. I want to thank you for the convert offset function. I used my own solution, which seemed to work, but in fact I greatly destabilized QB64. My bad conversion caused random errors in a complex program, fortunately also in version 1.5 and also in version 2.0, when using MEM, DO LOOP loops were also stuck. There were also random errors when writing to the binary. The program simply crashed and Windows just announced: The program stopped working and was therefore terminated. I tried everything here. Everything I could think of. The program is far from complete and it would be difficult for anyone to know about it, because it involves a lot of interconnected fields together. Before I wanted to start adding English comments to the program, I remembered your function. It was out of desperation, I didn't know what to try anymore.

I inserted and replaced my function with your function. All problems are gone. I don't understand or see the reason. Here's the hellish thing I'll kick out of all my programs. Really, nothing else. Only this. I work in a 64 bit version. Maybe someone wonders why this is causing problems. Problems absolutely fatal. The ones that can't be found! If anyone knows why this does such an evil, please, I want to explain.

This
Code: QB64: [Select]
  1. Function OFFSET_to_I64&& (value As _Offset)
  2.     Dim m As _MEM
  3.     $If 32BIT Then
  4.         DIM num AS LONG
  5.         m = _MEM(num)
  6.         _MEMPUT m,m.offset, value
  7.         Offset_to_i64 = num
  8.         _MEMFREE m
  9.     $Else
  10.         Dim num As _Integer64
  11.         m = _Mem(num)
  12.         _MemPut m, m.OFFSET, value
  13.         OFFSET_to_I64 = num
  14.         _MemFree m
  15.     $End If
  16.  

is replaced with your very small modified function

Code: QB64: [Select]
  1.  
  2. Function ConvertOffset&& (value As _Offset)
  3.     Dim co As _Integer64
  4.     Dim m As _MEM 'Define a memblock
  5.     m = _Mem(value) 'Point it to use value
  6.     $If 64BIT Then
  7.         'On 64 bit OSes, an OFFSET is 8 bytes in size.  We can put it directly into an Integer64
  8.         _MemGet m, m.OFFSET, co&& 'Get the contents of the memblock and put the values there directly into ConvertOffset&&
  9.     $Else
  10.         'However, on 32 bit OSes, an OFFSET is only 4 bytes.  We need to put it into a LONG variable first
  11.         _MEMGET m, m.OFFSET, temp& 'Like this
  12.         co&& = temp& 'And then assign that long value to ConvertOffset&&
  13.     $End If
  14.     _MemFree m 'Free the memblock
  15.     ConvertOffset&& = co&&
  16.  
  17.  
« Last Edit: October 18, 2021, 03:24:41 pm by Petr »

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Thanks Steve for ConvertOffset function
« Reply #1 on: October 16, 2021, 03:15:40 pm »
Just to give you an idea - I'm talking about a sound editing program and hundreds of megabytes of data flow through fields and memory.

Offline RhoSigma

  • QB64 Developer
  • Forum Resident
  • Posts: 565
    • View Profile
Re: Thanks Steve for ConvertOffset function
« Reply #2 on: October 16, 2021, 03:32:06 pm »
Hi @Petr,

since the latest stable version 2.0 its much easier to do this, see Changelog:

Quote
Functions _MK$ and _CV can now deal with _OFFSET values.

Hence, it's now as easy as:

Code: QB64: [Select]
  1. o%& = 5
  2.  
  3. PRINT "_OFFSET    ="; o%&
  4. PRINT "_INTEGER64 ="; l&&
  5.  

However, if you wanna give your program some backward compatiblity to v1.5 or even older, then you should stay with @SMcNeill 's converter function, as it works in all QB64 versions.
My Projects:   https://qb64forum.alephc.xyz/index.php?topic=809
GuiTools - A graphic UI framework (can do multiple UI forms/windows in one program)
Libraries - ImageProcess, StringBuffers (virt. files), MD5/SHA2-Hash, LZW etc.
Bonus - Blankers, QB64/Notepad++ setup pack

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Thanks Steve for ConvertOffset function
« Reply #3 on: October 16, 2021, 03:37:13 pm »
@RhoSigma

Thank you! I look at it! Perfect work!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Thanks Steve for ConvertOffset function
« Reply #4 on: October 16, 2021, 05:14:54 pm »
        Dim num As _Integer64
        m = _Mem(num)
        _MemPut m, m.OFFSET, value
        OFFSET_to_I64 = num
        _MemFree m


Looking at the above, I can't see why the heck it'd produce false results for you.  Only thing I can think you might try would be to add AS _OFFSET to the end of that memput statement.  I wouldn't think it'd be necessary since value is defined as an offset, but who knows?!!

Looks to me like it should work as is.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Thanks Steve for ConvertOffset function
« Reply #5 on: October 16, 2021, 06:12:39 pm »
Testing the two routines, I can't see a bit of difference in them or how they behave.

Code: QB64: [Select]
  1. Screen _NewImage(1024, 720, 32)
  2. v = 1
  3. For i = 1 To 30
  4.     Print i, v, OFFSET_to_I64(v), ConvertOffset(v)
  5.     v = v * 10
  6.  
  7. Print "Binary Analysis"
  8. v = 1
  9.     If OFFSET_to_I64(v) <> ConvertOffset(v) Then
  10.         Beep
  11.         Print "Numbers mismatch!"
  12.         Print v, OFFSET_to_I64(v), ConvertOffset(v)
  13.         End
  14.     End If
  15.     Locate 33, 1: Print v; "of"; &HFFFFFFFFFFFFFFFF~&&
  16.     v = v * 2
  17.     _Limit 10
  18. Loop Until v = 0 'we get too large for v and it becomes NaN
  19. Print "All numbers match.  "
  20. v = -1
  21.     If OFFSET_to_I64(v) <> ConvertOffset(v) Then
  22.         Beep
  23.         Print "Numbers mismatch!"
  24.         Print v, OFFSET_to_I64(v), ConvertOffset(v)
  25.         End
  26.     End If
  27.     Locate 36, 1: Print v; "of"; &HFFFFFFFFFFFFFFFF&&
  28.     v = v * 2
  29.     _Limit 10
  30. Loop Until v = 0 'we get too large for v and it becomes NaN
  31. Print "All numbers match.  "
  32.  
  33.  
  34.  
  35.  
  36. Function OFFSET_to_I64&& (value As _Offset)
  37.     Dim m As _MEM
  38.     $If 32BIT Then
  39.         DIM num AS LONG
  40.         m = _MEM(num)
  41.         _MEMPUT m,m.offset, value
  42.         Offset_to_i64 = num
  43.         _MEMFREE m
  44.     $Else
  45.         Dim num As _Integer64
  46.         m = _Mem(num)
  47.         _MemPut m, m.OFFSET, value 'As _OFFSET
  48.         OFFSET_to_I64 = num
  49.         _MemFree m
  50.     $End If
  51.  
  52.  
  53. Function ConvertOffset&& (value As _Offset)
  54.     Dim co As _Integer64
  55.     Dim m As _MEM 'Define a memblock
  56.     m = _Mem(value) 'Point it to use value
  57.     $If 64BIT Then
  58.         'On 64 bit OSes, an OFFSET is 8 bytes in size.  We can put it directly into an Integer64
  59.         _MemGet m, m.OFFSET, co&& 'Get the contents of the memblock and put the values there directly into ConvertOffset&&
  60.     $Else
  61.         'However, on 32 bit OSes, an OFFSET is only 4 bytes.  We need to put it into a LONG variable first
  62.         _MEMGET m, m.OFFSET, temp& 'Like this
  63.         co&& = temp& 'And then assign that long value to ConvertOffset&&
  64.     $End If
  65.     _MemFree m 'Free the memblock
  66.     ConvertOffset&& = co&&
  67.  

« Last Edit: October 16, 2021, 06:59:07 pm by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Thanks Steve for ConvertOffset function
« Reply #6 on: October 17, 2021, 04:22:16 pm »
@SMcNeill

I'm still looking for bugs in the source code of my program, when it happened that I called something like S$ = SPACE$ (CovnevertOffset (L.SIZE)) using a conversion function, and if I didn't load the whole MEM block, sometimes this just got stuck. Of course, I tried to take it out of the program and replicate the error outside the entire large source code, I tried to write repeatedly using SPACE$, I suspected that if the LONG upper limit for the size of SPACE$ was exceeded, it would fail, so I tried to write files in smaller pieces and not all at once, there were repeated completely unexpected crashes of the main program, but I never managed to bring it out, separately (if so, it would already be here). So I got a suspicion that I would exceed the upper limits of the SINGLE data type somewhere and that it would cause crashes.

I didn't plan it, but if someone finds it, it will benefit the whole team. Maybe I'm touching an unknown problem somewhere, or I'm just blind and I just can't see it. So now I'm adding a rough, uncommented, deeply unfinished program that does that for you to watch. It doesn't have a complete control or function, I only put it here for the ability to replicate my problems. It's not about RAM (apparently) because, according to Windows Task Manager, I never reached the upper memory area during the test.

So how do you can use it:
Compile, run. Press the S key to bring up the Windows dialog. Choose the format of MP3, for example, or select the file you want. The mouse will show a bar (indicates the length of the music). Press the P key to start playing the sound. Due to an SNDRAW error in stereo produce and a function that is intended for the program in the future, the audio data is written to the field and saved as a WAV file on the disc before playback. The problem is that it will be done 4 times correctly, for example, and then it will collapse like a house of cards. Press Esc once to end playback, press Esc again to exit insert mode. Click in the center of the bar on the screen to put this music in the program (unless you press Esc first). This works. It is allowed to insert the same music repeatedly. Insert another music track by pressing S. Then press P or O. O is for the final mix (it's still mixing very badly, I'm working on it now). According to my tests, the problem should arise in SaveSound16S, but I don't understand how at all. The program has an unlimited length of music, of course this is far from everything I want to add to it, so first write the main engine - and it is currently unreliable for unknown reasons.

Also is here one UNKNOWN problem in version 2.0 only (not crash under 1.5 with this) ------> comment row 791 and uncomment row 795, and also uncomment row 796 with END statement. This show you....... after run PROGRAM STOP WORKING....
EDIT: for this bug you must opening WAV audio file with S key (can be also supported format)

Try replace offset conversion function, it crash again, but not so often.
Code: QB64: [Select]
  1.  
  2. '$include:'opensave.bi'
  3. '$include:'winbox.bi'
  4. _Title "SoundEdit Alfa"
  5. Const MusicStep = 100 'how much pixels use for 1 second of sample sound
  6. Dim Shared DW As Integer, DH As Integer, LaneHeight As Integer
  7. Dim Shared SamplePlay As Long
  8.  
  9. Type Sample
  10.     '   Name AS STRING * 50
  11.     '  Path AS STRING * 200
  12.     Lenght As Single
  13.     Volume As _Unsigned _Byte
  14.     Format As _Unsigned _Byte 'ASC M  nebo ASC S
  15.     Effect As _Byte '
  16.     StartPos As Single
  17.     UsedLenght As Single
  18.     Speed As Integer '
  19.     StartO As Long
  20.     EndO As Long
  21.  
  22. Type SndSamples
  23.     Left As Integer
  24.     Right As Integer '16 bites
  25.  
  26.  
  27. Type Voices
  28.     Von As Integer ' this is for graphic coordinate for inserting samples
  29.     Bis As Integer
  30.  
  31. Dim Shared As Voices LeftIns(1 To 10), RightIns(1 To 10)
  32.  
  33. 'globalni pole vzorku
  34. ReDim Shared Samples(0) As SndSamples
  35.  
  36. 'pomocne pole SAMplu
  37. ReDim Shared SAM(1) As Sample
  38.  
  39. '---------------------------------- deklarace pro grafickou koordinaci -----------------------------
  40. Type Graphic
  41.     TimePos As Long
  42.     Row As Integer
  43.     '    Inf As Sample
  44.     NR As Integer
  45.     GrPos As Long
  46.  
  47. ReDim Shared LG(0) As Graphic 'left channel graphic (samples position in time, samples position in one from 10 voices [ROW], samples infos [inf as SAMPLE]
  48. ReDim Shared RG(0) As Graphic 'right channel                                                             -,,-
  49.  
  50.  
  51. 'kazdym vkladem samplu se konkretni pole navysi
  52.  
  53. '---------------------------------------------------------------------------------------------------
  54.  
  55.  
  56.  
  57.  
  58. Screen _NewImage(DW, DH, 32)
  59.  
  60. test& = BackgroundImage&
  61.  
  62.  
  63. 'On Error GoTo errhnd
  64.  
  65.     _PutImage , test&
  66.  
  67.  
  68.     i$ = InKey$
  69.  
  70.     Select Case UCase$(i$)
  71.         Case "S" '                                                           vyber samplu
  72.             test$ = SelectFile
  73.             If Len(test$) Then
  74.                 _SndStop SamplePlay
  75.                 _SndClose SamplePlay
  76.                 snd = LOADSAMPLE(test$)
  77.                 '  Print "Navratova hodnota funkce LOADSAMPLE je:"; snd   'cislo snd se ulozi do pole zasobniku samplu
  78.             End If
  79.  
  80.         Case "P" '      
  81.             If snd Then '
  82.                 PLAYSAMPLE snd
  83.             End If
  84.  
  85.         Case Chr$(0) + Chr$(75)
  86.             ShiftGridX = ShiftGridX + 10 'Grid to LEFT
  87.             If ShiftGridX > 0 Then ShiftGridX = 0
  88.  
  89.  
  90.         Case Chr$(0) + Chr$(77)
  91.             ShiftGridX = ShiftGridX - 10 'Grid to RIGHT
  92.             If ShiftGridX > 3600 * MusicStep Then ShiftGridX = 3600 * MusicStep
  93.  
  94.  
  95.         Case "4"
  96.             ShiftGridX = ShiftGridX + 1000 'Grid to LEFT
  97.             If ShiftGridX > 0 Then ShiftGridX = 0
  98.  
  99.  
  100.         Case "6"
  101.             ShiftGridX = ShiftGridX - 1000 'Grid to RIGHT
  102.             If ShiftGridX > 3600 * MusicStep Then ShiftGridX = 3600 * MusicStep
  103.  
  104.         Case "O"
  105.             SaveOutput
  106.  
  107.         Case Chr$(27)
  108.             If _SndPlaying(SamplePlay) Then _SndStop SamplePlay: _Delay .1 Else snd = 0
  109.  
  110.     End Select
  111.  
  112.    
  113.     If Position < 0 Then Position = 0
  114.     If Position > MusicStep * 3600 Then Position = MusicStep * 3600 'maximum is hour long record
  115.  
  116.  
  117.  
  118.  
  119.  
  120.     'kresba casove osy
  121.  
  122.  
  123.    
  124.     GridX = ShiftGridX
  125.  
  126.     TimeStart = (-ShiftGridX - 5) / MusicStep
  127.     TimeEnd = (-ShiftGridX / MusicStep) + ((DW - 75) / MusicStep)
  128.  
  129.  
  130.  
  131.  
  132.     Locate 1
  133.     Print "Time start:"; CSng(TimeStart); "Time end:"; CSng(TimeEnd)
  134.  
  135.  
  136.     If GridX > 80 + MusicStep Then
  137.         GridX = 0
  138.         '   GridH = GridH + 1
  139.     End If
  140.     bG = 1
  141.  
  142.     If TimeStart Mod 10 <> 0 Then TimeView = Int(TimeStart + 1) Else TimeView = _Ceil(TimeStart + .06) '1   posledni upravy v tomto radku
  143.     If TimeStart < 0 Then TimeView = 0
  144.     Color Gold
  145.     For GridDraw = GridX To MusicStep + DW Step MusicStep / 10
  146.         bG = bG + 1 'pro kresbu silnych car
  147.         If GridDraw > 75 Then
  148.             Line (GridDraw, DH * .1)-(GridDraw, DH * .453), &H40FFFFFF ' Left channel
  149.             Line (GridDraw, DH * .905)-(GridDraw, DH * .552), &H40FFFFFF ' RIGHT channel
  150.             If bG Mod 10 = 0 Then
  151.                 Line (GridDraw + 1, DH * .09)-(GridDraw - 1, DH * .453), &H40FFFFFF, BF 'LEFT channel
  152.                 Line (GridDraw + 1, DH * .905)-(GridDraw - 1, DH * .540), &H40FFFFFF, BF 'RIGHT channel
  153.                 CenterText$ = LTrim$(Str$(TimeView))
  154.                 CenterText = _PrintWidth(CenterText$) \ 2
  155.  
  156.                 _PrintMode _KeepBackground
  157.                 _PrintString (GridDraw - CenterText, DH * .07), CenterText$ 'left
  158.                 _PrintString (GridDraw - CenterText, DH * .52), CenterText$ 'right
  159.  
  160.                 _PrintString (GridDraw - 20, DH * .055), SecAsTime$(TimeView) 'left
  161.                 _PrintString (GridDraw - 20, DH * .505), SecAsTime$(TimeView) 'right
  162.  
  163.                 _PrintMode _FillBackground
  164.                 TimeView = TimeView + 1
  165.             End If
  166.         End If
  167.     Next
  168.  
  169.  
  170.    
  171.  
  172.     InsertLenght = SAMLEN(snd)
  173.     'Locate 3
  174.     'Print InsertLenght, snd
  175.  
  176.     MX = _MouseX: MY = _MouseY: LMB = _MouseButton(1)
  177.  
  178.     If snd Then Line (MX, MY)-(MX + InsertLenght, MY + 16), &H99FFFF00, BF
  179.     If MX > 80 Then
  180.         SelectedTime = (-ShiftGridX + MX - 80) / MusicStep
  181.         InsertStartTime$ = SecAsTime$(SelectedTime)
  182.         _PrintString (MX + 50, MY + 32), InsertStartTime$
  183.  
  184.         If LMB Then 'akce levym tlacitkem mysi
  185.             If snd Then
  186.                 InsertSam snd, SelectedTime, MY, MX - ShiftGridX
  187.                 'wait for mouse left button release
  188.                 Do Until LMB = 0
  189.                     While _MouseInput: Wend
  190.                     LMB = _MouseButton(1)
  191.                 Loop
  192.  
  193.  
  194.                 'snd = 0 aby bylo mozno stejny nastroj vlozit na vice mist, neanuluji ho po jednom vkladu, ale az pri stisku Esc   nebo pri otevreni noveho samplu
  195.             End If
  196.         End If
  197.  
  198.  
  199.         'InsertSam nema kontrolu toho, jestli nevkladas sampl nekam, kde uz jiny je (ve stejnem hlasu a ve stejnem nebo mensim ci prekryvajicim se rozsahu casu)
  200.  
  201.     End If
  202.     '--------------- predchozi radky resi vklad hudby, nasleduje reseni zobrazeni hudby ----------------------
  203.     ViewSamplesOnScreen ShiftGridX, DW - ShiftGridX
  204.  
  205.  
  206.  
  207.  
  208.  
  209.  
  210.  
  211.  
  212.     _Display
  213.     _Limit 70
  214.  
  215.  
  216. errhnd:
  217. Print "Unexpected error on line "; _ErrorLine; "error code: "; Err
  218.  
  219.  
  220. 'test$ = SelectFile
  221. 'PRINT test$
  222. 'BoxTest = MsgBox("Test okna" + CHR$(0), "Dobrý den" + CHR$(0), 4, 2, 6, 4096)
  223.  
  224.  
  225.  
  226.  
  227. Sub SaveOutput
  228.    
  229.     i = 0
  230.     Do Until i = UBound(LG)
  231.         If maxtimeL < LG(i).TimePos + SAM(LG(i).NR).UsedLenght Then
  232.             maxtimeL = LG(i).TimePos + SAM(LG(i).NR).UsedLenght
  233.             iL = i
  234.         End If
  235.         i = i + 1
  236.     Loop
  237.     i = 0
  238.     Do Until i = UBound(RG)
  239.         If maxtimeR < RG(i).TimePos + SAM(LG(i).NR).UsedLenght Then
  240.             maxtimeR = RG(i).TimePos + SAM(LG(i).NR).UsedLenght
  241.             iR = i
  242.         End If
  243.         i = i + 1
  244.     Loop
  245.     i = 0
  246.     If maxtimeL > maxtimeR Then
  247.         TotalTime = maxtimeL
  248.         uI = iL
  249.     Else
  250.         TotalTime = maxtimeR
  251.         uI = iR
  252.     End If
  253.  
  254.     TotalTime = TotalTime + SAM(uI).UsedLenght
  255.  
  256.     Print "SaveOutput: Celkova spocitana delka audio vystupu je: "; TotalTime
  257.     _Display
  258.     Sleep
  259.  
  260.     'alokace pameti pro vystup
  261.     Dim As _MEM L, R
  262.     L = _MemNew(TotalTime * 44100 * 2) 'integer
  263.     R = _MemNew(TotalTime * 44100 * 2)
  264.  
  265.  
  266.  
  267.     '  LG.NR = cislo samplu
  268.     '  SAM(cislo samplu)...
  269.  
  270.     Dim As Integer CV, ValueOut
  271.     For Left = LBound(LG) To UBound(LG) - 1
  272.         SamNr = LG(Left).NR
  273.         StartBytePosition& = 2 * LG(Left).TimePos * 44100
  274.         EndBytePosition& = 2 * (LG(Left).TimePos + SAM(SamNr).UsedLenght) * 44100
  275.         LM& = StartBytePosition&
  276.         Do Until LM& = EndBytePosition&
  277.             CV = _MemGet(L, L.OFFSET + LM&, Integer)
  278.             If CV Then
  279.                 ValueOut = (CV + Samples(SAM(SamNr).StartO + ReadSam).Left) / 2
  280.             Else
  281.                 ValueOut = Samples(SAM(SamNr).StartO + ReadSam).Left
  282.             End If
  283.  
  284.  
  285.             _MemPut L, L.OFFSET + LM&, ValueOut
  286.             LM& = LM& + 2
  287.             ReadSam = ReadSam + SAM(SamNr).Speed / 100
  288.         Loop
  289.         ReadSam = 0
  290.     Next
  291.  
  292.     For Right = LBound(RG) To UBound(RG) - 1
  293.         SamNr = RG(Right).NR
  294.         StartBytePosition& = 2 * RG(Right).TimePos * 44100
  295.         EndBytePosition& = 2 * (RG(Right).TimePos + SAM(SamNr).UsedLenght) * 44100
  296.         RM& = StartBytePosition&
  297.         Do Until RM& = EndBytePosition&
  298.             CV = _MemGet(L, L.OFFSET + RM&, Integer)
  299.             If CV Then ValueOut = (CV + Samples(SAM(SamNr).StartO + ReadSam).Right * (SAM(SamNr).Volume / 100)) / 2 Else ValueOut = Samples(SAM(SamNr).StartO + ReadSam).Right * (SAM(SamNr).Volume / 100)
  300.             _MemPut R, R.OFFSET + RM&, ValueOut
  301.             RM& = RM& + 2
  302.             ReadSam = ReadSam + SAM(SamNr).Speed / 100
  303.         Loop
  304.         ReadSam = 0
  305.     Next
  306.  
  307.     SAVESOUND16S L, R, "output.wav"
  308.     _SndPlayFile ("output.wav")
  309.     _MemFree L
  310.     _MemFree R
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320. Sub ViewSamplesOnScreen (PixelsStart, PixelsEnd) ' time, time, coordinate - X begin, coordinate - X end
  321.     'nejprve se musi urcit, jestli cas je v rozsahu viditelnosti, cili jestl je LG(i).timepos > TimeSart a soucasne je LG(i).timepos + lg(i).timepos + lg (i).inf.usedlenght < timeend
  322.     'musi spocitat delku samplu v pixelech
  323.     V = 0
  324.  
  325.     Do Until V = UBound(LG)
  326.         'prepocitat casovou pozici na pixely
  327.         CalcGraphicStart = LG(V).GrPos
  328.         CalcGraphicEnd = SAM(LG(V).NR).UsedLenght * MusicStep + LG(V).GrPos
  329.  
  330.         '        If PixelsStart <= CalcGraphicStart And PixelsEnd >= CalcGraphicEnd Or PixelsStart < CalcGraphicStart And PixelsStart > CalcGraphicEnd Then 'pokus o vklady long samplu
  331.         'urcit spravnou polohu Y
  332.         VoiceGraphicYs = LeftIns(LG(V).Row).Von + 3
  333.         VoiceGraphicYe = LeftIns(LG(V).Row).Bis - 3
  334.         'nakreslit znacku
  335.         MarkStart = PixelsStart + CalcGraphicStart
  336.         MarkEnd = PixelsStart + CalcGraphicEnd
  337.  
  338.         If MarkStart < 80 Then MarkStart = 80
  339.         If MarkEnd < 80 Then MarkEnd = 80
  340.         If MarkEnd > DW Then MarkEnd = DW
  341.  
  342.         If MarkEnd - MarkStart Then Line (MarkStart, VoiceGraphicYs)-(MarkEnd, VoiceGraphicYe), &H70FFAA0E, BF
  343.         '       End If
  344.         V = V + 1
  345.     Loop
  346.  
  347.     V = 0
  348.  
  349.     Do Until V = UBound(RG)
  350.         'prepocitat casovou pozici na pixely
  351.         CalcGraphicStart = RG(V).GrPos
  352.         CalcGraphicEnd = SAM(RG(V).NR).UsedLenght * MusicStep + RG(V).GrPos
  353.  
  354.         '        If PixelsStart <= CalcGraphicStart And PixelsEnd >= CalcGraphicEnd Then
  355.         'urcit spravnou polohu Y
  356.         VoiceGraphicYs = RightIns(RG(V).Row).Von + 3
  357.         VoiceGraphicYe = RightIns(RG(V).Row).Bis - 3
  358.         'nakreslit znacku
  359.  
  360.        
  361.         MarkStart = PixelsStart + CalcGraphicStart
  362.         MarkEnd = PixelsStart + CalcGraphicEnd
  363.  
  364.         If MarkStart < 80 Then MarkStart = 80
  365.         If MarkEnd < 80 Then MarkEnd = 80
  366.         If MarkEnd > DW Then MarkEnd = DW
  367.  
  368.         If MarkEnd - MarkStart Then Line (MarkStart, VoiceGraphicYs)-(MarkEnd, VoiceGraphicYe), &H70FFAA0E, BF
  369.  
  370.  
  371.         '       End If
  372.         V = V + 1
  373.     Loop
  374.  
  375.  
  376. Sub InsertSam (SamNr, Time, MousePosY, RelativePosX) ' insert sample to voice/channel (every channel contains 10 voices) - LG array for left channel, RG for right channel
  377.     test = 0
  378.     Do Until test = 10
  379.         test = test + 1
  380.         If MousePosY >= LeftIns(test).Von And MousePosY <= LeftIns(test).Bis Then Voice = 10 + test: GoTo Pass
  381.         If MousePosY >= RightIns(test).Von And MousePosY <= RightIns(test).Bis Then Voice = 30 + test: GoTo Pass
  382.     Loop
  383.     'if mouse is not in correct position, nothing is inserted, so exit sub
  384.     Exit Sub
  385.  
  386.     Pass:
  387.  
  388.  
  389.     Channel = Voice - 10 '1 - 10 = left; 21 - 30 = right
  390.  
  391.     Select Case Channel
  392.         Case 1 TO 10
  393.             Voice = Channel
  394.             '   Print "Levy kanal"
  395.             '  Print "Cislo hlasu: "; Voice 'OK
  396.  
  397.  
  398.  
  399.             LGi = UBound(LG)
  400.             LG(LGi).Row = Voice
  401.             LG(LGi).NR = SamNr
  402.             LG(LGi).TimePos = Time
  403.             LG(LGi).GrPos = RelativePosX
  404.             'pokud jde o stereo zvuk, vlozi se do obou poli:
  405.             If Chr$(SAM(SamNr).Format) = "S" Then 'if is sample in stereo format, insert both audio channels to both arrays
  406.                 RGi = UBound(RG)
  407.                 RG(RGi).Row = Voice
  408.                 RG(RGi).NR = SamNr
  409.                 RG(RGi).TimePos = Time
  410.                 RG(RGi).GrPos = RelativePosX
  411.                 RGi = RGi + 1
  412.                 ReDim _Preserve RG(RGi) As Graphic
  413.             End If
  414.             LGi = LGi + 1
  415.             ReDim _Preserve LG(LGi) As Graphic
  416.  
  417.         Case 21 TO 30
  418.             Voice = Channel - 20
  419.             '    Print "Pravy kanal"
  420.             '   Print "Cislo hlasu: "; Voice 'OK
  421.  
  422.             RGi = UBound(RG)
  423.             RG(RGi).Row = Voice
  424.             RG(RGi).NR = SamNr
  425.             RG(RGi).TimePos = Time
  426.             RG(RGi).GrPos = RelativePosX
  427.             'pokud jde o stereo zvuk, vloz to do obou poli
  428.             If Chr$(SAM(SamNr).Format) = "S" Then 'also: if is sample in stereo, insert both audio channels to both arrays
  429.                 LGi = UBound(LG)
  430.                 LG(LGi).Row = Voice
  431.                 LG(LGi).NR = SamNr
  432.                 LG(LGi).TimePos = Time
  433.                 LG(LGi).GrPos = RelativePosX
  434.                 LGi = LGi + 1
  435.                 ReDim _Preserve LG(LGi) As Graphic
  436.             End If
  437.             RGi = RGi + 1
  438.             ReDim _Preserve RG(RGi) As Graphic
  439.     End Select
  440.  
  441.  
  442.  
  443.  
  444. Function SAMLEN (SamNr) 'Return lane lenght in pixels according to the length of the music
  445.     SAMLEN = (SAM(SamNr).UsedLenght - SAM(SamNr).StartPos) * MusicStep
  446.  
  447. Sub PLAYSAMPLE (samNr) 'jen pro prehrani konkretniho samplu, bez mixovani s ostatnimi        For playing 1 sample without mixing
  448.     If SamplePlay Then _SndPlay SamplePlay: Exit Sub
  449.     '    Print "PLAYSAMPLE spusten..."
  450.     'bude to tak, ze se bleskove udela WAV soubor a ten se pusti pres _sndplayfile
  451.     Dim S As _Float, T As _Float
  452.     Volume = SAM(samNr).Volume / 100
  453.  
  454.     OriginalSize& = SAM(samNr).EndO - SAM(samNr).StartO + 4
  455.     T = 100 / SAM(samNr).Speed 'for music speed options
  456.     T2 = SAM(samNr).Speed / 100 'step for read music data from array definded with DIM
  457.  
  458.     MEMLEN& = T * OriginalSize& * 2
  459.  
  460.     Dim L As _MEM, R As _MEM
  461.     Dim LeftValue As Integer, RightValue As Integer
  462.     Dim I2 As Long
  463.  
  464.     L = _MemNew(MEMLEN&)
  465.     R = _MemNew(MEMLEN&)
  466.     S = 0: I2 = 0
  467.  
  468.     ' "Spustena smycka for S od "; SAM(samNr).StartO; " do"; SAM(samNr).EndO; " krok je"; T2
  469.     For S = SAM(samNr).StartO To SAM(samNr).EndO Step T2
  470.         ' IF samNr > 0 THEN
  471.         ' _SNDRAW (Samples(S).Left / 32768) * Volume, (Samples(S).Right / 32768) * Volume 'ZJISTENO: PRI DRUHEM BEHU SEM JDE PRAZDNA PAMET   L, R
  472.         ' IF TEST = 0 THEN BEEP: TEST = 1
  473.         ' END IF
  474.  
  475.         LeftValue = Samples(S).Left * Volume
  476.         RightValue = Samples(S).Right * Volume
  477.         _MemPut L, L.OFFSET + I2, LeftValue
  478.         _MemPut R, R.OFFSET + I2, RightValue
  479.         I2 = I2 + 2
  480.     Next S
  481.  
  482.     ' Print "Jeden prubeh je uspesne dokoncen - konec PLAYSAMPLE, rizeni predano SaveSound16S!"
  483.  
  484.     SAVESOUND16S L, R, "se.wav"
  485.     ' Print "SNDOPEN..."
  486.  
  487.     SamplePlay = _SndOpen("se.wav")
  488.     ' Print "cislo zvuku udelene SNDOPENem "; SamplePlay
  489.  
  490.     If SamplePlay Then _SndPlay SamplePlay
  491.  
  492.  
  493.  
  494.  
  495.     '
  496.  
  497.     _MemFree L
  498.     _MemFree R
  499.  
  500. Sub SAVESOUND16S (left As _MEM, right As _MEM, file As String) 'MEM blocks contains INTEGER values
  501.     Dim size As _Unsigned Long
  502.     size = OFFSET_to_I64(left.SIZE) / 2
  503.  
  504.     HeaderSize = size
  505.     If HeaderSize Mod 2 > 0 Then
  506.         Do Until HeaderSize Mod 2 = 0
  507.             HeaderSize = HeaderSize - 1
  508.         Loop
  509.     End If
  510.  
  511.  
  512.     Type head16
  513.         chunk As String * 4 '       4 bytes  (RIFF)
  514.         size As Long '              4 bytes  (file size)
  515.         fomat As String * 4 '       4 bytes  (WAVE)
  516.         sub1 As String * 4 '        4 bytes  (fmt )
  517.         subchunksize As Long '      4 bytes  (lo / hi), $00000010 for PCM audio
  518.         format As Integer '         2 bytes  (0001 = standard PCM, 0101 = IBM mu-law, 0102 = IBM a-law, 0103 = IBM AVC ADPCM)
  519.         channels As Integer '       2 bytes  (1 = mono, 2 = stereo)
  520.         rate As Long '              4 bytes  (sample rate, standard is 44100)
  521.         ByteRate As Long '          4 bytes  (= sample rate * number of channels * (bits per channel /8))
  522.         Block As Integer '          2 bytes  (block align = number of channels * bits per sample /8)
  523.         Bits As Integer '           2 bytes  (bits per sample. 8 = 8, 16 = 16)
  524.         subchunk2 As String * 4 '   4 bytes  ("data")  contains begin audio samples
  525.         lenght As Long '            4 bytes  Data block size
  526.     End Type '                     44 bytes  total
  527.     Dim H16 As head16
  528.     ch = FreeFile
  529.  
  530.     H16.chunk = "RIFF"
  531.     H16.size = 44 + size * 4
  532.     H16.fomat = "WAVE"
  533.     H16.sub1 = "fmt "
  534.     H16.subchunksize = 16
  535.     H16.format = 1
  536.     H16.channels = 2
  537.     H16.rate = 44100
  538.     H16.ByteRate = 44100 * 2 * 16 / 8
  539.     H16.Block = 4
  540.     H16.Bits = 16
  541.     H16.subchunk2 = "data"
  542.     H16.lenght = size * 4 'stereo and integer = 2 + 2
  543.     If _FileExists(file$) Then Kill file$
  544.  
  545.     Open file$ For Binary As #ch
  546.     Put #ch, , H16
  547.  
  548.  
  549.     Dim LeftChannel16 As Integer, RightChannel16 As Integer
  550.     Dim Recalc As _MEM
  551.  
  552.  
  553.     'recalculate audiodata to file - byte - values
  554.  
  555.     Recalc = _MemNew(size * 2) 'stereo
  556.  
  557.     Start = 0
  558.     '  Print "SaveSound16S: Spustena smycka FOR"
  559.     empty = 0
  560.     For Start = 0 To size - 4 Step 2
  561.         LeftChannel16 = _MemGet(left, left.OFFSET + Start, Integer)
  562.         RightChannel16 = _MemGet(right, right.OFFSET + Start, Integer)
  563.         If LeftChannel16 = 0 And RightChannel16 = 0 Then empty = empty + 1
  564.  
  565.         _MemPut Recalc, Recalc.OFFSET + S, LeftChannel16
  566.         _MemPut Recalc, Recalc.OFFSET + S + 2, RightChannel16
  567.         S = S + 4
  568.     Next
  569.  
  570.     H16.size = 44 + S
  571.     H16.lenght = S
  572.     Put #ch, 1, H16
  573.  
  574.  
  575.     'write audio data to file
  576.     ' Print "SaveSound16S: Smycka FOR ukoncena, Spusten SPACE$"; empty; S~&
  577.  
  578.     WAVeRAW$ = Space$(S~&)
  579.     _MemGet Recalc, Recalc.OFFSET, WAVeRAW$
  580.     Put #ch, , WAVeRAW$
  581.  
  582.     'erase memory
  583.     _MemFree Recalc
  584.     WAVeRAW$ = ""
  585.     Close #ch
  586.     '   Print "SaveSound16S dokonceno, rizeni predano PLAYSAMPLE"
  587.  
  588.  
  589.  
  590.  
  591.  
  592. Sub SAVESOUND8S (Left As _MEM, Right As _MEM, file As String) ' THIS IS NOT USED YET!
  593.  
  594.     Size = OFFSET_to_I64(Left.SIZE) 'convertion is used for WAV file header, becuse offset value can not be used directly
  595.  
  596.     Type head8
  597.         chunk As String * 4 '       4 bytes  (RIFF)
  598.         size As Long '              4 bytes  (file size)
  599.         fomat As String * 4 '       4 bytes  (WAVE)
  600.         sub1 As String * 4 '        4 bytes  (fmt )
  601.         subchunksize As Long '      4 bytes  (lo / hi), $00000010 for PCM audio
  602.         format As Integer '         2 bytes  (0001 = standard PCM, 0101 = IBM mu-law, 0102 = IBM a-law, 0103 = IBM AVC ADPCM)
  603.         channels As Integer '       2 bytes  (1 = mono, 2 = stereo)
  604.         rate As Long '              4 bytes  (sample rate, standard is 44100)
  605.         ByteRate As Long '          4 bytes  (= sample rate * number of channels * (bits per channel /8))
  606.         Block As Integer '          2 bytes  (block align = number of channels * bits per sample /8)
  607.         Bits As Integer '           2 bytes  (bits per sample. 8 = 8, 16 = 16)
  608.         subchunk2 As String * 4 '   4 bytes  ("data")  contains begin audio samples
  609.         lenght As Long '            4 bytes  Data block size
  610.     End Type '                     44 bytes  total
  611.     Dim H8 As head8
  612.     ch = FreeFile
  613.  
  614.     H8.chunk = "RIFF"
  615.     H8.size = 44 + Size / 2
  616.  
  617.     H8.fomat = "WAVE"
  618.     H8.sub1 = "fmt "
  619.     H8.subchunksize = 16
  620.     H8.format = 1
  621.     H8.channels = 2
  622.     H8.rate = 44100
  623.     H8.ByteRate = 44100 * 2 * 8 / 8
  624.     H8.Block = 2
  625.     H8.Bits = 8
  626.     H8.subchunk2 = "data"
  627.     H8.lenght = Size / 2
  628.     If _FileExists(file$) Then Kill file$
  629.  
  630.     Open file$ For Binary As #ch
  631.     Put #ch, , H8
  632.  
  633.     Dim LeftChannel8 As _Byte, RightChannel8 As _Byte, RawLeft As Single, RawRight As Single
  634.     Dim Recalc As _MEM, size As _Offset
  635.  
  636.     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
  637.  
  638.     'recalculate audiodata to file - byte - values
  639.  
  640.     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
  641.  
  642.     start& = 0: LRO& = 0
  643.     Do Until start& = Left.SIZE
  644.         RawLeft = _MemGet(Left, Left.OFFSET + start&, Single)
  645.         RawRight = _MemGet(Right, Right.OFFSET + start&, Single)
  646.  
  647.         LeftChannel8 = 128 - RawLeft * 128
  648.         RightChannel8 = 128 - RawRight * 128
  649.  
  650.         _MemPut Recalc, Recalc.OFFSET + s&, LeftChannel8
  651.         _MemPut Recalc, Recalc.OFFSET + s& + 1, RightChannel8
  652.         s& = s& + 2
  653.         start& = start& + 4
  654.     Loop
  655.  
  656.     'write audio data to file
  657.  
  658.     WAVeRAW$ = Space$(s&)
  659.     _MemGet Recalc, Recalc.OFFSET, WAVeRAW$
  660.     Put #ch, , WAVeRAW$
  661.  
  662.     'erase memory
  663.     _MemFree Recalc
  664.     WAVeRAW$ = ""
  665.     Close ch
  666.  
  667. Function TestWaveFormat (file As String, Left As _MEM, Right As _MEM, Channels, LenghtOther) '          test if WAV is supported 16 bit type or not (if is wav loaded using key S)
  668.  
  669.     Type head
  670.         chunk As String * 4 '       4 bytes  (RIFF)
  671.         size As Long '              4 bytes  (file size)
  672.         fomat As String * 4 '       4 bytes  (WAVE)
  673.         sub1 As String * 4 '        4 bytes  (fmt )
  674.         subchunksize As Long '      4 bytes  (lo / hi), $00000010 for PCM audio
  675.         format As Integer '         2 bytes  (0001 = standard PCM, 0101 = IBM mu-law, 0102 = IBM a-law, 0103 = IBM AVC ADPCM)
  676.         channels As Integer '       2 bytes  (1 = mono, 2 = stereo)
  677.         rate As Long '              4 bytes  (sample rate, standard is 44100)
  678.         ByteRate As Long '          4 bytes  (= sample rate * number of channels * (bits per channel /8))
  679.         Block As Integer '          2 bytes  (block align = number of channels * bits per sample /8)
  680.         Bits As Integer '           2 bytes  (bits per sample. 8 = 8, 16 = 16)
  681.         subchunk2 As String * 4 '   4 bytes  ("data")  contains begin audio samples
  682.         lenght As Long '            4 bytes  Data block size
  683.     End Type '                     44 bytes  total
  684.     Dim H As head
  685.     ff = FreeFile
  686.     Open file For Binary As ff
  687.     Get ff, 1, H
  688.     TestWaveFormat = H.Bits
  689.     Channels = H.channels
  690.     LenghtOther = H.lenght / (H.Bits / 8) / H.channels / H.rate 'without (   ) generate message Program stop working.... - not in 1.5
  691.     '
  692.  
  693.     ' error:
  694.     'LenghtOther = H.lenght \ (H.Bits \ 8) \ H.channels / H.rate
  695.     'End
  696.  
  697.     '    Print "LenghtOther:"; LenghtOther ' ok
  698.  
  699.     'if H.Bits is not 16, convert it!
  700.     Select Case H.Bits
  701.         Case 24 'RhoSigma Help ----> thanks RhoSigma for help with this!
  702.             '   Print "24 bit vaweform decoder:"
  703.             '   Print H.channels
  704.  
  705.             If H.channels = 1 Then multipl = 2 Else multipl = 1
  706.             Left = _MemNew((H.lenght \ 3) * multipl)
  707.             Right = _MemNew(H.lenght \ 3)
  708.  
  709.             f$ = Space$(H.lenght)
  710.             Get #ff, , f$
  711.             Close ff
  712.             Dim As Integer LFT, RGH
  713.             index& = 0
  714.             If H.channels = 2 Then SO = 6 Else SO = 3
  715.  
  716.             For samp& = 0 To (Len(f$) / SO) - 1 'lenght / block align - 1
  717.                 Ls& = 0: Rs& = 0 'clear samples
  718.                 For i% = 3 To 1 Step -1
  719.                     'loop trough little endian file data to build samples
  720.                     Ls& = (Ls& * 256) + Asc(f$, (samp& * SO) + i%) 'shift current value 8 bits left and add next byte
  721.                     If H.channels = 2 Then Rs& = (Rs& * 256) + Asc(f$, (samp& * 6) + i% + 3)
  722.                 Next i%
  723.                 'if MSB (bit 23) is set (negative sample) then sign extend to LONG
  724.                 If (Ls& And &H800000) Then Ls& = (Ls& Or &HFF000000)
  725.                 If H.channels = 2 Then
  726.                     If (Rs& And &H800000) Then Rs& = (Rs& Or &HFF000000)
  727.                 End If
  728.                 'play normalized samples in range -1.0 to +1.0
  729.                 LFT = ((Ls& / 8388608#) * 32767)
  730.                 If H.channels = 2 Then RGH = ((Rs& / 8388608#) * 32767)
  731.                 _MemPut Left, Left.OFFSET + index&, LFT
  732.                 If H.channels = 2 Then _MemPut Right, Right.OFFSET + index&, RGH
  733.                 index& = index& + 2
  734.             Next samp&
  735.  
  736.         Case 8, 32
  737.             Beep
  738.             Print "8 or 32 bit wavefom not supported yet!"
  739.             _Display
  740.             Sleep
  741.             System
  742.  
  743.  
  744.  
  745.  
  746.     End Select
  747.  
  748.  
  749. Function LOADSAMPLE (path As String) '                                            Function load music file and add music data to arrays Samples and also add one record to array SAM and return SAM index
  750.     If _FileExists(path) Then
  751.         Dim L As _MEM, R As _MEM
  752.         If UCase$(Right$(path, 3)) = "WAV" Then FileFormat = TestWaveFormat(path, L, R, Chann, LenghtOther) Else FileFormat = 16: Chann = 2 'MP3, OGG = 16, if format is not 16 bit, convert and load it to L, R as INTEGERs (16bit)
  753.  
  754.         If FileFormat = 16 Then 'wav is 16 bit (supported with _SndOpen)
  755.             Dim sndswp As Long
  756.             sndswp& = _SndOpen(path$)
  757.             L = _MemSound(sndswp, 1)
  758.             R = _MemSound(sndswp, 2)
  759.         End If
  760.  
  761.         SamplePlay = 0 'predchozi sampl se anuluje
  762.         U = UBound(SAM)
  763.  
  764.  
  765.         StartOffset& = UBound(Samples) + 1
  766.         EndOffset& = StartOffset& + OFFSET_to_I64(L.SIZE) 'ok!
  767.  
  768.         If R.SIZE > 0 Then SAM(U).Format = Asc("S") Else SAM(U).Format = Asc("M")
  769.         If Chann = 1 Then SAM(U).Format = Asc("M")
  770.         SAM(U).StartO = StartOffset&
  771.         SAM(U).EndO = EndOffset&
  772.         SAM(U).Lenght = _SndLen(sndswp)
  773.         If FileFormat = 24 Then SAM(U).Lenght = LenghtOther
  774.         SAM(U).Volume = 100 '                                                  sound volume in percentage
  775.         SAM(U).Speed = 70 '                                                    sound speed in percentage (works)
  776.         SAM(U).Effect = 0
  777.         SAM(U).StartPos = 0 '                                                  default: play sample from begin
  778.         SAM(U).UsedLenght = SAM(U).Lenght '                                    default: play whole sample (full lenght)
  779.         '    SAM(U).Path = path '                                                   just for info, not sure if this will be used or not
  780.         '   SAM(U).Name = _TRIM$(MID$(path, _INSTRREV(1, path, CHR$(92)))) '       just for info, not sure if this will be used or not
  781.  
  782.         ReDim _Preserve SAM(U + 1) As Sample
  783.  
  784.         ReDim _Preserve Samples(EndOffset&) As SndSamples
  785.  
  786.         D& = StartOffset&
  787.         Done& = 0
  788.         Dim LSPK As Integer, RSPK As Integer
  789.  
  790.         Do Until Done& = L.SIZE
  791.             LSPK = _MemGet(L, L.OFFSET + Done&, Integer)
  792.             Samples(D&).Left = LSPK
  793.  
  794.             '            IF R.SIZE > 0 THEN
  795.             If Chann > 1 Then
  796.                 RSPK = _MemGet(R, R.OFFSET + Done&, Integer)
  797.                 Samples(D&).Right = RSPK
  798.             End If
  799.             '           ELSE
  800.             '          Samples(D&).Right = 0
  801.             '         END IF
  802.             Done& = Done& + 2
  803.             D& = D& + 1
  804.         Loop
  805.         LOADSAMPLE = U
  806.  
  807.     Else
  808.         Print "Error. Path or file"; path$; "not found."
  809.         _Display
  810.         Sleep
  811.     End If
  812.  
  813.     _SndClose sndswp&
  814.     _MemFree L
  815.     _MemFree R
  816.  
  817.  
  818.  
  819.  
  820. Function OFFSET_to_I64&& (value As _Offset) '                                                                                My conversion function
  821.     Dim m As _MEM
  822.     $If 32BIT Then
  823.         DIM num AS LONG
  824.         m = _MEM(num)
  825.         _MEMPUT m,m.offset, value
  826.         Offset_to_i64 = num
  827.         _MEMFREE m
  828.     $Else
  829.         Dim num As _Integer64
  830.         m = _Mem(num)
  831.         _MemPut m, m.OFFSET, value
  832.         OFFSET_to_I64 = num
  833.         _MemFree m
  834.     $End If
  835.  
  836.  
  837.  
  838. Function BackgroundImage& '                                                                                                     Create Background image and fill arrays RightIns and LeftIns with Lane coordinates
  839.     oldDest = _Dest
  840.     sw& = _NewImage(DW, DH, 32)
  841.     _Dest sw&
  842.     Cls , &HFFAAAAFF
  843.     font = _LoadFont("calibrii.ttf", 24, "BOLD")
  844.     _Font font, sw&
  845.  
  846.     'pruhu bude 10, mezi levou a pravou stopou bude cca 10 procent mista
  847.  
  848.     LaneHeight = (DH - .3 * DH) / 20
  849.  
  850.     For LeftChannelLanes = DH * .1 To DH * .1 + 9 * LaneHeight Step LaneHeight
  851.         i = i + 1
  852.         Line (0, LeftChannelLanes)-(DW, LeftChannelLanes + LaneHeight), _RGBA32(25, 25, 200, 180), BF
  853.         Line (0, LeftChannelLanes)-(DW, LeftChannelLanes + LaneHeight), _RGBA32(25, 25, 25, 25), B
  854.         _PrintString (10, LeftChannelLanes + LaneHeight / 2 - 6), Str$(i)
  855.         LeftIns(i).Von = LeftChannelLanes + 5
  856.         LeftIns(i).Bis = LeftChannelLanes + LaneHeight - 5
  857.     Next
  858.     i = 0
  859.     For RightChannelLanes = LeftChannelLanes + DH * .1 To LeftChannelLanes + DH * .1 + 9 * LaneHeight Step LaneHeight
  860.         i = i + 1
  861.         Line (0, RightChannelLanes)-(DW, RightChannelLanes + LaneHeight), _RGBA32(25, 25, 200, 180), BF
  862.         Line (0, RightChannelLanes)-(DW, RightChannelLanes + LaneHeight), _RGBA32(25, 25, 25, 25), B
  863.         _PrintString (10, RightChannelLanes + LaneHeight / 2 - 6), Str$(i)
  864.         RightIns(i).Von = RightChannelLanes + 5
  865.         RightIns(i).Bis = RightChannelLanes + LaneHeight - 5
  866.     Next
  867.     Color _RGB32(50)
  868.     _PrintString (10, DH * .1 - 24), "LEFT"
  869.     _PrintString (10, LeftChannelLanes + DH * .1 - 24), "RIGHT"
  870.     For S = 0 To 1
  871.         Line (S + 10 + _PrintWidth("RIGHT") + 5, DH * .1 - 24)-(S + 10 + _PrintWidth("RIGHT") + 5, LeftChannelLanes), _RGBA32(25, 25, 25, 25)
  872.         Line (S + 10 + _PrintWidth("RIGHT") + 5, LeftChannelLanes + DH * .1 - 24)-(S + 10 + _PrintWidth("RIGHT") + 5, RightChannelLanes), _RGBA32(25, 25, 25, 25)
  873.     Next
  874.     _Dest oldDest
  875.     '    PRINT LaneHeight
  876.     BackgroundImage& = sw&
  877.  
  878.  
  879.  
  880.  
  881.  
  882. Function SelectFile$ 'for browse and select audio file (audio sources)                                                        WINBOX piece
  883.     Dim hWnd As _Integer64
  884.     $If 64BIT Then
  885.         hWnd = _WindowHandle 'FindWindow(0, "Open and Save Dialog demo" + CHR$(0)) 'get window handle using _TITLE string
  886.     $Else
  887.         hWnd&& = FindWindow(0, "FOCdemo" + CHR$(0)) 'get window handle using _TITLE string
  888.     $End If
  889.  
  890.     Filter$ = "WAV files (*.WAV)|*.WAV|MP3 files (*.MP3)|*.MP3|OGG files (*.OGG)|*.OGG|"
  891.     Flags& = OFN_FILEMUSTEXIST + OFN_NOCHANGEDIR + OFN_READONLY '    add flag constants here
  892.  
  893.     OFile$ = GetOpenFileName$("Select source audio file", ".\", Filter$, 1, Flags&, hWnd&&)
  894.  
  895.     If OFile$ = "" Then
  896.         Exit Function 'return nothing
  897.     Else
  898.         SelectFile$ = OFile$
  899.         'IF (Flags& AND OFN_READONLY) THEN PRINT "Read-only checkbox checked." 'read-only value in return
  900.     End If
  901.  
  902. Function SecAsTime$ (value) '                                                                                                 Function convert seconds to time format as 00:00:00
  903.     '75 = 01:15
  904.  
  905.     m2 = Int(value / 60)
  906.     sec = Int(value - 60 * m2)
  907.     set = CSng((value - 60 * m2) - sec)
  908.     set = Int(set * 100)
  909.     m2$ = LTrim$(Str$(m2))
  910.     sec$ = LTrim$(Str$(sec))
  911.     set$ = LTrim$(Str$(set))
  912.     If Len(m2$) = 1 Then m2$ = "0" + m2$
  913.     If Len(m2$) = 0 Then m2$ = "00"
  914.     If Len(sec$) = 1 Then sec$ = "0" + sec$
  915.     If Len(set$) = 1 Then set$ = "0" + set$
  916.     SecAsTime$ = m2$ + ":" + sec$ + ":" + set$
  917.  
  918.  
  919.  
  920. '$include:'opensave.bm'
  921. '$include:'winbox.bm'
  922.  


« Last Edit: October 19, 2021, 11:30:15 am by Petr »

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Thanks Steve for ConvertOffset function
« Reply #7 on: October 18, 2021, 12:54:05 pm »
I know not the reason for the QB64 jam due to division (see the description above), the reason for the jam due to playback is probably due to third-party software. I was able to write a short program that use a corrupted WAV file and reliably crashes the entire QB64 program:

Code: QB64: [Select]
  1. s = _SndOpen("se-test-output.wav")
  2.  

  [ You are not allowed to view this attachment ]  
Now I'm looking to see if there can be some internal memory and therefore is need to change the name of the file being opened and not opening just one file name.
« Last Edit: October 18, 2021, 01:03:41 pm by Petr »

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Thanks Steve for ConvertOffset function
« Reply #8 on: October 18, 2021, 02:56:32 pm »
So. Problem solved. This error do sure SPACE$ (not own SPACE$) but combination with _MEMGET. All _MEMGETs deleted, all rewrited, returned to old good DIMs and now is none problem. To file is content writed as PUT #ch, ,Sound()  so none SPACE$ is need. I am testing new solution three hours without one crash. Thanks for your interest. (1 person has interest due to downloads zip file, so it is really big interest and motivation)
« Last Edit: October 18, 2021, 03:31:41 pm by Petr »

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Thanks Steve for ConvertOffset function
« Reply #9 on: October 18, 2021, 03:20:41 pm »
And how the hell to actually write the _MEM field directly to a binary file? If I have a pointer and I enter PUT CH, pointer    so it will write about 100 bytes (or less) of something but not the contents of memory. Is there a direct command, or has SPACE$ been relied on so far? I'm annoying, aren't I? You will have to get used to it. :)
I want to create, and this problems stuck me for a week! Do you know how many unfinished programs I have been able to write down so far? :) Thousands.... :)

Finally, practical advice. The solution wanted two beers. Don't take me too seriously, there were three beers. Cheers! I am sooo happy, that it now works correct!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile