QBSound Updated For 0.15 (PLAY, SOUND and BEEP Tool)
QBSound Updated For 0.15 (PLAY, SOUND and BEEP Tool)
Nothing new in this update as it's just a fix for the new version of FB (0.15). The new headers broke QBSound and I thought I should fix it before one of the three users on the planet complain. :-)
The code can be found here: QBSound_04_Dec_05.zip
QBSound uses MIDI to not only give FB a PLAY command but to also expand the original QB PLAY command (polyphonic, different instruments). For those who don't love MIDI the way it should be, I am working on a version using OpenAL (the prove of concept is done) but without the polyphonic and multi-timbre abilities.
QBSound is very much a work in progress (although not so much right now, ah thejoys of teaching!) and I am open to all suggestions, ideas, and improvements. Currently it only works in Windows (Fedora and my Audigy don't like one another).
The code can be found here: QBSound_04_Dec_05.zip
QBSound uses MIDI to not only give FB a PLAY command but to also expand the original QB PLAY command (polyphonic, different instruments). For those who don't love MIDI the way it should be, I am working on a version using OpenAL (the prove of concept is done) but without the polyphonic and multi-timbre abilities.
QBSound is very much a work in progress (although not so much right now, ah thejoys of teaching!) and I am open to all suggestions, ideas, and improvements. Currently it only works in Windows (Fedora and my Audigy don't like one another).
-
- Posts: 785
- Joined: May 28, 2005 9:19
- Location: Finland
This is very useful. Thanks.
I changed the sound command so that it can accept an optional volume argument, and I added some commands so that two sounds can be played with no gap between them.
I changed the sound command so that it can accept an optional volume argument, and I added some commands so that two sounds can be played with no gap between them.
Code: Select all
'----------------------------------------------------------------
dim shared __sound_device as HMIDIOUT
dim shared as integer __sound_note, __sound_octave, __sound_channel
sub __sound_open
__sound_channel = 0
__sound_device = midiOpen()
midiSetMainVolume __sound_device, 127, 2
end sub
sub __sound_close
if __sound_channel then
midiNoteOff __sound_device, __sound_note, __sound_octave, __sound_channel
midiSetPitchBend __sound_device, 0, 64, __sound_channel
end if
midiClose __sound_device
__sound_channel = 0
end sub
sub __sound (ByVal frequency as single, ByVal Duration as single, _
ByVal Voice as integer = midiQBDefaultSound, _
byval volume as integer = midiMaxVolume )
'added R.Keeling 26 March 05
dim f as single
dim x as integer
dim w as single
dim k as single
dim s as single
dim msb as integer
dim lsb as integer
f = frequency
'we are only going to allow sound frequency between 10 and 14000 hertz
'the average human with GOOD hearing can hear between 20-20000 hertz
'so this isn't too bad
'
'besides, after 5000 its almost all the same :-) annoying
if f < 10 then f = 10
if f > 14000 then f = 14000
if volume < 0 then volume = 0
if volume > midiMaxVolume then volume = midiMaxVolume
s = f / midiNoteZeroFreq
'LRBN is the Log of the Ration Between Two Notes, i.e. the Log(n)
x = int(log(s)/LRBN)
w = RBN^x
k = 64 * ((s - w)/(w*SRBNM))
msb = int(k) + 64
lsb = int((k - int(k)) * 127)
dim t as double
dim as integer note, octave, channel
note = x mod 12
octave = (x-note)/12
if __sound_channel = 2 then channel = 4 else channel = 2
' Do the midi stuff.
midiSetInstrument __sound_device, Voice, channel
midiSetPitchBend __sound_device, lsb, msb, channel
if __sound_channel then
midiNoteOff __sound_device, __sound_note, __sound_octave, __sound_channel
midiSetPitchBend __sound_device, 0, 64, __sound_channel
end if
midiNoteOn __sound_device, note, octave, volume, channel
__sound_note = note
__sound_octave = octave
__sound_channel = channel
t = timer + duration
do while t > timer
sleep 2
loop
end sub
sub Sound (ByVal frequency as single, ByVal Duration as single, _
ByVal Voice as integer = midiQBDefaultSound, _
byval volume as integer = midiMaxVolume )
__sound_open
__sound frequency, duration, voice, volume
__sound_close
end sub
'-----------------------------------------------------------------
' Demo.
#include once "inc/qbsound.bi"
option explicit
dim as single freq
'' soft
sound 220, 1, 56, 64
'' loud
sound 220, 1, 56
sleep 100
__sound_open
for freq = 100 to 200 step .5
__sound freq, .1, midiSynth_voice, 100
next
__sound_close
@Refine: That's very cool. I'll add it to the package this weekend.
@axipher: If you just want to play wav files, look at some of the sound libraries out there (OpenAL, FMOD, etc) or system specific tools (like the Windows API).
@Nodtveidt: OK, I'll bite. :-) It is possible... but very difficult. I could see it being feasible for a non-polyphonic instrument like a horn or sax. In addition, perhaps with a lot of Fourier work, single polyphonic instruments like a piano might be possible but I don't even want to think about the nightmare it would be to do it. But in the end I don’t see a full blown wav to midi converter (e.g. take a wave of Beethoven’s 9th and get a midi) anytime soon either.
@axipher: If you just want to play wav files, look at some of the sound libraries out there (OpenAL, FMOD, etc) or system specific tools (like the Windows API).
@Nodtveidt: OK, I'll bite. :-) It is possible... but very difficult. I could see it being feasible for a non-polyphonic instrument like a horn or sax. In addition, perhaps with a lot of Fourier work, single polyphonic instruments like a piano might be possible but I don't even want to think about the nightmare it would be to do it. But in the end I don’t see a full blown wav to midi converter (e.g. take a wave of Beethoven’s 9th and get a midi) anytime soon either.
technically, my college project can convert from wav to midi (or should be able to be modified to do so when its finished). It can already identify simultaneuos notes playing and convert them to midi note values! At the moment it just plays the lowest note back to you using my custom piano generator (uses wav samples with FMOD)
Hello all.
I am trying to get a (I'd think is a) simple example to work using the lib posted in the first post. Here
http://www.randy.keeling.com/files/qbso ... dec_05.zip
It compiles - and NO midi errors print out.
I expect the above example to send MIDI controller #10 with a value of 66 on MIDI channel 1, to the midi port set as default in Windows Sound and Audio Devices control panel applet.
I looked in the inc files and see the midiSetControlChange
Its as follows - to save you the trouble of looking for the sub (located in 'qbsound_winmidi.bi' btw) here is the sub:
Any hints would be greatly appreciated.
P.S. Im using MIDIOX / MIDI YOKE to monitor midi activity and see none at all. And the supplied example with the lib runs fine - so its not that I have the includes in the wrong spot.
Thanks,
Mark
I am trying to get a (I'd think is a) simple example to work using the lib posted in the first post. Here
http://www.randy.keeling.com/files/qbso ... dec_05.zip
Code: Select all
#include once "qbsound.bi"
option explicit
dim Channel as integer
dim device as HMIDIOUT
dim ControlNumber as integer
dim Value as integer
device = MidiOpen
Channel = 1
ControlNumber = 10
Value = 127
'Send the Controller
midiSetControlChange(device, ControlNumber, Value, Channel)
PRINT midiGetError()
MidiClose device
SLEEP
I expect the above example to send MIDI controller #10 with a value of 66 on MIDI channel 1, to the midi port set as default in Windows Sound and Audio Devices control panel applet.
I looked in the inc files and see the midiSetControlChange
Its as follows - to save you the trouble of looking for the sub (located in 'qbsound_winmidi.bi' btw) here is the sub:
Code: Select all
sub midiSetControlChange (ByVal device as HMIDIOUT, _
ByVal ControlNumber as integer, _
ByVal Value as integer = 127, _
ByVal Channel as integer = 0)
'added R.Keeling 24 March 05
midiError = ""
if channel < midiMinChannel or channel > midiMaxChannel then
midiError = "Channel Out Of Range: " + STR$(Channel)
exit sub
end if
if Value < 0 or Value > 127 then
midiError = "Value in Set Key Pressure Out Of Range: " + STR$(Value)
exit sub
end if
if ControlNumber < 0 or ControlNumber > 127 then
midiError = "Control Number Out Of Range: " + STR$(ControlNumber)
exit sub
end if
midiSend device, midiCONTROLLER_CHANGE + Channel, ControlNumber, Value
end sub
P.S. Im using MIDIOX / MIDI YOKE to monitor midi activity and see none at all. And the supplied example with the lib runs fine - so its not that I have the includes in the wrong spot.
Thanks,
Mark
I don't know. I put this together to emulate the PLAY command using MIDI and I had assumed just a bare-bones sound card set-up. The other functions were ported for the sake of completeness.
Someone with a better understanding of MIDI and API will have to step in, but where are you getting the value of 66 from? Do mean you are sending 66 on controler (an external device) on channel 1 to the MIDI mapper controller?
I think this might be over my head at the moment.... oh for summer to get here! :-)
Someone with a better understanding of MIDI and API will have to step in, but where are you getting the value of 66 from? Do mean you are sending 66 on controler (an external device) on channel 1 to the MIDI mapper controller?
I think this might be over my head at the moment.... oh for summer to get here! :-)
Well a midi controller has 2 parameters - the controller # (0-127 - 7 = volume, 10=Pan, 91 = reverb send.. etc.) and a value. These are also channel dependant much like a midi note is- but theres no length involved.Keeling wrote:I don't know. I put this together to emulate the PLAY command using MIDI and I had assumed just a bare-bones sound card set-up. The other functions were ported for the sake of completeness.
Someone with a better understanding of MIDI and API will have to step in, but where are you getting the value of 66 from? Do mean you are sending 66 on controler (an external device) on channel 1 to the MIDI mapper controller?
I think this might be over my head at the moment.... oh for summer to get here! :-)
So a midi note on has - Frequency, velocity, channel
A controller has - controller, value, channel
Maye Ill try using MIDI SEND instead of that specific sub - it seems its used much through out the lib(s)
But I was wondering if I have to convert from HEX - or if its done in the libs somewhere.?
Thanks,
Mark
OK, I thing I get it. As I said, I'm not a MIDI guru... just a MIDI hack.
Have you tried
Have you tried
Code: Select all
midiSend device, midiCONTROLLER_CHANGE + Channel, 10, 66
Sort ofKeeling wrote:OK, I thing I get it. As I said, I'm not a MIDI guru... just a MIDI hack.
Have you triedCode: Select all
midiSend device, midiCONTROLLER_CHANGE + Channel, 10, 66
It seems very unstable - some times its on ch 15 - other times its on 4, 5,6,7 & 12 - at the same time. But NEVER on ch 1.
The lib must be hosed... was this QB lib, verified working before you converted for FB?? - Im thinking it wasn't working from the get go to begin with..??
But thanks for your help - I just wish I could find something to simplify what seems like it should be a simple task... *scratches head*
Thanks again,
Mark