Forum Rule: Always post complete source code & details to reproduce any issue!
Page 2 of 4 FirstFirst 1 2 3 4 LastLast
Results 26 to 50 of 78

Thread: USB Audio for Teensy 3.0

  1. #26
    Member
    Join Date
    Jan 2014
    Location
    London, UK
    Posts
    76
    Looking forward to seeing this as standard in the Teensy 3.1 Audio library :-)

    Fantastic work!

  2. #27
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,066
    I've started adapting and merging MickMad's code into the core library. Still a work in progress, but this is finally moving forward to becoming a fully supported feature on Teensy and the audio lib.

  3. #28
    Senior Member MickMad's Avatar
    Join Date
    Feb 2013
    Location
    Italy
    Posts
    163
    Paul, that's amazing! Do you have a repo on github I can access to help you?

  4. #29
    Senior Member MickMad's Avatar
    Join Date
    Feb 2013
    Location
    Italy
    Posts
    163
    Nevermind, I see you are pushing stuff on the main Core repo. Perfect.

  5. #30
    Senior Member
    Join Date
    Sep 2013
    Location
    Boston, MA
    Posts
    130
    Quote Originally Posted by PaulStoffregen View Post
    I've started adapting and merging MickMad's code into the core library. Still a work in progress, but this is finally moving forward to becoming a fully supported feature on Teensy and the audio lib.
    For what it's worth, I did spend a few days looking at this before today and have it more-or-less working with the core git code from a few days ago. I was going to work on it a few more days and then publish it, but since you are already on top of it, I figured I should just send what I have in case it is of any use to you.

    The changed files are in the attached ZIP. MickMad's code was pretty good easy to follow. Thanks for your hard work!

    In addition, I made a small change to the AudioPlayMemory (change "private" to "protected" in play_memory.h) class to let me inherit it so I can play back the sound form my sample sketch.
    Attached Files Attached Files
    Last edited by ftrias; 04-13-2016 at 12:41 AM.

  6. #31
    Senior Member MickMad's Avatar
    Join Date
    Feb 2013
    Location
    Italy
    Posts
    163
    Hi all guys,

    @Paul, how are we going to handle the different size of packets for Isochronous endpoints? I'm talking about lines 914 and 923 of usb_dev.c, the usb_memory_rx() function in usb_dev.c, and usb_malloc() function as well.

    edit:
    in my old code, I have this set for lines 914 and 923.

    b->desc = BDT_DESC(MAX_PACKET_BUFFER_SIZE*MAX_PACKET_BUFFER_ SAMPLE_SIZE, ((uint32_t)b & 8) ? DATA1 : DATA0);

    Instead of MAX_PACKET_BUFFER_SIZE*MAX_PACKET_BUFFER_SAMPLE_SI ZE we shall have 180 (45 samples*2 channels*2 bytes).

    USB packets size is still fixed to 64 words*1 byte...
    Last edited by MickMad; 04-13-2016 at 10:38 AM.

  7. #32
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,066
    Quote Originally Posted by MickMad View Post
    @Paul, how are we going to handle the different size of packets for Isochronous endpoints?
    I'm working on that right now... a lot of #ifdef AUDIO_INTERFACE

  8. #33
    Senior Member MickMad's Avatar
    Join Date
    Feb 2013
    Location
    Italy
    Posts
    163
    Quote Originally Posted by PaulStoffregen View Post
    I'm working on that right now... a lot of #ifdef AUDIO_INTERFACE
    LOL I know I also added you to the project page here : https://hackaday.io/project/6787-teensy-usb-audio

  9. #34
    Senior Member
    Join Date
    Sep 2013
    Location
    Boston, MA
    Posts
    130
    In addition to the problem of longer data blocks for isochronous packets, there is also the problem that setup commands on endpoint 0 also sometimes require more that 64 bytes. For example, when you get a command with

    wRequestAndType=0x0122 (set the frequency)

    The data parameter comes after the 64 bytes, according to the spec and my observations with Wireshark.

    If you are going to allow options like multiple frequencies or channels, you'll have to implement this somehow because that's how the parameters are transmitted from the computer to the device.

    I didn't get very far looking at solutions. In the K20 reference manual (section 41.4.5) it addresses oversized packets:

    The packet received may be larger than the negotiated MaxPacket size. Typically, this is caused by a software bug. For DMA overrun errors due to oversized data packets, the USB specification is ambiguous. It assumes correct software drivers on both sides. NAKing the packet can result in retransmission of the already oversized packet data. Therefore, in response to oversized packets, the USB core continues ACKing the packet for non-isochronous transfers.

  10. #35
    Senior Member
    Join Date
    Sep 2013
    Location
    Boston, MA
    Posts
    130
    If I may also request a new feature, it would be volume control. But I think it requires solving the problem with oversized packets on EP0. I did get the host computer to request volume changes by adding the following feature descriptor:

    Code:
    // Feature Descriptor (Table 4.7, p. 43,  USB Device Class Definition for Audio Data Formats 2.0)
    0x0A,			// bLength
    0x24,			// bDescriptorType = CS_INTERFACE
    0x06,			// bDescriptorSubtype = FEATURE_UNIT
    0x31,			// bUnitID
    0x30,			// bSourceID
    0x01,			// bControlSize
    0x03,			// bmaControls(0) (MASTER, VOL)
    0x03,			// bmaControls(1) Left
    0x03,			// bmaControls(2) Right
    0x00,			// iFeature
    bSourceID=0x30 is the terminal id of the "Input Terminal Descriptor". Then the "Output Terminal Descriptor" is modified to take the feature as input, instead of the previous input terminal.

    Code:
    // Output Terminal Descriptor (Table 4.9, p.53, USB Device Class Definition for Audio Devices 2.0)
    0x09,			// bLength
    0x24,			// bDescriptorType = CS_INTERFACE
    0x03,			// bDescriptorSubtype = OUTPUT_TERMINAL
    0x40,			// bTerminalID = OUTPUT_TERMINAL_ID
    0x02, 0x03,		// wTerminalType = HEADPHONES
    0x00,			// bAssocTerminal
    //0x30,			// bCSourceID = INPUT_TERMINAL_ID
    0x31,			// bCSourceID = FEATURE UNIT_ID
    0x00,			// iTerminal

  11. #36
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,066
    I've added the first code which moves streaming audio from the PC into the audio library.

    https://github.com/PaulStoffregen/co...ccb150b0ec603a

    This is still very much a work in progress. Runs with Ubuntu 14.04 and Windows 10. My Mac still doesn't like it. On both Windows and Linux, there's audible distortion once every several seconds, which I suspect is the mismatch in sample rates. The rest of the time it sounds excellent.

    I had to change some headers in the core library, so an update of the audio library is also needed.

    Here's a simple passthrough sketch I've using for testing:

    Code:
    #include <Audio.h>
    
    AudioInputUSB            usb1;           //xy=200,69
    AudioOutputI2S           i2s1;           //xy=365,94
    AudioConnection          patchCord1(usb1, 0, i2s1, 0);
    AudioConnection          patchCord2(usb1, 1, i2s1, 1);
    AudioControlSGTL5000     sgtl5000_1;     //xy=302,184
    
    // the setup routine runs once when you press reset:
    void setup() {                
      AudioMemory(12);
      Serial1.begin(115200);
      Serial1.println("*********************");
      sgtl5000_1.enable();
      sgtl5000_1.volume(0.75);
    }
    
    int count=0;
    
    // the loop routine runs over and over again forever:
    void loop() {
      Serial.println(count++);
      delay(500);               // wait for a second
    }
    Last edited by PaulStoffregen; 04-14-2016 at 11:59 PM.

  12. #37
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,066
    I've added the asynchronous sample rate feedback endpoint and code to transmit a fixed value.

    https://github.com/PaulStoffregen/co...d148d031aef619

    Aside from the obvious lack of a feedback loop, there also seems to be an issue with detecting startup condition and initializing the incoming buffer to half full. That'll be tomorrow's project.....

  13. #38
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,066
    I've now implemented the asynchronous sample rate feedback loop. The control strategy is proportional-integral, where I did some quick fiddling but no really serious tuning effort.

    I also put quite a bit of work into improving the behavior if underruns or overruns do happen. But these really shouldn't happen when the feedback loop is working.

  14. #39
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,066
    I've added AudioOutputUSB, so now there's bidirectional USB audio streaming to/from the audio library.

    https://github.com/PaulStoffregen/cores

    Here's a little program I've been using for testing the Teensy-to-PC direction.

    Code:
    #include <Audio.h>
    #include <SD.h>
    
    AudioPlaySdWav           playWav1;
    AudioOutputUSB           audioOutput;
    AudioOutputAnalog        dac;
    AudioConnection          patchCord1(playWav1, 0, audioOutput, 0);
    AudioConnection          patchCord2(playWav1, 1, audioOutput, 1);
    
    // Use these with the audio adaptor board
    #define SDCARD_CS_PIN    10
    #define SDCARD_MOSI_PIN  7
    #define SDCARD_SCK_PIN   14
    
    void setup() {
      Serial.begin(9600);
      Serial1.begin(115200);
      Serial1.println("=======================");
    
      // Audio connections require memory to work.  For more
      // detailed information, see the MemoryAndCpuUsage example
      AudioMemory(20);
    
      SPI.setMOSI(SDCARD_MOSI_PIN);
      SPI.setSCK(SDCARD_SCK_PIN);
      if (!(SD.begin(SDCARD_CS_PIN))) {
        // stop here, but print a message repetitively
        while (1) {
          Serial.println("Unable to access the SD card");
          delay(500);
        }
      }
    }
    
    void playFile(const char *filename)
    {
      Serial1.print("Playing file: ");
      Serial1.println(filename);
      playWav1.play(filename);
      // A brief delay for the library read WAV info
      delay(5);
      // Simply wait for the file to finish playing.
      while (playWav1.isPlaying()) {
      }
    }
    
    
    void loop() {
      playFile("SDTEST1.WAV");  // filenames are always uppercase 8.3 format
      delay(500);
      playFile("SDTEST2.WAV");
      delay(500);
      playFile("SDTEST3.WAV");
      delay(500);
      playFile("SDTEST4.WAV");
      delay(1500);
    }

  15. #40
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,066
    Mac compatibility is still an issue. I'm working on it...

    If anyone tries AudioInputUSB, where the Mac sends to Teensy, you probably also need an AudioOutputUSB running to make it work. They're supposed to be able to run independently, but Apple's doing some implicit sample rate stuff (maybe), even though we have the explicit feedback endpoint. Eventually I'm going to get to the bottom of this and make each able to run independently on Macs, but for now you probably need both if you want to try this early code with a Mac.

  16. #41
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,794
    Hi,

    great development. I assume, that boards.txt needs to be edited ? What do i have to add ?

  17. #42
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,794
    I just tried it and added
    Code:
    teensy31.menu.usb.audio=Audio
    teensy31.menu.usb.audio.build.usbtype=USB_AUDIO
    teensy31.menu.usb.audio.fake_serial=teensy_gateway
    But now i get this ("Teensy MIDI" and code 10 in device manager) :
    Click image for larger version. 

Name:	AudioCode10.png 
Views:	209 
Size:	39.5 KB 
ID:	6990

    i guess i have done something wrong..

    is it a problem with this:

    Code:
      #define PRODUCT_ID        0x0485
    which is "midi" ?


    Edit:
    Ok, i unplugged the Teensy, removed "Teensy MIDI" and plugged it in again.

    Now it is titled "Teensy Audio", but still code 10.

    Code:
    Das E/A-Gerät ist falsch konfiguriert, oder die Konfigurationsparameter für den Treiber sind falsch.
    
    C0000182
    ..must be something like "I/O deivce wrong configuration or wrong parameters for the driver" in English...
    Last edited by Frank B; 04-17-2016 at 06:29 PM. Reason: add details

  18. #43
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,066
    Opps, looks like something I did yesterday broke usb audio for Windows.

    I'm looking into it now....

  19. #44
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,066
    Ok, I fixed several problems. I believe Mac and Windows may finally both be working.

    https://github.com/PaulStoffregen/cores

    Here what I just tested...

    Linux PC to Teensy: working
    Linux Teensy to PC: working
    Mac PC to Teensy: working
    Mac Teensy to PC: working
    Windows PC to Teensy: working
    Windows Teensy to PC: maybe working?

    On Windows, my drivers are screwed up so the speaker and line-out aren't working (Teensy is the only way to get sound out right now, crazy!), so all I can do at the moment is watch the little level meter in the sound control panel to see if Teensy is sending.

    So far, I haven't managed to test simultaneous input and output. I don't do a lot of serious sound work with computers, so I'm not even sure what should really be done to test this. Anyone have ideas?

    The main issue on Windows was incorrect delay parameters in the descriptor, which apparently are fine when Windows believe the isync endpoint is adaptive, but causes the "code 10" error when the endpoint is asynchronous.

    The main problem on Mac was not transmitting (silence) on the unused input endpoint when it's enabled. Apparently Apple expects data to be arriving if it's enabled the input endpoint, and even if you're not using it, OSX refuses to send to the output endpoint. Seems strange, but it's true.

    If anyone has good sound setup with Windows, please give this a try. Windows is the system I use the least, so I really depend on help finding Windows issues.

  20. #45
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,794
    Works !!!

    To use it with the prop-shield:

    Code:
    #include <Audio.h>
    
    AudioInputUSB            usb1;           //xy=200,69
    AudioMixer4              mixer1;         //xy=324,161
    AudioOutputAnalog        dac1;           //xy=365,94
    AudioConnection          patchCord1(usb1, 0, mixer1, 0);
    AudioConnection          patchCord2(usb1, 1, mixer1, 1);
    AudioConnection          patchCord3(mixer1, dac1);
    
    #define PROP_AMP_ENABLE    5
    
    // the setup routine runs once when you press reset:
    void setup() { 
    
      //Start Amplifier
      pinMode(PROP_AMP_ENABLE, OUTPUT);
      digitalWrite(PROP_AMP_ENABLE, HIGH); 
      
      AudioMemory(12);
      Serial1.begin(115200);
      Serial1.println("*********************");
    
    }
    
    int count=0;
    
    // the loop routine runs over and over again forever:
    void loop() {
      Serial.println(count++);
      delay(500);               // wait for a second
    }

  21. #46
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,432
    Quote Originally Posted by Frank B View Post
    Works !!!

    To use it with the prop-shield:

    Code:
    #include <Audio.h>
    
    AudioInputUSB            usb1;           //xy=200,69
    AudioMixer4              mixer1;         //xy=324,161
    AudioOutputAnalog        dac1;           //xy=365,94
    AudioConnection          patchCord1(usb1, 0, mixer1, 0);
    AudioConnection          patchCord2(usb1, 1, mixer1, 1);
    AudioConnection          patchCord3(mixer1, dac1);
    This is for output. Now, add also AudioCard and add SGTL5000 AudioInput.
    (sorry, I could not resist. I know prop card and audiocard do not work together (I2S-RXD0 is occupied by SPI-CLK), or is there a workaround?)

  22. #47
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,794
    Isn't is possible to use pin 14 for the prop shield ? Ok, requires a short wire instead of a header pin.. but that should'nt be a problem.
    Perhaps Paul can add a jumper for a future "REV 2" of the prop-shield ?

  23. #48
    Senior Member
    Join Date
    Sep 2013
    Location
    Boston, MA
    Posts
    130
    Quote Originally Posted by PaulStoffregen View Post
    The main problem on Mac was not transmitting (silence) on the unused input endpoint when it's enabled. Apparently Apple expects data to be arriving if it's enabled the input endpoint, and even if you're not using it, OSX refuses to send to the output endpoint. Seems strange, but it's true.
    I also observed this when I worked on MickMad's code. If the Mac turns on the microphone (sets the microphone's alternate interface to 1) it expects data or else it will hang.

    If anyone has good sound setup with Windows, please give this a try. Windows is the system I use the least, so I really depend on help finding Windows issues.
    I can confirm that the code from today works on my PC tested using Audacity. Both input and output seem to work just fine with the sketch below. I also tested recording and playing back at the same time (using Audacity's "Software Playthrough" setting in the Recording settings) and it worked on my Mac, Linux and PC. Curiously, the Mac also has a "Hardware Playthrough" setting not found on Linux or the PC, but it doesn't work.

    Code:
    #include <Audio.h>
    
    AudioSynthWaveformSine   wav1;
    AudioOutputUSB           audioOutput; 
    AudioConnection          patchCord5(wav1, 0, audioOutput, 0);
    
    AudioInputUSB            usbin;    
    AudioOutputI2S           out1;
    AudioConnection          patchCord1(usbin, 0, out1, 0);
    AudioConnection          patchCord2(usbin, 1, out1, 1);
    AudioControlSGTL5000     sgtl5000_1;  
    
    int led = 13;
    
    // the setup routine runs once when you press reset:
    void setup() {
      AudioMemory(12);
      pinMode(led, OUTPUT);
      wav1.frequency(220);
      wav1.amplitude(1);
      sgtl5000_1.enable();
      sgtl5000_1.volume(0.50);
    }
    
    int count=0;
    int ledon = 0;
    
    // the loop routine runs over and over again forever:
    void loop() {
      ledon ^= 1; // flip bit
      digitalWrite(led, ledon);
      delay(500);
    }

  24. #49
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,432
    Quote Originally Posted by Frank B View Post
    Isn't is possible to use pin 14 for the prop shield ? Ok, requires a short wire instead of a header pin.. but that should'nt be a problem.
    Perhaps Paul can add a jumper for a future "REV 2" of the prop-shield ?
    I still have hope that T4 will be compatible with prop shield and use of I2S
    Last edited by WMXZ; 04-18-2016 at 07:45 PM.

  25. #50
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,794
    Yeah, but since audio-shield and prop-shield use the same pin...how should that work ?
    As said above, it needs only a wire... even with the existing T 3.2

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •