interrupts,freq, buffer stream

08 Dec 2011

Hi,

Ok I now have a circular buffer for the reversing code and the nice mbed usb audio code, I have not managed to figure out how to add it into the main reversing code, but I am still faced with this problem of a clicking noise in the audio.

What I think I have noticed is that at a slower interrupt ticking time and frequency the audio clicking is less, it seems less at a interrupt time of 31.25us with a freq of 32000khz compared to 20.83us with a freq of 48000khz

Does anybody have any idea how to fix the audio clicking noise in the code thanks.

// Hello World example for the USBMIDI library (circular buffer)

#include "mbed.h"
#include "USBAudio.h"
#include "CircBuffer.h"

Serial pc(USBTX, USBRX);

// frequency: 48 kHz
#define FREQ 32000

// 1 channel: mono
#define NB_CHA 1

// length computed: each ms, we receive 48 * 16bits ->48 * 2 bytes. as there is one channel, the length will be 48 * 2 * 1
#define LENGTH_AUDIO_PACKET 32 * 2 * 1

#define USR_POWERDOWN    (0x104)

int semihost_powerdown() {
    uint32_t arg;
    return __semihost(USR_POWERDOWN, &arg);
}
 

// USBAudio
USBAudio USBaudio(FREQ, NB_CHA, 0x71aa, 0x7500);

// speaker connected to the AnalogOut output. The audio stream received over USb will be sent to the speaker
AnalogOut speaker(p18);

// ticker to send data to the speaker at the good frequency
Ticker tic;

// circular buffer where will be stored data to be sent to the speaker
CircBuffer<int16_t> cbuf(LENGTH_AUDIO_PACKET);

// previous value sent to the speaker
uint16_t p_val = 0;

// function executed each 1/FREQ s
void tic_handler() {
    int16_t val;
    float speaker_value;
    unsigned short PlaySample;


    if (cbuf.available() >= 1) {
        cbuf.dequeue(&val);
        speaker_value = (float)val;

        // speaker_value between 0 and 65535
        speaker_value +=  32768.0;

        // adjust according to current volume
        speaker_value *= USBaudio.getVolume();
    } else {
        speaker_value = p_val;
    }
    p_val = speaker_value;
    
    /* ADAMGR: Inserting my May 30th reversing code here!!! */
  {
    static const unsigned int   BufferSize = 1920 * 8 ;
    static unsigned short Buffer[BufferSize];
    
    static int           Index = 0;
    static int           Direction = 1;
    static int           Playback = false;
    static int           ChunkSize = BufferSize;
 
    unsigned short       ReadSample;
 
    /* Default PlaySample to the current sample from USB buffer. */
    PlaySample =  speaker_value;

    
    
    /* Read out the sample from the buffer to be played back */
    if (Playback)
    {
        PlaySample = Buffer[Index];
    }
    
    /* Obtain current audio sample from the USB buffer. */
    ReadSample = (unsigned short)speaker_value;
    
    /* Record the sample into the buffer right where a space was freed up from the PlaySample read above */
    Buffer[Index] = ReadSample;
    
     /* Increment the buffer pointer */
    Index += Direction;
    
    /* Check to see if the chunk has been filled */
    if (Index < 0)
    {
        /* Now have a chunk to be played back */
        Playback = true;
        /* Reverse the direction of playback and recording */
        Direction *= -1;//Direction;
        Index = 0;
    }
    else if (Index >= ChunkSize)
    
    

    {
       /* Now have a chunk to be played back */
        Playback = true;
        /* Reverse the direction of playback and recording */
        Direction *= -1;//Direction;
        Index = ChunkSize - 1;
    }
  }
  

    // send value to the speaker
    speaker.write_u16((uint16_t)PlaySample);
}

int main() {
    int16_t buf[LENGTH_AUDIO_PACKET/2];
    
    semihost_powerdown();

    // attach a function executed each 1/FREQ s
    tic.attach_us(tic_handler, 1000000.0/(float)FREQ);

    while (1) {
        // read an audio packet
        USBaudio.read((uint8_t *)buf);

        // put buffer in the circ buffer
        for(int i = 0; i < LENGTH_AUDIO_PACKET/2; i++) {
            cbuf.queue(buf[i]);
        }
    }
}
09 Dec 2011

My guess is that you hear the transistions of the reverse samples stitched together or you are overshooting your buffer on playback (that is your playback goes beyond the end of the sample and it plays back one or more samples of the start/end of the circular buffer)

You could try to print a list of sample values with adresses which are played back and see if there are any sudden 'jumps' in the values.

09 Dec 2011

Gert van der Knokke wrote:

My guess is that you hear the transistions of the reverse samples stitched together or you are overshooting your buffer on playback (that is your playback goes beyond the end of the sample and it plays back one or more samples of the start/end of the circular buffer)

You could try to print a list of sample values with adresses which are played back and see if there are any sudden 'jumps' in the values.

Gert,

I was wondering if it could be spikes tho as well? like what was seen on the adc of mbed.

Do you think this code will do the trick for printing the audio to the console or is it not up to the job,

thanks,

Philips.

NOTE: Just printing out samples in reverse printf("%d: %d\r\n", Index, PlaySample); wait(0.2f);

at 96khz it becomes a lot louder?

How do I use the audio code and the serial pc can you do that http://mbed.org/handbook/SerialPC

If you understand what I am asking is

"Your mbed Microcontroller can appear on your computer as a serial port."

My mbed is appearing on the pc as a usb speaker and not connected by the same cable that is used for programming, can I still print values to the console down the usb cable that I am using to use the mbed as a usb speaker?

which is connected like this

http://mbed.org/media/uploads/samux/img_0080.jpg

I try to explain myself better I know sometimes people don't know what it is that I am asking sometimes. This is the problem I am faced with, how am I supposed to debug projects and code like this?

10 Dec 2011

The 'standard' USB port does indeed appear as two devices, one is the flash storage and the other is a simulated serial port. With a simple terminal program you can monitor the output. Depending on the OS you need to select the right serial port and baud rate.

If you get this up and running then you add some markers in the output by which you can see what is the start and end of the buffer (or when it rolls over) and compare the current and former sample that is being sent to the DAC. If they are very different you will hear a click or pop. You can then try to smooth out the values by calculating the average of those values before sending them to the DAC.

AFAIK the DAC does not suffer from the same 'glitches' the ADC part has.

10 Dec 2011

Gert van der Knokke wrote:

The 'standard' USB port does indeed appear as two devices, one is the flash storage and the other is a simulated serial port. With a simple terminal program you can monitor the output. Depending on the OS you need to select the right serial port and baud rate.

If you get this up and running then you add some markers in the output by which you can see what is the start and end of the buffer (or when it rolls over) and compare the current and former sample that is being sent to the DAC. If they are very different you will hear a click or pop. You can then try to smooth out the values by calculating the average of those values before sending them to the DAC.

AFAIK the DAC does not suffer from the same 'glitches' the ADC part has.

I guess you did not understand what I was trying to explain, as I try to say I am not using the 'standard' USB port that is next to the Transistors , I am using the D+ and D- to my understand I think I can only use one mode.

or are you saying

I can use the http://mbed.org/handbook/USBSerial publish by Samuel Mokrani and the and the usb audio code

http://mbed.org/handbook/USBAudio

To my understanding I can not have the mbed function as a usb audio device and virtual serial port at the same time, I see this could be possible by Bluetooth

which I am not using the usb B female jack that ship with the mbed, I use p31 (D+), p32 (D-) and GND.

10 Dec 2011

Gert van der Knokke wrote:

The 'standard' USB port does indeed appear as two devices, one is the flash storage and the other is a simulated serial port. With a simple terminal program you can monitor the output. Depending on the OS you need to select the right serial port and baud rate.

If you get this up and running then you add some markers in the output by which you can see what is the start and end of the buffer (or when it rolls over) and compare the current and former sample that is being sent to the DAC. If they are very different you will hear a click or pop. You can then try to smooth out the values by calculating the average of those values before sending them to the DAC.

AFAIK the DAC does not suffer from the same 'glitches' the ADC part has.

I guess you did not understand what I was trying to explain, as I try to say I am not using the 'standard' USB port that is next to the Transistors , I am using the D+ and D- to my understand I think I can only use one mode.

or are you saying

I can use the http://mbed.org/handbook/USBSerial publish by Samuel Mokrani and the and the usb audio code

http://mbed.org/handbook/USBAudio

To my understanding I can not have the mbed function as a usb audio device and virtual serial port at the same time, I see this could be possible by Bluetooth

which I am not using the usb B female jack that ship with the mbed,

10 Dec 2011

Will this code work yes or no??? both together like this???

But Gert you talk of stuff that is just not possible for me to do, lack the knowledge.

USBSerial echo


#include "mbed.h"
#include "USBAudio.h"
#include "CircBuffer.h"

#include "USBSerial.h"

//Virtual serial port over USB
USBSerial serial;
Serial pc(USBTX, USBRX);

int main(void) {
    uint8_t buf[128];
    while(1)
    {
        serial.scanf("%s", buf);
        serial.printf("recv: %s", buf);
        pc.printf("recv: %s\r\n", buf);
    }
}

// Hello World example for the USBMIDI library (circular buffer)



Serial pc(USBTX, USBRX);

// frequency: 48 kHz
#define FREQ 32000

// 1 channel: mono
#define NB_CHA 1

// length computed: each ms, we receive 48 * 16bits ->48 * 2 bytes. as there is one channel, the length will be 48 * 2 * 1
#define LENGTH_AUDIO_PACKET 32 * 2 * 1

#define USR_POWERDOWN    (0x104)

int semihost_powerdown() {
    uint32_t arg;
    return __semihost(USR_POWERDOWN, &arg);
}
 

// USBAudio
USBAudio USBaudio(FREQ, NB_CHA, 0x71aa, 0x7500);

// speaker connected to the AnalogOut output. The audio stream received over USb will be sent to the speaker
AnalogOut speaker(p18);

// ticker to send data to the speaker at the good frequency
Ticker tic;

// circular buffer where will be stored data to be sent to the speaker
CircBuffer<int16_t> cbuf(LENGTH_AUDIO_PACKET);

// previous value sent to the speaker
uint16_t p_val = 0;

// function executed each 1/FREQ s
void tic_handler() {
    int16_t val;
    float speaker_value;
    unsigned short PlaySample;


    if (cbuf.available() >= 1) {
        cbuf.dequeue(&val);
        speaker_value = (float)val;

        // speaker_value between 0 and 65535
        speaker_value +=  32768.0;

        // adjust according to current volume
        speaker_value *= USBaudio.getVolume();
    } else {
        speaker_value = p_val;
    }
    p_val = speaker_value;
    
    /* ADAMGR: Inserting my May 30th reversing code here!!! */
  {
    static const unsigned int   BufferSize = 1920 * 8 ;
    static unsigned short Buffer[BufferSize];
    
    static int           Index = 0;
    static int           Direction = 1;
    static int           Playback = false;
    static int           ChunkSize = BufferSize;
 
    unsigned short       ReadSample;
 
    /* Default PlaySample to the current sample from USB buffer. */
    PlaySample =  speaker_value;

    
    
    /* Read out the sample from the buffer to be played back */
    if (Playback)
    {
        PlaySample = Buffer[Index];
    }
    
    /* Obtain current audio sample from the USB buffer. */
    ReadSample = (unsigned short)speaker_value;
    
    /* Record the sample into the buffer right where a space was freed up from the PlaySample read above */
    Buffer[Index] = ReadSample;
    
     /* Increment the buffer pointer */
    Index += Direction;
    
    /* Check to see if the chunk has been filled */
    if (Index < 0)
    {
        /* Now have a chunk to be played back */
        Playback = true;
        /* Reverse the direction of playback and recording */
        Direction *= -1;//Direction;
        Index = 0;
    }
    else if (Index >= ChunkSize)
    
    

    {
       /* Now have a chunk to be played back */
        Playback = true;
        /* Reverse the direction of playback and recording */
        Direction *= -1;//Direction;
        Index = ChunkSize - 1;
    }
  }
  

    // send value to the speaker
    speaker.write_u16((uint16_t)PlaySample);
}

int main() {
    int16_t buf[LENGTH_AUDIO_PACKET/2];
    
    semihost_powerdown();

    // attach a function executed each 1/FREQ s
    tic.attach_us(tic_handler, 1000000.0/(float)FREQ);

    while (1) {
        // read an audio packet
        USBaudio.read((uint8_t *)buf);

        // put buffer in the circ buffer
        for(int i = 0; i < LENGTH_AUDIO_PACKET/2; i++) {
            cbuf.queue(buf[i]);
        }
    }
}
10 Dec 2011

Hi,

No it's not possible to use USBSerial and USBAudio at the same time. You can plug two usb cables (one on the usual usb port to flash the mbed and one on D+ and D- for USBAudio) and use printf on the usual virtual serial port.

Sam

10 Dec 2011

Is that completely safe confirmation from the mbed team would be nice, is that not to much for the Transistors, what does that work out at 10v

11 Dec 2011

will something like this work where only 8 integers are read and perhaps 8 written from the buffer, I wanted the circularBuffer like this at first but just could not understand how to write it into my code ,taken from worrall playback code

http://mbed.org/users/d_worrall/programs/playback/lvgoa5/docs/main_8cpp_source.html

// Hello World example for the USBMIDI library (circular buffer)

#include "mbed.h"
#include "USBAudio.h"
#include "CircBuffer.h"

Serial pc(USBTX, USBRX);

// frequency: 48 kHz
#define FREQ 32000

// 1 channel: mono
#define NB_CHA 1

// length computed: each ms, we receive 48 * 16bits ->48 * 2 bytes. as there is one channel, the length will be 48 * 2 * 1
#define LENGTH_AUDIO_PACKET 32 * 2 * 1

#define USR_POWERDOWN    (0x104)

int semihost_powerdown() {
    uint32_t arg;
    return __semihost(USR_POWERDOWN, &arg);
}
 

// USBAudio
USBAudio USBaudio(FREQ, NB_CHA, 0x7186, 0x7507);

// speaker connected to the AnalogOut output. The audio stream received over USb will be sent to the speaker
AnalogOut speaker(p18);

// ticker to send data to the speaker at the good frequency
Ticker tic;

// circular buffer where will be stored data to be sent to the speaker
CircBuffer<int16_t> cbuf(LENGTH_AUDIO_PACKET);

// previous value sent to the speaker
uint16_t p_val = 0;

// function executed each 1/FREQ s
void tic_handler() {
    int16_t val;
    float speaker_value;
    unsigned short PlaySample;


    if (cbuf.available() >= 1) {
        cbuf.dequeue(&val);
        speaker_value = (float)val;

        // speaker_value between 0 and 65535
        speaker_value +=  32768.0;

        // adjust according to current volume
        speaker_value *= USBaudio.getVolume();
    } else {
        speaker_value = p_val;
    }
    p_val = speaker_value;
    
    /* ADAMGR: Inserting my May 30th reversing code here!!! */
  {
   // static const unsigned int   BufferSize = 20 * 640;
    
    static const unsigned int circularBuffer[4096]; 
    static unsigned short Buffer[circularBuffer];
    
    static int           Index = 0;
    static int           Direction = 1;
    static int           Playback = false;
    static int           ChunkSize =  circularBuffer;
 
    unsigned short       ReadSample = 0;
 
    /* Default PlaySample to the current sample from USB buffer. */
    PlaySample =  speaker_value;

    
    
    /* Read out the sample from the buffer to be played back */
    void Playback(void)
    {
        PlaySample = Buffer[Index];
        // send value to the speaker
    speaker.write_u16((uint16_t)PlaySample,  ReadSample, 8);   

        
        ReadSample, 8);      
        //Pointer fun :-)
        ReadSample += 8;
        ReadSample &=  (unsigned short)speaker_value;
       // theta -= 8;
       Index -= 8:
    }
    
    /* Obtain current audio sample from the USB buffer. */
   // ReadSample = (unsigned short)speaker_value;
    
    /* Record the sample into the buffer right where a space was freed up from the PlaySample read above */
    Buffer[Index] = ReadSample;
    
     /* Increment the buffer pointer */
    Index += Direction;
    
    /* Check to see if the chunk has been filled */
    if (Index < 0)
    {
        /* Now have a chunk to be played back */
        Playback = true;
        /* Reverse the direction of playback and recording */
         ReadSample, 8;      
        //Pointer fun :-)
        ReadSample += 8;
        ReadSample &= 0xfff;
       // theta -= 8;
       Index -= 8:
        Direction *= -1;//Direction;
      //  Index = 0;
    }
    else if (Index >= ChunkSize)
    
    

    {
       /* Now have a chunk to be played back */
        Playback = true;
        /* Reverse the direction of playback and recording */
        Direction *= -1;//Direction;
        Index = ChunkSize - 1;
    }
  }
  
   for(int j = 0; j < 4096; ++j){          //upon interrupt generation
        circularBuffer[j] = 0;              //clear circular buffer
  

    // send value to the speaker
   // speaker.write_u16((uint16_t)PlaySample);
}

int main() {
    int16_t buf[LENGTH_AUDIO_PACKET/2];
    
    semihost_powerdown();

    // attach a function executed each 1/FREQ s
    tic.attach_us(tic_handler, 1000000.0/(float)FREQ);

    while (1) {
        // read an audio packet
        USBaudio.read((uint8_t *)buf);

        // put buffer in the circ buffer
        for(int i = 0; i < LENGTH_AUDIO_PACKET/2; i++) {
            cbuf.queue(buf[i]);
        }
    }
}

It don't work still not sure how to write it in:)