NotePlayer problem

Hello folks
Using Xojo2013r1 in Windows 7
Elementary code as per the Language Reference -
NotePlayer1.PlayNote(60, 100) works fine.
NotePlayer1.PlayNote(60*256, 100) should produce the same note but in fact it produces a very low rumbling note.
NotePlayer1.PlayNote(60.5*256, 100) produces nothing I can hear. This should be a quarter tone above C.

Can anyone suggest why this does not work?

(What I really would like is to specify the frequency in cycles per second. I am surprised that Xojo does not offer this. Or have I missed it?)

This is a long-standing issue. To sum it up, micro-tones don’t work on Windows. It’s a deficiency of the underlying framework. Instead, it takes the low-order byte. So your second statement is actually playing at frequency 0, which is a bit more than 8 hertz (too low to hear, but has harmonics that are audible). The second, meanwhile, is playing frequency 128, which is just out of the range that a NotePlayer can handle.

This really needs to be fixed in the docs if it can’t be fixed in the software.

Thanks, JA. So I can’t do it.
Very disappointing. I have done this in old, much simpler forms of BASIC but Xojo can’t do it! Too many fancy instrument simulations and not enough basic sound versatility.

Sorry to step in but I think that maybe there is some unfortunate name for the first parameter of the PlayNote() method.

As documentation states (see Notes) the “pitch” must to be intended as a note (as for MIDI standard) and not as a frequency so the value 60=middle C, 61=middle C# and so on.

As you can see from the examples the framework it is using MIDI synth as player engine.
MIDI only know notes and not frequencies.


“MIDI only know notes and not frequencies.”
Yes, I see what you mean, Maurizio. But does this mean that all those instrument simulations are built into MIDI and not constructed by Xojo? Because I imagine they can not be done withour overtones which must use frequencies.

Older, simpler BASIC langauages have used wave functions and frequencies to produce computed sounds. Not easy but certainly more versatile. Considering the increasing complexity of Xojo I am surprised that it does not offer this as well as the MIDI functions. Surely of benefit to game writers?

I don’t think that Xojo as an internal sound generation engine but it uses OS system services.
I don’t have tried myself but I think that you can connect an external synth to your computer and after setting the OS to map MIDI events to external equipment you can use Xojo to play anything able to understand MIDI.
A software synth it is available in every system today.
Xojo is no meant to (re)create a software synth but Xojo can be use to create a software synth: it is a compiler…

Simple BASIC is gone and actual systems are very different…

Seems to me like in order to use more advanced features you need to declare and use the specific system routines. MacOSLib for example seems to deliver no Core Audio declares yet, and for the other systems I don’t know.

And the note player, offering only methods to play a note, is very limited in its implementation of the system MIDI routines. The pitch bend message (which would give at least the opportunity to change the pitch of all notes on the same channel) ist not accessible. But that’s still to limited if you need to fine tune one single note. In that case, only the system routines (like Core Audio) would help.

As Xojo goes for multi-platform compatibility, all those routines would have to be set up for each system individually. The note player probably therefore delivers only the methods common to all systems.

Maybe Xojo implements only what was seen as a bare minimum to have in an generic application.
A serious musical application can’t be multiplatform because it is adhering to a single API.
None of the OS platforms that Xojo supports has a common view of multimedia.
Win, Mac e Linux on the multimedia side are different planets.

But the same applies also for other more basic things like, for example, threads and IPC.

Thank you folks, I get the picture.
I thought that a generic application would at simplest level generate a specified frequency but apparently it is not possible to apply this generically. I will think again.

You know, I would love it if somebody would take the time to create a set of declares or a simple plugin that access the AVFoundation tools in Apple. Then all this sound stuff would be accessable to all of us. The coders at Xojo don’t want to do it. I’d do it if I knew C or whatever plugin coders use

I’d like to see declares to AVFoundation too. I’ve tried it but not sure how to instantiate AV objects, only NS ones. Maybe with QTKit out this stuff can be easier to build in. Anyways, if you know how to build your waveform a brute force strategy is to write wav format files which are pretty raw. This example makes a 8bit, mono, 44.1khz, 2 second file then opens and plays it.

[code]//Pushbutton to create and write test.wav file on Desktop
Sub Action()

dim waveData As MemoryBlock = genWaveData
dim fileData As MemoryBlock = createWaveFileData(waveData)

dim f As FolderItem = SpecialFolder.Desktop.Child(“test.wav”)
dim bs As BinaryStream = BinaryStream.Create(f, true)

End Sub

Function genWaveData() As MemoryBlock

dim res As integer = 44100 //hz
dim samplesCount As integer = 88200 //gen 2 seconds of samples

dim m As new MemoryBlock(samplesCount)

dim scaler As double = 6.28318 / res
dim lastSample As integer = samplesCount - 1
dim a As double

for i As integer = 0 to lastSample
a = i * scaler
m.UInt8Value(i) = 127 + 32sin(440a) + 16sin(882a) + 8sin(1761a) //sine sum

return m

End Function

Function createWaveFileData(waveData As MemoryBlock) As MemoryBlock
dim m As new MemoryBlock(44 + waveData.Size) //header is 44 bytes
m.LittleEndian = true

m.UInt32Value(0) = &h46464952 //“RIFF”
m.Int32Value(4) = m.Size - 8
m.UInt32Value(8) = &h45564157 //“WAVE”

m.UInt32Value(12) = &h20746d66 //"fmt "
m.UInt32Value(16) = 16 //fmt chunck size
m.UInt16Value(20) = 1 //PCM
m.UInt16Value(22) = 1 //mono
m.UInt32Value(24) = 44100 //sample rate
m.UInt32Value(28) = 44100 //44100 * 1 * 8 / 8 //SampleRate * NumChannels * BitsPerSample/8 //ByteRate
m.UInt16Value(32) = 1 //1 * 8 / 8 //NumChannels * BitsPerSample/8 //block align
m.UInt16Value(34) = 8 //bits per sample

m.UInt32Value(36) = &h61746164 //“data”
m.UInt32Value(40) = waveData.Size //waveData.Size * 1 * 8/8 //NumSamples * NumChannels * BitsPerSample/8
m.StringValue(44, waveData.Size) = waveData //copy in samples

return m

//format references
//https:/ /
//http:/ /
End Function

//Pushbutton to open and play test.wav
Sub Action()

dim s As Sound = SpecialFolder.Desktop.Child(“test.wav”).OpenAsSound

if s = nil then break


End Sub[/code]