Posts: 823
Threads: 116
Joined: Apr 2022
Reputation:
20
02-04-2025, 12:57 PM
(This post was last modified: 02-04-2025, 01:04 PM by madscijr.)
Back in the olden days before digital audio, when sound was recorded using analog formats like records and tapes, the pitch of the audio was affected by playback speed (e.g., 33 1/4 vs 45 vs 78 rpm for records, 3.75 vs 7.5 vs 15 vs 30 ips for audio tape). Or you could record at a very high speed, and playing back the recording at normal speed would result in a very slow and low sound. Playing back audio recorded at a very low speed would sound like chipmunks. Professional and even consumer tape machines often included a knob to vary the speed of the tape or turntable motor and thus the pitch & speed, where adjusting it a small amount allowed fine-tuning. DJs can accomplish this when playing records by lightly pressing their finger down on the record as it plays (the harder they press, the more it slows down).
I'm wondering how we might use modern QB64PE with its extensive audio capability to replicate this function? Perhaps the playback speed (or speed while recording) could be manipulated using a mouse or other analog or continuous type input device like an analog joystick, or a little at a time by pressing +/- keys.
Any ideas how this might be done?
Posts: 51
Threads: 7
Joined: May 2024
Reputation:
7
the easiest and dirtiest way. playback with _sndraw while making computations on sample playback. load a wave file and play back each sample frame with that procedure. normal playback is rate of 1. a higher rate produces a higher pitch and faster playback. a lower rate, with a better chance one frame is played twice or more. has issues with sound quality but it's the only way to get a lower frequency than root. interpolation for lower pitches would only increase cpu usage.
a really fast computer would be needed to do it in realtime and to keep up with gui controls and that sort of thing.
Posts: 321
Threads: 51
Joined: May 2022
Reputation:
41
02-04-2025, 09:14 PM
(This post was last modified: 02-04-2025, 09:20 PM by Petr.)
Here is an equalizer program where you can change the sound frequency by pressing + or minus: https://qb64phoenix.com/forum/showthread...558&page=2
Speed change - try this....
Code: (Select All)
f$ = "slunce.mp3" 'must be mp3 (use single array)
Dim As Long s, t, Sze, i, Block
Dim As _MEM m
If _FileExists(f$) Then
s = _SndOpen(f$)
_Delay .5
Else
Print f$; " not found."
End
End If
If s < 1 Then Print "Error opening sound file "; f$: End
Sze = _SndRate * _SndLen(s)
m = _MemSound(s, 0)
Dim As Single Left(Sze), Right(Sze) 'load Audio do Ram
Do Until t = m.SIZE
Left(i) = _MemGet(m, m.OFFSET + t, Single)
Right(i) = _MemGet(m, m.OFFSET + t + 4, Single)
t = t + 8
i = i + 1
Loop
i = 0
speed = 1 'basic speed
Block = _SndRate \ 4 'data window - 0.25 sec
Print "Press + or - for setting music speed..."
Do Until i >= Sze - Block
X = i
Do Until X = Block
If X + i >= Sze Then Exit Do
_SndRaw Left(i + X), Right(i + X)
X = X + speed
Do Until _SndRawLen < .1
Loop
i$ = InKey$
Select Case i$
Case "+": speed = speed + .1
Case "-": speed = speed - .1
End Select
Locate 2: Print "Speed: "; CInt(speed * 100); " percent "
If speed < 0 Then speed = 0
Loop
i = i + Block
Loop
_MemFree m
_SndClose s
Print "End."
Posts: 823
Threads: 116
Joined: Apr 2022
Reputation:
20
02-04-2025, 11:30 PM
(This post was last modified: 02-04-2025, 11:36 PM by madscijr.)
(02-04-2025, 05:28 PM)hsiangch_ong Wrote: the easiest and dirtiest way. playback with _sndraw while making computations on sample playback. load a wave file and play back each sample frame with that procedure. normal playback is rate of 1. a higher rate produces a higher pitch and faster playback. a lower rate, with a better chance one frame is played twice or more. has issues with sound quality but it's the only way to get a lower frequency than root. interpolation for lower pitches would only increase cpu usage.
a really fast computer would be needed to do it in realtime and to keep up with gui controls and that sort of thing. I don't need a fancy GUI, just reading basic mouse input and displaying a number on screen in plain text will be enough. I have not done any _sndraw, are there any simple examples you would recommend that I can build off of?
UPDATE: I just saw Petr's reply, will try playing with that...
(02-04-2025, 09:14 PM)Petr Wrote: Here is an equalizer program where you can change the sound frequency by pressing + or minus: https://qb64phoenix.com/forum/showthread...558&page=2
Speed change - try this....
Code: (Select All)
f$ = "slunce.mp3" 'must be mp3 (use single array)
...
Print "End."
Oh cool - thanks!!
I'll give these a look and see if I can combine the functionality,
and post the results when I have something.
Posts: 823
Threads: 116
Joined: Apr 2022
Reputation:
20
(02-04-2025, 09:14 PM)Petr Wrote: Here is an equalizer program where you can change the sound frequency by pressing + or minus: https://qb64phoenix.com/forum/showthread...558&page=2
Speed change - try this....
Code: (Select All)
f$ = "slunce.mp3" 'must be mp3 (use single array)
...
Print "End."
It works great! Thanks!
I want to play with it some more and hear how it sounds with different types of audio files, but it does exactly what I was looking for.
Thanks again!
Posts: 823
Threads: 116
Joined: Apr 2022
Reputation:
20
02-06-2025, 09:22 PM
(This post was last modified: 02-07-2025, 12:08 AM by madscijr.)
(02-04-2025, 09:14 PM)Petr Wrote: Code: (Select All)
f$ = "slunce.mp3" 'must be mp3 (use single array)
Question: How might we get it to work with WAV files?
(02-04-2025, 09:14 PM)Petr Wrote: Speed change - try this....
I added to your code to allow using the mouse to speed up / slow down the audio file. Also, +/- now increases/decreases speed by one percent at a time to allow finer tuning.
The code is kind of bloated (apologies in advance to Steve and bplus for the headache it will give you!) and uses a hi-res screen, so not as efficient as a text-only display. Just a proof of concept for using mouse input.
Code: (Select All) ' Question: sound file playback (and record) - manipulating speed + pitch in realtime?
' https://qb64phoenix.com/forum/showthread.php?tid=3440
' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
' Post #1
' From: madscijr
' Date: 02-04-2025, 07:57 AM (This post was last modified: Yesterday, 08:04 AM by madscijr.)
'
' Back in the olden days before digital audio, when sound was recorded using
' analog formats like records and tapes, the pitch of the audio was affected by
' playback speed (e.g., 33 1/4 vs 45 vs 78 rpm for records, 3.75 vs 7.5 vs 15 vs
' 30 ips for audio tape). Or you could record at a very high speed, and playing
' back the recording at normal speed would result in a very slow and low sound.
' Playing back audio recorded at a very low speed would sound like chipmunks.
' Professional and even consumer tape machines often included a knob to vary the
' speed of the tape or turntable motor and thus the pitch & speed, where
' adjusting it a small amount allowed fine-tuning. DJs can accomplish this when
' playing records by lightly pressing their finger down on the record as it plays
' (the harder they press, the more it slows down).
'
' I'm wondering how we might use modern QB64PE with its extensive audio
' capability to replicate this function? Perhaps the playback speed (or speed
' while recording) could be manipulated using a mouse or other analog or
' continuous type input device like an analog joystick, or a little at a time by
' pressing +/- keys.
'
' Any ideas how this might be done?
' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
' Reply #2
' From: hsiangch_ong Offline
' Date: 02-04-2025, 12:28 PM
'
' the easiest and dirtiest way. playback with _sndraw while making computations
' on sample playback. load a wave file and play back each sample frame with that
' procedure. normal playback is rate of 1. a higher rate produces a higher
' pitch and faster playback. a lower rate, with a better chance one frame is
' played twice or more. has issues with sound quality but it's the only way to
' get a lower frequency than root. interpolation for lower pitches would only
' increase cpu usage.
'
' a really fast computer would be needed to do it in realtime and to keep up with
' gui controls and that sort of thing.
' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
' Reply #3
' From : Petr
' Date: 02-04-2025, 04:14 PM (This post was last modified: Yesterday, 04:20 PM by Petr.)
'
' Here is an equalizer program where you can change the sound frequency by
' pressing + or minus: https://qb64phoenix.com/forum/showthread...558&page=2
'
' Speed change - try this....
' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
' Reply #4
' From: madscijr
' Date: 02-04-2025, 06:30 PM (This post was last modified: Yesterday, 06:36 PM by madscijr.)
'
' (02-04-2025, 12:28 PM) hsiangch_ong Wrote:
' >the easiest and dirtiest way. playback with _sndraw while making computations
' >on sample playback. load a wave file and play back each sample frame with that
' >procedure. normal playback is rate of 1. a higher rate produces a higher
' >pitch and faster playback. a lower rate, with a better chance one frame is
' >played twice or more. has issues with sound quality but it's the only way to
' >get a lower frequency than root. interpolation for lower pitches would only
' >increase cpu usage.
' >
' >a really fast computer would be needed to do it in realtime and to keep up with
' >gui controls and that sort of thing.
'
' I don't need a fancy GUI, just reading basic mouse input and displaying a
' number on screen in plain text will be enough. I have not done any _sndraw, are
' there any simple examples you would recommend that I can build off of?
'
' UPDATE: I just saw Petr's reply, will try playing with that...
'
' Petr Wrote:
' >Here is an equalizer program where you can change the sound frequency by
' >pressing + or minus: https://qb64phoenix.com/forum/showthread...558&page=2
' >
' >Speed change - try this....
' >Code: (Select All)
' >f$ = "slunce.mp3" 'must be mp3 (use single array)
' >...
' >Print "End."
'
' Oh cool - thanks!!
' I'll give these a look and see if I can combine the functionality,
' and post the results when I have something.
' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
Const FALSE = 0
Const TRUE = Not FALSE ' -1
' CONSTANTS FOR QUICKMOUSE
Const Drift = 5 ' change the drift value for how lenient you want to be for your directional wandering of the mouse movement
' GLOBAL VARIABLES FOR QUICKMOUSE
Dim Shared As Long MB1, MB2, MB3, MMX, MMY, MW, MX, MY
Dim Shared As Integer oMB1, oMB2, oMB3 ' old mouse buttons
Dim f$
Dim As Long s
Dim t
Dim Sze
Dim i
Dim Block
Dim As _MEM m
ReDim As Single Left(-1)
ReDim As Single Right(-1)
Dim xPos As Integer
Dim xMax As Integer
Dim bMoved As Integer
Dim bExit As Integer
Dim RowNum As Integer
f$ = "sound1.mp3" ' must be mp3 (use single array)
If _FileExists(f$) Then
s = _SndOpen(f$)
_Delay .5
Else
Print f$; " not found."
End
End If
If s < 1 Then Print "Error opening sound file "; f$: End
Sze = _SndRate * _SndLen(s)
m = _MemSound(s, 0)
ReDim As Single Left(Sze) ' load Audio do Ram
ReDim As Single Right(Sze) ' load Audio do Ram
Do Until t = m.SIZE
Left(i) = _MemGet(m, m.OFFSET + t, Single)
Right(i) = _MemGet(m, m.OFFSET + t + 4, Single)
t = t + 8
i = i + 1
Loop ' Until t = m.SIZE
' Init screen
Screen _NewImage(1024, 768, 32): _ScreenMove 0, 0 ' Screen set at top of program, before main menu.
Cls , cBlack~& ' makes the background opaque black
' SHOW INSTRUCTIONS
RowNum = 0
RowNum = RowNum + 1: Color cWhite~&, cBlue~&: PrintString0 RowNum, 1, "Tape Speed Simulator v2.0"
RowNum = RowNum + 1: Color cRed~&, cBlack~&: PrintString0 RowNum, 1, "by Petr"
RowNum = RowNum + 1: Color cLime~&, cBlack~&: PrintString0 RowNum, 1, "mods by madscijr"
RowNum = RowNum + 1
RowNum = RowNum + 1: Color cPurple~&, cBlack~&: PrintString0 RowNum, 1, "MOUSE:"
RowNum = RowNum + 1: Color cCyan~&, cBlack~&: PrintString0 RowNum, 1, "Left/right/wheel: decrease/increase sound speed and pitch"
RowNum = RowNum + 1: Color cCyan~&, cBlack~&: PrintString0 RowNum, 1, "Left click : decrease sound speed/pitch by 100%"
RowNum = RowNum + 1: Color cCyan~&, cBlack~&: PrintString0 RowNum, 1, "Middle click : reset sound speed/pitch to 100%"
RowNum = RowNum + 1: Color cCyan~&, cBlack~&: PrintString0 RowNum, 1, "Right click : increase sound speed/pitch by 100%"
RowNum = RowNum + 1
RowNum = RowNum + 1: Color cPurple~&, cBlack~&: PrintString0 RowNum, 1, "KEYS:"
RowNum = RowNum + 1: Color cCyan~&, cBlack~&: PrintString0 RowNum, 1, "- or +: decrease/increase sound speed and pitch by 1%"
RowNum = RowNum + 1: Color cCyan~&, cBlack~&: PrintString0 RowNum, 1, "Esc : Quit program"
RowNum = RowNum + 1
RowNum = RowNum + 1
_MouseHide
' INITIALIZE
i = 0
speed = 1 ' basic speed
xPos = _Width * speed
xMax = _Width
Block = _SndRate \ 4 ' data window - 0.25 sec
bMoved = _FALSE
bExit = _FALSE
Do Until i >= Sze - Block
X = i
Do Until X = Block
If X + i >= Sze Then Exit Do
_SndRaw Left(i + X), Right(i + X)
X = X + speed
Do Until _SndRawLen < .1
Loop
' LET USER CHANGE SPEED WITH KEYBOARD
i$ = InKey$
Select Case i$
Case "-": speed = speed - .01
Case "+": speed = speed + .01
End Select
' LET USER CHANGE SPEED WITH MOUSE
quickmouse
' LEFT/RIGHT
If MMX < -Drift Then speed = speed - .01 ' Print "LEFT"
If MMX > Drift Then speed = speed + .01 ' Print "RIGHT"
' MOUSE WHEEL
If MW > 0 Then speed = speed - .01: bMoved = _TRUE ' Print "LEFT"
If MW < 0 Then speed = speed + .01: bMoved = _TRUE ' Print "RIGHT"
' UP/DOWN
'If MMY < -Drift Then Print "UP"
'If MMY > Drift Then Print "DOWN"
' MOUSE BUTTONS
If MB1 Then speed = speed - 1: bMoved = _TRUE ' Print "PEW PEW"
If MB2 Then speed = speed + 1: bMoved = _TRUE ' Print "BYE BYE": System
If MB3 Then speed = 1: bMoved = _TRUE
' CHECK BOUDARIES
If speed < 0 Then speed = 0: bMoved = _TRUE
' PLACE MOUSE POINTER
'if bMoved = _TRUE then _MOUSEMOVE (speed * 100), MY
' SHOW VALUES
Color cHotPink~&, cBlack~&: PrintString0 RowNum, 1, "Speed: " + _Trim$(Str$(speed * 100)) + "% "
' SHOW GRAPH
DrawRectSolid 0, ((RowNum + 1) * _FontHeight), _Width, _FontHeight, cGray~&
DrawRectSolid 0, ((RowNum + 1) * _FontHeight), (speed * 100), _FontHeight, cWhite~&
' DID USER HIT ESCAPE?
If _KeyDown(27) Then bExit = _TRUE: Exit Do
Loop ' Until X = Block
' DID USER HIT ESCAPE?
If bExit = _TRUE Then Exit Do
i = i + Block
Loop ' Until i >= Sze - Block
_MemFree m
_SndClose s
If _MouseHidden = TRUE Then _MouseShow "DEFAULT"
Print "End."
' /////////////////////////////////////////////////////////////////////////////
' QuickMouse
' https://qb64phoenix.com/forum/showthread.php?tid=3442
' From: SMcNeill
' Date: 02-05-2025 04:30 PM
' I was talking to someone on Discord earlier today,
' and they were looking for a simple little routine
' to add directional movement and pew-pews to a game,
' using a mouse. They had a routine,
' but it was rather laggy and didn't work quite right for me,
' so I wrote this little demo for them and thought
' I'd share it here in case anyone else might need
' something really simple like this:
Sub quickmouse
' mouse buttons
MB1 = _FALSE
MB2 = _FALSE
MB3 = _FALSE
' track x/y
MMX = 0
MMY = 0
' track mouse wheel
MW = 0
While _MouseInput
MMX = MMX + _MouseMovementX
MMY = MMY + _MouseMovementY
MW = MW + _MouseWheel
MX = _MouseX
MY = _MouseY
Wend
' mouse buttons
If _MouseButton(1) And Not oMB1 Then MB1 = _TRUE
If _MouseButton(2) And Not oMB2 Then MB2 = _TRUE
If _MouseButton(3) And Not oMB3 Then MB3 = _TRUE
' old mouse buttons
oMB1 = _MouseButton(1)
oMB2 = _MouseButton(2)
oMB3 = _MouseButton(3)
End Sub ' quickmouse
' /////////////////////////////////////////////////////////////////////////////
' Convert integer to string and trim it (because normal Str$ adds spaces)
Function istr$ (MyValue%)
istr$ = _Trim$(Str$(MyValue%))
End Function ' istr$
' /////////////////////////////////////////////////////////////////////////////
' Convert long to string and trim it (because normal Str$ adds spaces)
Function lstr$ (MyValue&)
lstr$ = _Trim$(Str$(MyValue&))
End Function ' lstr$
' /////////////////////////////////////////////////////////////////////////////
' Use to pretty print TRUE and FALSE values.
Function TrueFalse$ (myValue)
If myValue = TRUE Then
TrueFalse$ = "TRUE"
Else
TrueFalse$ = "FALSE"
End If
End Function ' TrueFalse$
' /////////////////////////////////////////////////////////////////////////////
' Does a _PrintString at the specified row+column.
' iRow and iCol are 0-based.
' See also: PrintString1
Sub PrintString0 (iRow As Integer, iCol As Integer, MyString As String)
Dim iX As Integer
Dim iY As Integer
iX = _FontWidth * iCol
iY = _FontHeight * iRow ' (iRow + 1)
_PrintString (iX, iY), MyString
End Sub ' PrintString0
' /////////////////////////////////////////////////////////////////////////////
' DRAW A 2-D RECTANGLE (OUTLINE)
'DrawRectOutline iX, iY, iSizeW, iSizeH, fgColor
Sub DrawRectOutline (iX As Integer, iY As Integer, iSizeW As Integer, iSizeH As Integer, fgColor As _Unsigned Long)
Line (iX, iY)-(iX + (iSizeW - 1), iY + (iSizeH - 1)), fgColor, B ' Draw rectangle outline
End Sub ' DrawRectOutline
' /////////////////////////////////////////////////////////////////////////////
' DRAW A 2-D RECTANGLE (SOLID)
'DrawRectSolid iX, iY, iSizeW, iSizeH, fgColor
Sub DrawRectSolid (iX As Integer, iY As Integer, iSizeW As Integer, iSizeH As Integer, fgColor As _Unsigned Long)
Line (iX, iY)-(iX + (iSizeW - 1), iY + (iSizeH - 1)), fgColor, BF ' Draw a solid rectangle
End Sub ' DrawRectSolid
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' BEGIN RGB COLOR FUNCTIONS #RGB
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function cRed~& ()
cRed = _RGB32(255, 0, 0)
End Function
Function cOrangeRed~& ()
cOrangeRed = _RGB32(255, 69, 0)
End Function ' cOrangeRed~&
Function cDarkOrange~& ()
cDarkOrange = _RGB32(255, 140, 0)
End Function ' cDarkOrange~&
Function cOrange~& ()
cOrange = _RGB32(255, 165, 0)
End Function ' cOrange~&
Function cGold~& ()
cGold = _RGB32(255, 215, 0)
End Function ' cGold~&
Function cYellow~& ()
cYellow = _RGB32(255, 255, 0)
End Function ' cYellow~&
' LONG-HAIRED FRIENDS OF JESUS OR NOT,
' THIS IS NOT YELLOW ENOUGH (TOO CLOSE TO LIME)
' TO USE FOR OUR COMPLEX RAINBOW SEQUENCE:
Function cChartreuse~& ()
cChartreuse = _RGB32(127, 255, 0)
End Function ' cChartreuse~&
' WE SUBSTITUTE THIS CSS3 COLOR FOR INBETWEEN LIME AND YELLOW:
Function cOliveDrab1~& ()
cOliveDrab1 = _RGB32(192, 255, 62)
End Function ' cOliveDrab1~&
Function cLime~& ()
cLime = _RGB32(0, 255, 0)
End Function ' cLime~&
Function cMediumSpringGreen~& ()
cMediumSpringGreen = _RGB32(0, 250, 154)
End Function ' cMediumSpringGreen~&
' ADDED THIS FOR THE GAUGE COLOR:
Function cSpringGreen~& ()
cSpringGreen = _RGB32(0, 255, 160)
End Function ' cSpringGreen~&
Function cCyan~& ()
cCyan = _RGB32(0, 255, 255)
End Function ' cCyan~&
Function cDeepSkyBlue~& ()
cDeepSkyBlue = _RGB32(0, 191, 255)
End Function ' cDeepSkyBlue~&
Function cDodgerBlue~& ()
cDodgerBlue = _RGB32(30, 144, 255)
End Function ' cDodgerBlue~&
Function cSeaBlue~& ()
cSeaBlue = _RGB32(0, 64, 255)
End Function ' cSeaBlue~&
Function cBlue~& ()
cBlue = _RGB32(0, 0, 255)
End Function ' cBlue~&
Function cBluePurple~& ()
cBluePurple = _RGB32(64, 0, 255)
End Function ' cBluePurple~&
Function cDeepPurple~& ()
cDeepPurple = _RGB32(96, 0, 255)
End Function ' cDeepPurple~&
Function cPurple~& ()
cPurple = _RGB32(128, 0, 255)
End Function ' cPurple~&
Function cPurpleRed~& ()
cPurpleRed = _RGB32(128, 0, 192)
End Function ' cPurpleRed~&
Function cDarkRed~& ()
cDarkRed = _RGB32(160, 0, 64)
End Function ' cDarkRed~&
Function cBrickRed~& ()
cBrickRed = _RGB32(192, 0, 32)
End Function ' cBrickRed~&
Function cDarkGreen~& ()
cDarkGreen = _RGB32(0, 100, 0)
End Function ' cDarkGreen~&
Function cGreen~& ()
cGreen = _RGB32(0, 128, 0)
End Function ' cGreen~&
Function cOliveDrab~& ()
cOliveDrab = _RGB32(107, 142, 35)
End Function ' cOliveDrab~&
Function cLightPink~& ()
cLightPink = _RGB32(255, 182, 193)
End Function ' cLightPink~&
Function cHotPink~& ()
cHotPink = _RGB32(255, 105, 180)
End Function ' cHotPink~&
Function cDeepPink~& ()
cDeepPink = _RGB32(255, 20, 147)
End Function ' cDeepPink~&
Function cMagenta~& ()
cMagenta = _RGB32(255, 0, 255)
End Function ' cMagenta~&
Function cBlack~& ()
cBlack = _RGB32(0, 0, 0)
End Function ' cBlack~&
Function cDimGray~& ()
cDimGray = _RGB32(105, 105, 105)
End Function ' cDimGray~&
Function cGray~& ()
cGray = _RGB32(128, 128, 128)
End Function ' cGray~&
Function cDarkGray~& ()
cDarkGray = _RGB32(169, 169, 169)
End Function ' cDarkGray~&
Function cSilver~& ()
cSilver = _RGB32(192, 192, 192)
End Function ' cSilver~&
Function cLightGray~& ()
cLightGray = _RGB32(211, 211, 211)
End Function ' cLightGray~&
Function cGainsboro~& ()
cGainsboro = _RGB32(220, 220, 220)
End Function ' cGainsboro~&
Function cWhiteSmoke~& ()
cWhiteSmoke = _RGB32(245, 245, 245)
End Function ' cWhiteSmoke~&
Function cWhite~& ()
cWhite = _RGB32(255, 255, 255)
'cWhite = _RGB32(254, 254, 254)
End Function ' cWhite~&
Function cDarkBrown~& ()
cDarkBrown = _RGB32(128, 64, 0)
End Function ' cDarkBrown~&
Function cLightBrown~& ()
cLightBrown = _RGB32(196, 96, 0)
End Function ' cLightBrown~&
Function cKhaki~& ()
cKhaki = _RGB32(240, 230, 140)
End Function ' cKhaki~&
Function cEmpty~& ()
'cEmpty~& = -1
cEmpty = _RGB32(0, 0, 0, 0)
End Function ' cEmpty~&
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' END RGB COLOR FUNCTIONS @RGB
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' ################################################################################################################################################################
' BEGIN RGB COLOR ARRAY FUNCTIONS #COLR
' ################################################################################################################################################################
' /////////////////////////////////////////////////////////////////////////////
Sub AddColor (ColorValue As _Unsigned Long, arrColor() As _Unsigned Long)
ReDim _Preserve arrColor(0 To UBound(arrColor) + 1) As _Unsigned Long
arrColor(UBound(arrColor)) = ColorValue
End Sub ' AddColor
' /////////////////////////////////////////////////////////////////////////////
Sub AddColors (ColorValue As _Unsigned Long, arrColor() As _Unsigned Long, HowMany As Long)
Dim iLoop As Integer
For iLoop = 1 To HowMany
AddColor ColorValue, arrColor()
Next iLoop
End Sub ' AddColors
' /////////////////////////////////////////////////////////////////////////////
Sub AddSpectrumColors (arrColor() As _Unsigned Long)
Dim iNum As Integer
iNum = 1
AddColors cRed, arrColor(), iNum
AddColors cOrangeRed, arrColor(), iNum
AddColors cDarkOrange, arrColor(), iNum
AddColors cOrange, arrColor(), iNum
AddColors cGold, arrColor(), iNum
AddColors cYellow, arrColor(), iNum
AddColors cChartreuse, arrColor(), iNum
AddColors cOliveDrab1, arrColor(), iNum
AddColors cLime, arrColor(), iNum
AddColors cMediumSpringGreen, arrColor(), iNum
AddColors cSpringGreen, arrColor(), iNum
AddColors cCyan, arrColor(), iNum
AddColors cDeepSkyBlue, arrColor(), iNum
AddColors cDodgerBlue, arrColor(), iNum
AddColors cSeaBlue, arrColor(), iNum
AddColors cBlue, arrColor(), iNum
AddColors cBluePurple, arrColor(), iNum
AddColors cDeepPurple, arrColor(), iNum
AddColors cPurple, arrColor(), iNum
AddColors cPurpleRed, arrColor(), iNum
End Sub ' AddSpectrumColors
' /////////////////////////////////////////////////////////////////////////////
Sub AddGrayscaleColors (arrColor() As _Unsigned Long)
Dim iNum As Integer
iNum = 1
AddColors cDimGray, arrColor(), iNum
AddColors cGray, arrColor(), iNum
AddColors cDarkGray, arrColor(), iNum
AddColors cSilver, arrColor(), iNum
AddColors cLightGray, arrColor(), iNum
AddColors cGainsboro, arrColor(), iNum
AddColors cWhiteSmoke, arrColor(), iNum
AddColors cWhite, arrColor(), iNum '* 2
AddColors cWhiteSmoke, arrColor(), iNum
AddColors cGainsboro, arrColor(), iNum
AddColors cLightGray, arrColor(), iNum
AddColors cSilver, arrColor(), iNum
AddColors cDarkGray, arrColor(), iNum
AddColors cGray, arrColor(), iNum
End Sub ' AddGrayscaleColors
' ################################################################################################################################################################
' END COLOR ARRAY FUNCTIONS @COLR
' ################################################################################################################################################################
Here is a slightly modified version, with just a couple lines added to show the progress of the file playing, However, now the sound quality is very poor. I probably need to go back and streamline the code to be more efficient, and simplify the display to be text only:
Code: (Select All) ' This version sounds really bad with just a couple extra lines...
' Question: sound file playback (and record) - manipulating speed + pitch in realtime?
' https://qb64phoenix.com/forum/showthread.php?tid=3440
' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
' Post #1
' From: madscijr
' Date: 02-04-2025, 07:57 AM (This post was last modified: Yesterday, 08:04 AM by madscijr.)
'
' Back in the olden days before digital audio, when sound was recorded using
' analog formats like records and tapes, the pitch of the audio was affected by
' playback speed (e.g., 33 1/4 vs 45 vs 78 rpm for records, 3.75 vs 7.5 vs 15 vs
' 30 ips for audio tape). Or you could record at a very high speed, and playing
' back the recording at normal speed would result in a very slow and low sound.
' Playing back audio recorded at a very low speed would sound like chipmunks.
' Professional and even consumer tape machines often included a knob to vary the
' speed of the tape or turntable motor and thus the pitch & speed, where
' adjusting it a small amount allowed fine-tuning. DJs can accomplish this when
' playing records by lightly pressing their finger down on the record as it plays
' (the harder they press, the more it slows down).
'
' I'm wondering how we might use modern QB64PE with its extensive audio
' capability to replicate this function? Perhaps the playback speed (or speed
' while recording) could be manipulated using a mouse or other analog or
' continuous type input device like an analog joystick, or a little at a time by
' pressing +/- keys.
'
' Any ideas how this might be done?
' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
' Reply #2
' From: hsiangch_ong Offline
' Date: 02-04-2025, 12:28 PM
'
' the easiest and dirtiest way. playback with _sndraw while making computations
' on sample playback. load a wave file and play back each sample frame with that
' procedure. normal playback is rate of 1. a higher rate produces a higher
' pitch and faster playback. a lower rate, with a better chance one frame is
' played twice or more. has issues with sound quality but it's the only way to
' get a lower frequency than root. interpolation for lower pitches would only
' increase cpu usage.
'
' a really fast computer would be needed to do it in realtime and to keep up with
' gui controls and that sort of thing.
' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
' Reply #3
' From : Petr
' Date: 02-04-2025, 04:14 PM (This post was last modified: Yesterday, 04:20 PM by Petr.)
'
' Here is an equalizer program where you can change the sound frequency by
' pressing + or minus: https://qb64phoenix.com/forum/showthread...558&page=2
'
' Speed change - try this....
' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
' Reply #4
' From: madscijr
' Date: 02-04-2025, 06:30 PM (This post was last modified: Yesterday, 06:36 PM by madscijr.)
'
' (02-04-2025, 12:28 PM) hsiangch_ong Wrote:
' >the easiest and dirtiest way. playback with _sndraw while making computations
' >on sample playback. load a wave file and play back each sample frame with that
' >procedure. normal playback is rate of 1. a higher rate produces a higher
' >pitch and faster playback. a lower rate, with a better chance one frame is
' >played twice or more. has issues with sound quality but it's the only way to
' >get a lower frequency than root. interpolation for lower pitches would only
' >increase cpu usage.
' >
' >a really fast computer would be needed to do it in realtime and to keep up with
' >gui controls and that sort of thing.
'
' I don't need a fancy GUI, just reading basic mouse input and displaying a
' number on screen in plain text will be enough. I have not done any _sndraw, are
' there any simple examples you would recommend that I can build off of?
'
' UPDATE: I just saw Petr's reply, will try playing with that...
'
' Petr Wrote:
' >Here is an equalizer program where you can change the sound frequency by
' >pressing + or minus: https://qb64phoenix.com/forum/showthread...558&page=2
' >
' >Speed change - try this....
' >Code: (Select All)
' >f$ = "slunce.mp3" 'must be mp3 (use single array)
' >...
' >Print "End."
'
' Oh cool - thanks!!
' I'll give these a look and see if I can combine the functionality,
' and post the results when I have something.
' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
Const FALSE = 0
Const TRUE = Not FALSE ' -1
' CONSTANTS FOR QUICKMOUSE
Const Drift = 5 ' change the drift value for how lenient you want to be for your directional wandering of the mouse movement
' GLOBAL VARIABLES FOR QUICKMOUSE
Dim Shared As Long MB1, MB2, MB3, MMX, MMY, MW, MX, MY
Dim Shared As Integer oMB1, oMB2, oMB3 ' old mouse buttons
Dim f$
Dim As Long s
Dim t
Dim Sze
Dim i
Dim Block
Dim As _MEM m
ReDim As Single Left(-1)
ReDim As Single Right(-1)
Dim xPos As Integer
Dim xMax As Integer
Dim bMoved As Integer
Dim bExit As Integer
Dim RowNum As Integer
f$ = "sound1.mp3" ' must be mp3 (use single array)
If _FileExists(f$) Then
s = _SndOpen(f$)
_Delay .5
Else
Print f$; " not found."
End
End If
If s < 1 Then Print "Error opening sound file "; f$: End
Sze = _SndRate * _SndLen(s)
m = _MemSound(s, 0)
ReDim As Single Left(Sze) ' load Audio do Ram
ReDim As Single Right(Sze) ' load Audio do Ram
Do Until t = m.SIZE
Left(i) = _MemGet(m, m.OFFSET + t, Single)
Right(i) = _MemGet(m, m.OFFSET + t + 4, Single)
t = t + 8
i = i + 1
Loop ' Until t = m.SIZE
' Init screen
Screen _NewImage(1024, 768, 32): _ScreenMove 0, 0 ' Screen set at top of program, before main menu.
Cls , cBlack~& ' makes the background opaque black
' SHOW INSTRUCTIONS
RowNum = 0
RowNum = RowNum + 1: Color cWhite~&, cBlue~&: PrintString0 RowNum, 1, "Tape Speed Simulator v2.0"
RowNum = RowNum + 1: Color cRed~&, cBlack~&: PrintString0 RowNum, 1, "by Petr"
RowNum = RowNum + 1: Color cLime~&, cBlack~&: PrintString0 RowNum, 1, "mods by madscijr"
RowNum = RowNum + 1
RowNum = RowNum + 1: Color cPurple~&, cBlack~&: PrintString0 RowNum, 1, "MOUSE:"
RowNum = RowNum + 1: Color cCyan~&, cBlack~&: PrintString0 RowNum, 1, "Left/right/wheel: decrease/increase sound speed and pitch"
RowNum = RowNum + 1: Color cCyan~&, cBlack~&: PrintString0 RowNum, 1, "Left click : decrease sound speed/pitch by 100%"
RowNum = RowNum + 1: Color cCyan~&, cBlack~&: PrintString0 RowNum, 1, "Middle click : reset sound speed/pitch to 100%"
RowNum = RowNum + 1: Color cCyan~&, cBlack~&: PrintString0 RowNum, 1, "Right click : increase sound speed/pitch by 100%"
RowNum = RowNum + 1
RowNum = RowNum + 1: Color cPurple~&, cBlack~&: PrintString0 RowNum, 1, "KEYS:"
RowNum = RowNum + 1: Color cCyan~&, cBlack~&: PrintString0 RowNum, 1, "- or +: decrease/increase sound speed and pitch by 1%"
RowNum = RowNum + 1: Color cCyan~&, cBlack~&: PrintString0 RowNum, 1, "Esc : Quit program"
RowNum = RowNum + 1
RowNum = RowNum + 1
_MouseHide
' INITIALIZE
i = 0
speed = 1 ' basic speed
xPos = _Width * speed
xMax = _Width
Block = _SndRate \ 4 ' data window - 0.25 sec
bMoved = _FALSE
bExit = _FALSE
Do Until i >= Sze - Block
X = i
Do Until X = Block
If X + i >= Sze Then Exit Do
_SndRaw Left(i + X), Right(i + X)
X = X + speed
Do Until _SndRawLen < .1
Loop
' LET USER CHANGE SPEED WITH KEYBOARD
i$ = InKey$
Select Case i$
Case "-": speed = speed - .01
Case "+": speed = speed + .01
End Select
' LET USER CHANGE SPEED WITH MOUSE
quickmouse
' LEFT/RIGHT
If MMX < -Drift Then speed = speed - .01 ' Print "LEFT"
If MMX > Drift Then speed = speed + .01 ' Print "RIGHT"
' MOUSE WHEEL
If MW > 0 Then speed = speed - .01: bMoved = _TRUE ' Print "LEFT"
If MW < 0 Then speed = speed + .01: bMoved = _TRUE ' Print "RIGHT"
' UP/DOWN
'If MMY < -Drift Then Print "UP"
'If MMY > Drift Then Print "DOWN"
' MOUSE BUTTONS
If MB1 Then speed = speed - 1: bMoved = _TRUE ' Print "PEW PEW"
If MB2 Then speed = speed + 1: bMoved = _TRUE ' Print "BYE BYE": System
If MB3 Then speed = 1: bMoved = _TRUE
' CHECK BOUDARIES
If speed < 0 Then speed = 0: bMoved = _TRUE
' PLACE MOUSE POINTER
'if bMoved = _TRUE then _MOUSEMOVE (speed * 100), MY
' SHOW VALUES
Color cHotPink~&, cBlack~&: PrintString0 RowNum, 1, "Speed: " + _Trim$(Str$(speed * 100)) + "% "
' SHOW GRAPH
DrawRectSolid 0, ((RowNum + 1) * _FontHeight), _Width, _FontHeight, cGray~&
DrawRectSolid 0, ((RowNum + 1) * _FontHeight), (speed * 100), _FontHeight, cWhite~&
' SHOW PROGRESS (HOW DO YOU SHOW IT IN SECONDS?)
Color cDodgerBlue~&, cBlack~&: PrintString0 RowNum + 3, 1, "Progress: " + _Trim$(Str$((i / (Sze - Block)) * 100)) + "% "
' SHOW PROGRESS GRAPH
DrawRectSolid 0, ((RowNum + 4) * _FontHeight), 100, _FontHeight, cGray~&
DrawRectSolid 0, ((RowNum + 4) * _FontHeight), (i / (Sze - Block)) * 100, _FontHeight, cWhite~&
' DID USER HIT ESCAPE?
If _KeyDown(27) Then bExit = _TRUE: Exit Do
Loop ' Until X = Block
' DID USER HIT ESCAPE?
If bExit = _TRUE Then Exit Do
i = i + Block
Loop ' Until i >= Sze - Block
_MemFree m
_SndClose s
If _MouseHidden = TRUE Then _MouseShow "DEFAULT"
Print "End."
' /////////////////////////////////////////////////////////////////////////////
' QuickMouse
' https://qb64phoenix.com/forum/showthread.php?tid=3442
' From: SMcNeill
' Date: 02-05-2025 04:30 PM
' I was talking to someone on Discord earlier today,
' and they were looking for a simple little routine
' to add directional movement and pew-pews to a game,
' using a mouse. They had a routine,
' but it was rather laggy and didn't work quite right for me,
' so I wrote this little demo for them and thought
' I'd share it here in case anyone else might need
' something really simple like this:
Sub quickmouse
' mouse buttons
MB1 = _FALSE
MB2 = _FALSE
MB3 = _FALSE
' track x/y
MMX = 0
MMY = 0
' track mouse wheel
MW = 0
While _MouseInput
MMX = MMX + _MouseMovementX
MMY = MMY + _MouseMovementY
MW = MW + _MouseWheel
MX = _MouseX
MY = _MouseY
Wend
' mouse buttons
If _MouseButton(1) And Not oMB1 Then MB1 = _TRUE
If _MouseButton(2) And Not oMB2 Then MB2 = _TRUE
If _MouseButton(3) And Not oMB3 Then MB3 = _TRUE
' old mouse buttons
oMB1 = _MouseButton(1)
oMB2 = _MouseButton(2)
oMB3 = _MouseButton(3)
End Sub ' quickmouse
' /////////////////////////////////////////////////////////////////////////////
' Convert integer to string and trim it (because normal Str$ adds spaces)
Function istr$ (MyValue%)
istr$ = _Trim$(Str$(MyValue%))
End Function ' istr$
' /////////////////////////////////////////////////////////////////////////////
' Convert long to string and trim it (because normal Str$ adds spaces)
Function lstr$ (MyValue&)
lstr$ = _Trim$(Str$(MyValue&))
End Function ' lstr$
' /////////////////////////////////////////////////////////////////////////////
' Use to pretty print TRUE and FALSE values.
Function TrueFalse$ (myValue)
If myValue = TRUE Then
TrueFalse$ = "TRUE"
Else
TrueFalse$ = "FALSE"
End If
End Function ' TrueFalse$
' /////////////////////////////////////////////////////////////////////////////
' Does a _PrintString at the specified row+column.
' iRow and iCol are 0-based.
' See also: PrintString1
Sub PrintString0 (iRow As Integer, iCol As Integer, MyString As String)
Dim iX As Integer
Dim iY As Integer
iX = _FontWidth * iCol
iY = _FontHeight * iRow ' (iRow + 1)
_PrintString (iX, iY), MyString
End Sub ' PrintString0
' /////////////////////////////////////////////////////////////////////////////
' DRAW A 2-D RECTANGLE (OUTLINE)
'DrawRectOutline iX, iY, iSizeW, iSizeH, fgColor
Sub DrawRectOutline (iX As Integer, iY As Integer, iSizeW As Integer, iSizeH As Integer, fgColor As _Unsigned Long)
Line (iX, iY)-(iX + (iSizeW - 1), iY + (iSizeH - 1)), fgColor, B ' Draw rectangle outline
End Sub ' DrawRectOutline
' /////////////////////////////////////////////////////////////////////////////
' DRAW A 2-D RECTANGLE (SOLID)
'DrawRectSolid iX, iY, iSizeW, iSizeH, fgColor
Sub DrawRectSolid (iX As Integer, iY As Integer, iSizeW As Integer, iSizeH As Integer, fgColor As _Unsigned Long)
Line (iX, iY)-(iX + (iSizeW - 1), iY + (iSizeH - 1)), fgColor, BF ' Draw a solid rectangle
End Sub ' DrawRectSolid
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' BEGIN RGB COLOR FUNCTIONS #RGB
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function cRed~& ()
cRed = _RGB32(255, 0, 0)
End Function
Function cOrangeRed~& ()
cOrangeRed = _RGB32(255, 69, 0)
End Function ' cOrangeRed~&
Function cDarkOrange~& ()
cDarkOrange = _RGB32(255, 140, 0)
End Function ' cDarkOrange~&
Function cOrange~& ()
cOrange = _RGB32(255, 165, 0)
End Function ' cOrange~&
Function cGold~& ()
cGold = _RGB32(255, 215, 0)
End Function ' cGold~&
Function cYellow~& ()
cYellow = _RGB32(255, 255, 0)
End Function ' cYellow~&
' LONG-HAIRED FRIENDS OF JESUS OR NOT,
' THIS IS NOT YELLOW ENOUGH (TOO CLOSE TO LIME)
' TO USE FOR OUR COMPLEX RAINBOW SEQUENCE:
Function cChartreuse~& ()
cChartreuse = _RGB32(127, 255, 0)
End Function ' cChartreuse~&
' WE SUBSTITUTE THIS CSS3 COLOR FOR INBETWEEN LIME AND YELLOW:
Function cOliveDrab1~& ()
cOliveDrab1 = _RGB32(192, 255, 62)
End Function ' cOliveDrab1~&
Function cLime~& ()
cLime = _RGB32(0, 255, 0)
End Function ' cLime~&
Function cMediumSpringGreen~& ()
cMediumSpringGreen = _RGB32(0, 250, 154)
End Function ' cMediumSpringGreen~&
' ADDED THIS FOR THE GAUGE COLOR:
Function cSpringGreen~& ()
cSpringGreen = _RGB32(0, 255, 160)
End Function ' cSpringGreen~&
Function cCyan~& ()
cCyan = _RGB32(0, 255, 255)
End Function ' cCyan~&
Function cDeepSkyBlue~& ()
cDeepSkyBlue = _RGB32(0, 191, 255)
End Function ' cDeepSkyBlue~&
Function cDodgerBlue~& ()
cDodgerBlue = _RGB32(30, 144, 255)
End Function ' cDodgerBlue~&
Function cSeaBlue~& ()
cSeaBlue = _RGB32(0, 64, 255)
End Function ' cSeaBlue~&
Function cBlue~& ()
cBlue = _RGB32(0, 0, 255)
End Function ' cBlue~&
Function cBluePurple~& ()
cBluePurple = _RGB32(64, 0, 255)
End Function ' cBluePurple~&
Function cDeepPurple~& ()
cDeepPurple = _RGB32(96, 0, 255)
End Function ' cDeepPurple~&
Function cPurple~& ()
cPurple = _RGB32(128, 0, 255)
End Function ' cPurple~&
Function cPurpleRed~& ()
cPurpleRed = _RGB32(128, 0, 192)
End Function ' cPurpleRed~&
Function cDarkRed~& ()
cDarkRed = _RGB32(160, 0, 64)
End Function ' cDarkRed~&
Function cBrickRed~& ()
cBrickRed = _RGB32(192, 0, 32)
End Function ' cBrickRed~&
Function cDarkGreen~& ()
cDarkGreen = _RGB32(0, 100, 0)
End Function ' cDarkGreen~&
Function cGreen~& ()
cGreen = _RGB32(0, 128, 0)
End Function ' cGreen~&
Function cOliveDrab~& ()
cOliveDrab = _RGB32(107, 142, 35)
End Function ' cOliveDrab~&
Function cLightPink~& ()
cLightPink = _RGB32(255, 182, 193)
End Function ' cLightPink~&
Function cHotPink~& ()
cHotPink = _RGB32(255, 105, 180)
End Function ' cHotPink~&
Function cDeepPink~& ()
cDeepPink = _RGB32(255, 20, 147)
End Function ' cDeepPink~&
Function cMagenta~& ()
cMagenta = _RGB32(255, 0, 255)
End Function ' cMagenta~&
Function cBlack~& ()
cBlack = _RGB32(0, 0, 0)
End Function ' cBlack~&
Function cDimGray~& ()
cDimGray = _RGB32(105, 105, 105)
End Function ' cDimGray~&
Function cGray~& ()
cGray = _RGB32(128, 128, 128)
End Function ' cGray~&
Function cDarkGray~& ()
cDarkGray = _RGB32(169, 169, 169)
End Function ' cDarkGray~&
Function cSilver~& ()
cSilver = _RGB32(192, 192, 192)
End Function ' cSilver~&
Function cLightGray~& ()
cLightGray = _RGB32(211, 211, 211)
End Function ' cLightGray~&
Function cGainsboro~& ()
cGainsboro = _RGB32(220, 220, 220)
End Function ' cGainsboro~&
Function cWhiteSmoke~& ()
cWhiteSmoke = _RGB32(245, 245, 245)
End Function ' cWhiteSmoke~&
Function cWhite~& ()
cWhite = _RGB32(255, 255, 255)
'cWhite = _RGB32(254, 254, 254)
End Function ' cWhite~&
Function cDarkBrown~& ()
cDarkBrown = _RGB32(128, 64, 0)
End Function ' cDarkBrown~&
Function cLightBrown~& ()
cLightBrown = _RGB32(196, 96, 0)
End Function ' cLightBrown~&
Function cKhaki~& ()
cKhaki = _RGB32(240, 230, 140)
End Function ' cKhaki~&
Function cEmpty~& ()
'cEmpty~& = -1
cEmpty = _RGB32(0, 0, 0, 0)
End Function ' cEmpty~&
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' END RGB COLOR FUNCTIONS @RGB
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' ################################################################################################################################################################
' BEGIN RGB COLOR ARRAY FUNCTIONS #COLR
' ################################################################################################################################################################
' /////////////////////////////////////////////////////////////////////////////
Sub AddColor (ColorValue As _Unsigned Long, arrColor() As _Unsigned Long)
ReDim _Preserve arrColor(0 To UBound(arrColor) + 1) As _Unsigned Long
arrColor(UBound(arrColor)) = ColorValue
End Sub ' AddColor
' /////////////////////////////////////////////////////////////////////////////
Sub AddColors (ColorValue As _Unsigned Long, arrColor() As _Unsigned Long, HowMany As Long)
Dim iLoop As Integer
For iLoop = 1 To HowMany
AddColor ColorValue, arrColor()
Next iLoop
End Sub ' AddColors
' /////////////////////////////////////////////////////////////////////////////
Sub AddSpectrumColors (arrColor() As _Unsigned Long)
Dim iNum As Integer
iNum = 1
AddColors cRed, arrColor(), iNum
AddColors cOrangeRed, arrColor(), iNum
AddColors cDarkOrange, arrColor(), iNum
AddColors cOrange, arrColor(), iNum
AddColors cGold, arrColor(), iNum
AddColors cYellow, arrColor(), iNum
AddColors cChartreuse, arrColor(), iNum
AddColors cOliveDrab1, arrColor(), iNum
AddColors cLime, arrColor(), iNum
AddColors cMediumSpringGreen, arrColor(), iNum
AddColors cSpringGreen, arrColor(), iNum
AddColors cCyan, arrColor(), iNum
AddColors cDeepSkyBlue, arrColor(), iNum
AddColors cDodgerBlue, arrColor(), iNum
AddColors cSeaBlue, arrColor(), iNum
AddColors cBlue, arrColor(), iNum
AddColors cBluePurple, arrColor(), iNum
AddColors cDeepPurple, arrColor(), iNum
AddColors cPurple, arrColor(), iNum
AddColors cPurpleRed, arrColor(), iNum
End Sub ' AddSpectrumColors
' /////////////////////////////////////////////////////////////////////////////
Sub AddGrayscaleColors (arrColor() As _Unsigned Long)
Dim iNum As Integer
iNum = 1
AddColors cDimGray, arrColor(), iNum
AddColors cGray, arrColor(), iNum
AddColors cDarkGray, arrColor(), iNum
AddColors cSilver, arrColor(), iNum
AddColors cLightGray, arrColor(), iNum
AddColors cGainsboro, arrColor(), iNum
AddColors cWhiteSmoke, arrColor(), iNum
AddColors cWhite, arrColor(), iNum '* 2
AddColors cWhiteSmoke, arrColor(), iNum
AddColors cGainsboro, arrColor(), iNum
AddColors cLightGray, arrColor(), iNum
AddColors cSilver, arrColor(), iNum
AddColors cDarkGray, arrColor(), iNum
AddColors cGray, arrColor(), iNum
End Sub ' AddGrayscaleColors
' ################################################################################################################################################################
' END COLOR ARRAY FUNCTIONS @COLR
' ################################################################################################################################################################
Posts: 823
Threads: 116
Joined: Apr 2022
Reputation:
20
(02-04-2025, 09:14 PM)Petr Wrote: Here is an equalizer program where you can change the sound frequency by pressing + or minus: https://qb64phoenix.com/forum/showthread...558&page=2
Speed change - try this....
Hey Petr, that worked for playback.
Can you think of a way to _record_ at a different speed?
So if you record faster and then play it back at normal speed, it sounds slow, and if you record slow and play it back, it sounds fast?
Posts: 809
Threads: 35
Joined: Apr 2022
Reputation:
54
What code are you using for recording?
The noticing will continue
Posts: 823
Threads: 116
Joined: Apr 2022
Reputation:
20
02-10-2025, 03:03 PM
(This post was last modified: 02-10-2025, 03:59 PM by madscijr.)
(02-10-2025, 02:41 PM)SpriggsySpriggs Wrote: What code are you using for recording? I'm not - haven't figured out how to record yet - but I think it would need to be low level processing one sample at a time in a loop, similar to the approach in Petr's playback example above.
PS: Over the weekend I collected my notes on this, didn't get around to reading through it all or running any code yet, but here's what I have:
From the wiki:
_SNDNEW (function) creates a raw empty sound in memory and returns a LONG handle value for later access.
_SNDOPENRAW (function) opens a new channel to shove _SNDRAW content into without mixing.
SNDRATE (function) returns the sound card sample rate to set _SNDRAW durations.
_SNDRAWLEN (function) returns a value until the _SNDRAW buffer is empty.
_MEMSOUND (function) returns a _MEM block referring to a designated sound handle's memory
SMFL Library - SFML is a sound library that allows users to record and play sounds.
Threads:
QB64PE - Help Me! - What options are there to get audio input? (10/25/2024)
QB64PE - General Discussion - WAV file splitter program? (4/20/2023)
QB64PE issues - Sound playback from embedded data #232 (KingMocker opened on Oct 31, 2022)
QB64PE - Help Me! - Building sounds with _SNDPLAYCOPY? (10/12/2022)
Posts: 809
Threads: 35
Joined: Apr 2022
Reputation:
54
The noticing will continue
|