QB64 Phoenix Edition v3.8.0 Released!
#51
Quote:@grymmjack - I loved VB6 back in the day. I made some really fun stuff with it.

Did you see InformPE? Check it out! @a740g and @fellipe (I'm sorry I don't know if he's a user here, and I have no desire to look for the name because: lazy). made it.
I tried InForm last year but something went wrong; it all hung up after a short time. Something got in the way. I then reinstalled QB64 without InForm.
But, it's a great job. I haven't tried QBJS yet. I am are no longer as not quite as adventurous as I used to be. It is really just a hobby now to get my mind off things.

Do you know this page here - A really good (old)site?: Fravia Searchlores

Unfortunately: Fravia - R.I.P.

I did not know Cracked. Mad Magazine was also here, but I never read it. But I read this one (I found it in a library back then). Can't find the link right now.

Freak Brothers.

[Image: 04.jpg]
Reply
#52
The old Fravia, ca. 2001. Three examples:

[Image: Fravias-Lores-0001.jpg]

[Image: Fravias-Lores-0002.jpg]

[Image: Fravias-Lores-0003.jpg]
Reply
#53
(06-17-2023, 03:12 PM)doppler Wrote:
(06-17-2023, 02:09 PM)grymmjack Wrote: I'm super excited about this stuff!
Thanks for the sound demo. It's giving me some ideas for revisiting old sound play code I wrote (in programs).
NP sir. It's a lot of fun to see what we can make.

I really love those old PC speaker sound effects. From the likes of Duke Nukem 1, Commander Keen, etc.

Pretty awesome what they were able to achieve you know? Just square waves, frequency, duration. Nothing more.

grymmjack (gj!)
GitHubYouTube | Soundcloud | 16colo.rs
Reply
#54
Music 
https://github.com/zserge/1bitr

Had a lot of fun with this for at least a week with a Lua script I wrote doing 20-minute muzak LOL. Even recorded it to wave and imported it into Audacity creating a stereo pair and applied reverb. Was very bored that day.

Code: (Select All)
-- by mnrvovrfc, verified 17-Jun-2023

function table_create(atable)
  function local_table_copy(t)
    local tret

    function local_copy(t)
      local tret = { }
      for i = 1, #t do
        tret[i] = t[i]
      end
      for k, v in pairs(t) do
        if type(v) == "table" then
          tret[k] = local_copy(v)
        elseif type(k) ~= "number" then
          tret[k] = v
        end
      end
      return tret
    end

    tret = local_copy(t)
    return tret
  end

  local tret = {
    insert = function (s, ...)
               local rest = { ... }
               if rest == nil or #rest == 0 then return end
               local lrest = #rest
               for i = 1, lrest do
                 table.insert(s, rest[i])
               end
             end,
    first =  function (s, t)
               if t == nil then return end
               table.insert(s, 1, t)
             end,
    enter =  function (s, t)
               if type(t) ~= "table" or #t == 0 then return end
               local ts = local_table_copy(t)
               table.insert(s, ts)
             end,
    concat = function (s, delim, pfrom, pto)
               return table.concat(s, delim, pfrom, pto)
             end,
    copy =   function (s, ts, append)
               if type(ts) ~= "table" then return end
               if next(ts) == nil then return end
               if append == nil then s:delete() end
               local n = #ts
               for i = 1, n do
                 table.insert(s, ts[i])
               end
             end,
    remove = function (s, spos)
               table.remove(s, spos)
             end,
    delete = function (s)
               local n = #s
               while n > 0 do
                 table.remove(s)
                 n = n - 1
               end
             end,
    clear  = function (s)
               s:delete()
             end,
    is_empty = function (s)
                -- not a good way, but the alternative is to search all elements for one with numeric index
                -- the assumption is that if table_create() is used to create a table then
                --   "insert" method would be used to add elements, like an array in BASIC
                return (#s == 0)
             end,
    find =   function (s, aval)
               if aval == nil then return nil end
               if type(aval) ~= "number" and type(aval) ~= "string" then return nil end
               if type(aval) == "number" then aval = tostring(aval) end
               local laval = string.lower(aval)
               local akey, ve
               for kk, vv in pairs(s) do
                 if type(vv) == "number" then ve = tostring(vv) end
                 if type(vv) == "string" then ve = string.lower(vv) end
                 if ve == laval then
                   akey = kk
                   break
                 end
               end
               return akey
             end
  }
  if type(atable) == "table" and next(atable) ~= nil then
    local t = tret
    tret = local_table_copy(atable)
    if not tret.insert then
      tret.insert = t.insert
      tret.clear = t.clear
      tret.concat = t.concat
      tret.copy = t.copy
      tret.delete = t.delete
      tret.enter = t.enter
      tret.find = t.find
      tret.first = t.first
      tret.is_empty = t.is_empty
      tret.remove = t.remove
    end
  end
  return tret
end

function sformat(aformat, arg1, ...)
  if arg1 == nil then
    return aformat
  end
  return string.format(aformat, arg1, ...)
end

function ran(a, b)
  if type(a) ~= "number" then return nil end
  if math.floor(a) == math.floor(b) then return a end
  if a < 0 and b < 0 then
    a = a * -1
    b = b * -1
    if a > b then a, b = b, a end
    return math.random(a, b) * -1
  end
  if a > b then a, b = b, a end
  if a < 0 or b < 0 then
    local x = a * -1
    if b < 0 then x = b * -1 end
    return math.random(a + x, b + x) - x
  end
  return math.random(a, b)
end

function choicet(tbl)
  if type(tbl) ~= "table" then
    return ""
  end
  local x
  local numele = #tbl
  if numele == 0 then return "" end
  if numele == 1 then return tbl[1] end
  repeat
    x = math.random(1, numele)
  until x ~= choicetprev
  choicetprev = x
  return tbl[x]
end

function findstr(txt, lookfor)
  return string.find(txt, lookfor, 1, true)
end


-- main program

tn = table_create()
tc = { "C-", "C#", "D-", "D#", "E-", "F-", "F#", "G-", "G#", "A-", "A#", "B-" }

for j = 3, 7 do
    for i = 1, 12 do
        tn:insert(sformat("%s%d", tc[i], j))
    end
end
tc = nil

nprog = {
    { 3, 4, 3, 4 },
    { 3, 4, 3, 5 },
    { 3, 4, 5, 6 },
    { 3, 5, 5, 6 },
    { 5, 6, 5, 7 },
    { 5, 5, 5, 7 },
    { 4, 5, 5, 5 },
    { 4, 5, 5, 7 },
    { 4, 7, 5, 5 },
    { 4, 7, 5, 7 },
    { 3, 7, 5, 5 },
    { 3, 7, 5, 7 },
    { 3, 7, 7, 6 },
    { 3, 7, 7, 7 },
    { 4, 7, 7, 6 },
    { 4, 7, 5, 5 },
    { 4, 5, 7, 7 },
    { 5, 5, 7, 7 },
    { 6, 7, 7, 7 },
    { 6, 5, 5, 5 },
    { 6, 3, 7, 5 },
    { 4, 7, 3, 5 },
    { 3, 7, 4, 5 },
    { 7, 7, 7, 7 }
}
lnprog = #nprog

popsong = {
    { 4, 4, 2, 4, 4, 2, 2, 2, 4, 4, 2, 2, 2, 4, 4, 2, 4, 4, 2, 2, 2, 1 },
    { 4, 4, 2, 4, 4, 2, 2, 2, 8, 8, 4, 2, 2, 2, 4, 4, 2, 4, 8, 8, 2, 2, 2, 1 },
    { 4, 4, 8, 8, 8, 8, 4, 4, 2, 8, 8, 8, 8, 2, 8, 8, 4, 2, 8, 8, 8, 8, 2, 4, 4, 2, 8, 8, 4, 8, 8, 8, 8, 2, 2, 1 },
    { 2, 8, 8, 2, 4, 8, 8, 8, 8, 2, 4, 2, 4, 8, 8, 2, 8, 8, 8, 8, 2, 4, 4, 4, 8, 8, 8, 8, 4, 2, 4, 8, 8, 8, 8, 1 },
    { 4, 4, 2, 8, 8, 8, 8, 4, 2, 2, 8, 8, 8, 1 },
    { 4, 2, 4, 2, 2, 8, 8, 8, 8, 2, 2 },
    { 2, 8, 8, 2, 4, 2, 2, 2, 8, 8, 2, 4, 2, 4, 4 },
    { 4, 2, 4, 8, 8, 8, 8, 4, 2, 2, 2 },
    { 8, 8, 8, 8, 2, 8, 8, 8, 8, 4, 4, 4, 4, 4 },
    { 8, 8, 2, 8, 8, 8, 8, 2, 8, 8, 4, 4, 4, 4 },
    { 2, 8, 8, 2, 4, 2, 2, 2, 8, 8, 2, 4, 2, 8, 3 },
    { 8, 8, 2, 8, 8, 4, 2, 8, 8, 8, 8, 4, 8, 3 },
    { 0 }
}
lpopsong = #popsong

popline = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 6 }
raise = { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2 }

for o = 10, 59 do
repeat
    goahead = true
    u = ran(64, 125) * 2
    t = table_create{ u }
    for i = 1, 3 do
        t:insert(t[i] / 2)
    end
    for i = 1, #t do
        sg = tostring(t[i])
        if findstr(sg, '.') then
            if not findstr(sg, ".0") then
                -- print("Warning: dividing the note length doesn't produce a whole value.")
                goahead = false
            end
        end
    end
until goahead

notelen = { t[1], t[2], 0, t[3], 0, 0, 0, t[4] }
t = nil
notelen[3] = notelen[4] + notelen[8]
-- notelen[6] = notelen[8] + math.floor(notelen[8] / 2)

noat, nute = table_create(), table_create()
u = ran(1, 18)
uu = u
m = ran(3, 7)
t = choicet(nprog)
for i = 1, #t do
    noat:insert(u)
    if i == m then noat:insert(0) end
    u = u + t[i]
end
noat:insert(u)
u = uu
m = ran(3, 7)
t = choicet(nprog)
for i = 1, #t do
    nute:insert(u)
    if i == m then nute:insert(0) end
    u = u + t[i]
end
nute:insert(u)

fo = io.open(sformat(os.getenv("HOME") .. "/Documents/z1bitr/musak%02d", o - 9), "w")
if fo then fo:write("; 0\n") end
song = choicet(popsong)
if song[1] == 0 then
    local t = { 4, 4, 8, 8, 2, 8, 8, 4, 4, 2, 8, 8, 8, 8, 2, 8, 8, 4, 2, 8, 8, 8, 8, 2, 4, 4, 2, 8, 8, 4, 8, 8, 8, 8, 2, 1 }
    local l = #t
    local w = ran(1, l)
    local x = w - 1
    local r = 0
    local g = ran(2, 4)
    local c = 1
    local d
    song = table_create()
    repeat
        if t[w] == 2 then
            r = r + 1
            if r == g then
                song:insert(3, 8)
            else
                song:insert(t[w])
            end
        else
            song:insert(t[w])
        end
        w = w + 1
        if w > l then break end
        c = c + 1
    until c > l
    if c <= l then
        if x == 0 then
            print("SOMETHING IS WRONG!")
            os.exit()
        end
        if ran(1, 2) == 1 then
            w = x
            d = -1
        else
            w = 1
            d = 1
        end
        repeat
            if t[w] == 2 then
                r = r + 1
                if r == g then
                    song:insert(3, 8)
                else
                    song:insert(t[w])
                end
            else
                song:insert(t[w])
            end
            w = w + d
            c = c + 1
        until c > l
    end
end
lsong = #song
pass =  math.ceil(math.sqrt(o))
y = ran(1, pass)
for j = 1, pass do
    kount = 1
    newpopline = table_create()
    for i = 1, lsong do
        newpopline:insert(choicet(popline))
    end
    repeat
        u = song[kount]
        -- restrict the pause to the two shortest note lengths
        trig = newpopline[kount]
        if j == y then
            if nute[trig] then
                if u < 4 and nute[trig] == 0 then
                    trig = 1
                end
            else
                trig = 1
            end
        else
            if noat[trig] then
                if u < 4 and noat[trig] == 0 then
                    trig = 1
                end
            else
                trig = 1
            end
        end
        -- the lowest two notes in the sequence never vary
        if (j == y and trig > 2) then
            w = choicet(raise)
            if w == -1 then w = 3 end
        elseif (trig > 3) or (trig == 3 and ran(1, 3) == 1) then
            w = choicet(raise)
        else
            w = 0
        end
        if j == y then
            if nute[trig] == 0 then
                -- out-of-range on purpose so it's later considered a pause
                v = 1e+6
            else
                v = nute[trig] + w
            end
        else
            if noat[trig] == 0 then
                v = 1e+6
            else
                v = noat[trig] + w
            end
        end
        if v > #tn then
            st = "---"
        else
            st = tn[v]
        end
        print(sformat("%s%c%02x", st, 32, notelen[u]))
        if fo then
            fo:write(sformat("%s%c%02x\n", st, 32, notelen[u]))
            fo:write(sformat("%s%c%02x\n", st, 32, notelen[u]))
        end
        kount = kount + 1
    until kount > lsong
end
if fo then fo:close() end
print("===")
end  -- for o

ROFL doesn't sound enough like Color Computer playing through a budget television. It had to be the Color Computer 2 because the COCO3 did have "PLAY" which supported volume but could play one voice at a time with square wave.

This is an early version of the script I made, ended up making another one which created sets of three for one song, for left, center and right channels for stereo music. This script presented here requires Lua v5.4 or later. The line with "io.open()" statement could be changed easily to something that makes sense on Windows ("USERPROFILE" environment variable instead of "HOME"). Make sure "1bitr" is installed, and "z1bitr" directory (which is what I called the installation directory) exists inside "Documents" of your regular user's account before running this script.

Then feed one of the text files to the program like this:

Code: (Select All)
$ ./1bitr < musak01

EDIT: Sorry for the lack of indentation, it seems this forum really wants CHR$(9) characters for it, it sucks.
Reply
#55
Here's that same Lua script as attachment so you could enjoy the indentation.

.zip   mnrvovrfc-noater-lua.zip (Size: 2.69 KB / Downloads: 62)
Reply
#56
I'm sorry for the off-topic (and wrong focused programming language). One concept that is not employed, but that I'm thinking about now is keeping track of song "snippets" into arrays such as:

Code: (Select All)
songsnippet(1, 1) = "L8O4AO5C#"
songsnippet(1, 2) = "L4O3A"

songsnippet(2, 1) = "L16O4AFL8O5C#"
songsnippet(2, 2) = "L8O3FC#"

songsnippet(3, 1) = "L16O4FL8AL16O5C#"
songsnippet(3, 2) = "L4O3F"

and send them together for two-channel sound. (I purposely used PLAY strings expected by the Color Computer 3 in this example.) Also because I'm not very good with traditional musical concepts, especially scales I made a simple process in which a "lowest" note is selected, then four or five other notes are created from an array like this:

Code: (Select All)
scale(1) = 4
scale(2) = 5
scale(3) = 3
scale(4) = 4
scale(5) = 3
basenote = 36: 'two octaves below "middle C"
notes(1) = basenote
for i = 1 to 5
    basenote = basenote + scale(i)
    notes(i + 1) = basenote
next

Then the musak is generated only selecting notes from "notes()" array as indicated in the above example. (In QB64 use "N" command for PLAY.) For each song, of course, the "scale()" array and "basenote" would be initialized differently. However, the Lua script only does one channel at a time. The "1bitr" has a multi-channel mode but I'm unwilling to study it. LOL click drums, I want something better than that after hearing enough chiptunes. Smile
Reply
#57
Quote:I'm sorry for the off-topic (and wrong focused programming language). One concept that is not employed, but that I'm thinking about now is keeping track of song "snippets" into arrays such as:

@mnrvovrfc I am sorry too, wading through all this off topic stuff.

Start a thread! then no one has to be sorry Smile
b = b + ...
Reply
#58
In one of the best Arch Linux derrivatives going, called EndeavourOS, might also have to do this line so QB64PE is created successfully. Note no "dev" nor "devel" after the item names, which boggled me today. Everything else needed is already installed, eg. "g++", "alsa-lib".

Code: (Select All)
$ sudo pacman -S glu libcurl-compat
Reply




Users browsing this thread: 5 Guest(s)