I’m downloading waveforms (samples) from MIDI devices, those shapes need to go through MIDI so they are encoded in various weird ways. I can decode the data to get for example
So i got my 256 decoded bytes, now i’d like to start with displaying it in an AudioThumbnail for example. I know i need to convert my linear data that i have (it’s in a MemoryBlock) to an AudioSampleBuffer with specified channels, sample rate, bit depth etc. But how. Also how do i convert a void * to a const int ** and not crash everything (this is what i get when i need to write() to a WavAudioFormat() writer).
I imagine i should use the AudioData::Converter class ? Could someone hint me how to do that for a MemoryBlock assuming i have 16bit samples in it mono ? and put it in one of JUCE’s containers so i can use it for AudiThumbnail or other Audio* classes ?
AudioDataConverters::convertInt16LEToFloat? (Assuming the arch is LE) Pretty simple, just pass it two pointers to preallocated blocks and the number of samples. Personally I would use HeapBlocks as you can just provide each one with a number of samples, you don’t have to fiddle around with sizeof operators.
You can then create an AudioSampleBuffer from this block using the relevant constructor. You’ll probably need an intermediate array to hold the pointers to the start of each channel something like:
You could do this with a member HeapBlock if you need to keep the samples around for reasons such as adding them on a background thread but make sure the HeapBlock’s that contain the actual sample data are also members.
Once the samples are in an AudioSampleBuffer you can just add them to the thumbnail using AudioThimbnail::addBlock(), make sure to call reset() first though.
The other way to do it would be to write the AudioSampleBuffer to a WavAudioFormat and then use that as the InputSource to the AudioThumbnail.
Another way would be to use my AudioSampleBufferAudioFormat to be able to read directly from the AudioSampleBuffer into the AudioThumbnail::setSource() method.
I was looking at the AudioDataConverters but i notices that i should no use them anymore:
that’s why i was asking about the AudioData class and how to deal with that, especially what should i pass to the template, i’ll try to work with that today a bit more, but it’s all very complicated and any mistakes i make cause crashes and that’s just annoying Pointer math is always complicated.
What kind of sample data is it? Remember that AudioThumbnail draws a line between the minimum and maximum samples within a block so isn’t really good for levels where you have more than 1 pixel per sample, you’ll end up with a load of dots rather than lines joining the samples.
When I’ve had to do super zoomed in stuff in the past I’ve had to write an extra section in CachedWindow::drawChannel that draws lines between samples and places dots on the samples if the number of samples per pixel is less than 1.
Also what have you set the sourceSamplesPerThumbnailSample to? If you only have 256 samples this should definitely be 1.
Have you tried this with a longer piece of audio? Perhaps even just loop the 256 samples you have a few hundred times to get a couple of seconds worth (you could even just loop calls to addBlock), at least then you’ll know if you’re getting the correct output. I always tend to keep my test sample open in Audacity when designing thumbnails so you can keep an eye out for things such as general shape, offsets, clipping etc.
On the other hand if you are only ever going to be dealing with 256 samples you might find it easier to just create your own component that draws a line between the samples.
Well i get some results that are close to the actual shape when I set the type to Uint8 i think the samples are unsigned int, and i can’t set that as a source type as UInt16 cause there isn’t one like that. The other thing is there is no samplerate in those shapes so setting that is tricky i can’t set it to 44100 and draw one second cause i won’t get anything drawn. I set the sourceSamplesPerThumbnailSample to 1 yes.
I am not sure if it’s correct, my problem was with reading bytes from the message (i started at a byte to far, and everything was messed up cause i was reading the samples in the wrong order). With my Uint16 class it looked at least like the shape i wanted, but you are right about the zero point. What should i look at in the class to correct this, the resolution member ?
[quote]The ROM Waveshapes are 12 bit two’s complement (to match the VS), but the User Waveshapes (97 – 128) can
be a full 16 bits.[/quote]
That quote suggests a few things:
The User and ROM waveshapes are encoded in a slightly different format
At least the ROM shapes are signed. [it says 12 bit two’s complement]
The ROM shapes using 12 bit signed values is quite an odd choice indeed! I’m not sure that there’s an ‘easy’ way to convert those (without getting your hands dirty manipulating bits on each sample, of course). Unless of course they’re saying that the numbers have a range of 12bits but actually use the normal top bit of 16 for the sign…
If the ROM shapes are signed, I’d assume that the user shapes would be too… but then I’d not really expect the whole 12 bit thing to be done, so who knows!
It looks like they’ve tried to make it as complicated as possible!