Audio adapter and library noob frustration

Status
Not open for further replies.

GGmmGG

Member
Ok kind of stuck at the starting block. At an impasse for way too long. Have a dedicated 2.0 handling MIDI from DAW to effects processor kicking so much butt, the Audio Board would open up so much right now.
Can get 3.1 to Blink and SerialMonitor sketches working, read 3.3v on the volume header with multimeter.
ToneSweep seems to run, but no sound heard in headphones.
SDCardTest gives "SD card is not connected or unusable :-(" everytime with several different SanDisk Ultra Class 10 SD cards.
WavFile Player => "Unable to access the SD card".
Arduino 1.6.1 & Td 1.23, Windows 8. Help, probably a simple step missed, or maybe I killed it? Have a nice weekend.
 
If you are just trying examples and having no fun then it must be your connections, can you post a picture of how you have connected the Audio Adapter to the Teensy 3.1?
 
like so:
t3t3s.jpg
 
Your extra lores pic doesn't make me sure that I can see whether or not that thing is even soldered appropriately, or are those pins meant to be interference fit?

Is it fully soldered?

Maybe the problem is Arduino 1.6.1 - one of the versions I didn't even try, till recently 1.6.3 was the only recent version I didn't hear anything stupid about.
 
Not soldered, going for the 'interference fit' as robsoles called it. Firing up the iron now will report back.
 
The holes in Teensy are a bit too accommodating (as they should be) to try interference fit with regular header pins, I expect you are going to have much more joy with soldered connections - as I must assume you were hoping to separate the boards at whim; it is a pity (another assumption that) you do not have header sockets (https://www.pjrc.com/store/socket_14x1.html) to solder into the Audio Adapter instead.
 
Ooooook, it's alive. In my defense the headers were soldered in to the audio adapter, but yea now it's all soldered. PlaySynthMusic and SDCardTest responding, this is fantastic. Thanks and thanks.
 
Man this thing kicks major ---. Would you know how to write midi clock to usbMIDI? I see a few posts about this around still confused by sysex lengths and format. RealTimeSystem is working on reading the incoming clock messages from PC, is it possible to go the other way, tried usbMIDI.sendSysEx(realTime) or usbMIDI.sendRealTime(Clock),for example, send bytes, binary, hex or dec on usb? Using the buttons/Transmit Example code from Paul's td midi page and some switches. It would be nice to send these 3-4 messages to DAW/PC with 'transport' buttons or footswitches while recording or tempo tapping.
 
The usbMIDI stack on Teensy seems to be based off the MIDI library v2.6, which did not support midi clock, transport commands, etc. Unlike status codes 8* to E* which put the channel in the low nibble, F* is 16 separate and often unrelated commands. So effectively for F* status bytes, only F0 = sysex is supported right now on the usbMIDI implementation. Adding them is not especially hard, but has a backward compat risk because the internal result codes use only the high nibble of the status. One option would be to deprecate the old status codes and use the full byte status codes, like MIDI library 4.x (and i think 3.2) do.

See http://www.midi.org/techspecs/midimessages.php
 
The usbMIDI stack on Teensy seems to be based off the MIDI library v2.6, which did not support midi clock, transport commands, etc. Unlike status codes 8* to E* which put the channel in the low nibble, F* is 16 separate and often unrelated commands. So effectively for F* status bytes, only F0 = sysex is supported right now on the usbMIDI implementation. Adding them is not especially hard, but has a backward compat risk because the internal result codes use only the high nibble of the status. One option would be to deprecate the old status codes and use the full byte status codes, like MIDI library 4.x (and i think 3.2) do.

See http://www.midi.org/techspecs/midimessages.php

Just curious if this is still the case with usbMIDI on the teensy. Been trying to get the teensy to act as midi master clock, but not having any luck receiving midi clock (0xF8) messages. In the core there's a function for sendRealTime( data ) written, and it looks like it should work, but I'm not getting anything from any of my listeners. Tried MIDI-OX as well as max/msp. Anyone ever get this tow work? Have a project based around this, would really suck if this actually isn't an option. Here's my sketch if it makes any difference, about as simple as it gets :

Code:
void setup() {
}

void loop() {

  usbMIDI.sendRealTime( (uint32_t)0xF8 );

  delay(10);

	while (usbMIDI.read()) {
		// ignore incoming messages
	}

}
 
Also, just looking more closely at the function in the core midi code it looks like it doubles up the real time message from one byte to, two duplicate bytes :

Code:
uint32_t data = ( (type & 0xFF) | ((type << 8) & 0xFF00) );

where type is the single byte real time midi message, after data type verification, followed by:
Code:
usb_midi_write_packed(data);

I'm assuming this isn't a mistake... but anyone know why this is necessary? Or is this the problem?
 
I'm assuming this isn't a mistake... but anyone know why this is necessary?

MIDI over USB uses a different format, where messages are packed into fixed-size 32 bit words (with some of the info duplicated), rather than traditional MIDI over serial using variable-size 1 or 3 byte messages.
 
Last edited:
Ah, figured it had something to do with that. Thanks Paul. Am I to assume then that the usbMIDI.sendRealTime() function works properly then? Just something wrong on my end probably?
 
Am I to assume then that the usbMIDI.sendRealTime() function works properly then?

At least a few people have used it successfully.

Truth is, I don't personally do much MIDI stuff. I really depend on feedback from people like you on these less commonly used MIDI features.
 
That's all I was looking for, gives me a reason to keep trying to sort out my problem, will post when I find out what I'm doing wrong in case anyone else is going down the wrong path.

Truth is, I don't personally do much MIDI stuff. I really depend on feedback from people like you on these less commonly used MIDI features.

Thanks as always for your quick and helpful responses Paul, allows us to keep moving forward with our projects. Makes all the difference with the Teensy platform.
 
Found it!!

This is a first for me, but it's actually a problem in the core function. The first line of the sendRealTime() function reads :

Code:
uint32_t data = ( (type & 0xFF) | ((type << 8) & 0xFF00) );

but it should actually just be :
Code:
 uint32_t data = ( (0x0F) | ((type << 8) & 0xFF00) );

See usb midi class compliant manual pg. 17 for the single byte header. Had to do some digging through the usb_desc.c files to find the cable number, which I don't totally understand, but it appears to be 0 in the case of the teensy board. The example in the manual in table 4.2 is for cable 3, so instead of 0F, it shows 0x3F. In our case we want 0x0F. ( I tried both obviously until it worked.)

Maybe someone changed this at some point? Or maybe it never fully worked, no big deal. This is the fix for me in the short term, if there's a reason why this shouldn't be changed in the next update, please let me know what I've done wrong.

I changed the sendRealTime() function to the following :

Code:
void sendRealTime(uint32_t type) __attribute__((always_inline)) {
		//uint32_t data = ( (type & 0xFF) | ((type << 8) & 0xFF00) );
		switch (type) {
			case 0xF8: // Clock
			case 0xFA: // Start
			case 0xFC: // Stop
			case 0xFB: // Continue
			case 0xFE: // ActiveSensing
			case 0xFF: // SystemReset
				usb_midi_write_packed( 0x000F | (type << 8) );
				break;
			default: // Invalid Real Time marker
				break;
		}
	}

Doesn't seem much need to create the temporary variable 'data' with the oring and anding. I get that it's a safe way to ensure the message is of a certain type, but the case structure does that right after, so it seems a little redundant. In addition, I would want my midi clocks to be executed with as little overhead as possible to keep the timing more accurate. Maybe this doesn't help, but either way, the above function works.
 
Last edited:
Didn't hear a response from anyone on this issue... just want to make sure it gets included in the next build if possible?
 
Good work sir, but in my experience if you want something included you should check it is formatted to style guidelines and submit a pull on GitHub.

It makes a busy man's life easier!
 
Good work sir, but in my experience if you want something included you should check it is formatted to style guidelines and submit a pull on GitHub.

It makes a busy man's life easier!

Pretty much a noob when it comes to that kind of stuff... anywhere you can point me to so I can learn the proper way? Would be much appreciated!
 
Status
Not open for further replies.
Back
Top