guitar effect reverse

08 May 2011

http://mbed.org/users/vsergeev/programs/echo_effect/5zrah/

How do I go about making the mbed do a reverse effect, I have been able to google this so far

you have to make the D/A converter read the memory backwards. You have to sync the read and writes to the memory to make sure they don't collide.

Anybody know how to do this or where I might get more info or help on how I would do it with mbeds LPC1768

12 May 2011

How does this reverse effect work? Do you press a pedal to start recording and then release it to stop the recording and then playback the recorded data backwards? I guess while you are playing back one sample in reverse you can be recording another sample to be played back in reverse once the previous reverse playback is completed?

13 May 2011

Adam Green wrote:

How does this reverse effect work? Do you press a pedal to start recording and then release it to stop the recording and then playback the recorded data backwards? I guess while you are playing back one sample in reverse you can be recording another sample to be played back in reverse once the previous reverse playback is completed?

nope I think it works like this record mic fill the buffer.. loop write to analog out

lol

gotta use two ints I, J but err how mbed is supposed to tell which is the end of sample and which is the beginning I don't know

Still learning I don't even know the C language yet

like

Digitech TimeBender

Reverse Mode Description Categories: Delay Modes, Feature Descriptions, Reverse Written By: TimeBender

The Reverse delay type records the input signal in “chunks” with a length equal to the current delay time setting, and then plays these sound segments back in reverse. Unlike other reverse effects in which the chunks are arbitrary, the TimeBender starts chunks at note onsets where possible in order to avoid having notes cross chunk boundaries. When using Reverse, the Mix knob starts to attenuate (reduce) the dry signal when you turn the knob up, so you can adjust the wet/dry mix.

Hint: If you mute your guitar for the currently set delay time, then the TimeBender will resync at the start of the next thing you play making it really easy to do call/answer effects.

http://www.youtube.com/watch?v=T0bZsXmKWEA

http://www.youtube.com/watch?v=hHRk2HO-kpo

or like sweep:)

http://www.metadecks.org/software/sweep/

so that means it records and plays back in reverse, continuously no pedal push and if not for the fraction of a second it would be real time or how ever long you set the buffer or delay. it plays back reverse sounds in a instant, their cool like me:)

13 May 2011

Maybe you could read out a value from the buffer for playback and then store the newly recorded sample into the buffer where the data was just read out. Each time you finish recording a chunk, you could just reverse the direction of the buffer walk. I have included a sample that fakes ascending values for the recorded data and when played back, it will print out the values in reverse.

#include <mbed.h>

// Boolean types
#define TRUE 1
#define FALSE 0


int main(void)
{
    unsigned char        ReadSample = 0xFF;
    // Indices to track where the playback and recording should take place in the
    // audio buffer.  The recording can occur one sample behind the current playback
    // index since it is no longer required.
    int                  Index = 0;
    // Reverse the direction the buffer is walked between each iteration to save memory
    int                  Direction = 1;
    // Have audio to playback
    int                  Playback = FALSE;
    // The amount of data to be recorded before starting reverse playback
    // NOTE: Probably want this to be configured at runtime via a knob, etc.
    int                  ChunkSize = 256;
    // Allocate a buffer to be used for the audio recording
    // NOTE: Just showing a 20k buffer in a static for this example
    static const size_t  BufferSize = 20 * 1024;
    static unsigned char Buffer[BufferSize];
    
    // Infinite loop of recording and reverse playback
    for (;;)
    {
        unsigned char PlaySample;

        // Read out the sample from the buffer to be played back
        if (Playback)
        {
            PlaySample = Buffer[Index];
            // NOTE: Just printing out samples in reverse
            printf("%d: %d\r\n", Index, PlaySample);
            wait(0.2f);
        }
        
        // Obtain current audio sample from the A/D converter.
        // NOTE: I am just faking these values in this sample with an incrementing value
        ReadSample++;
        
        // 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;
            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;
            Index = ChunkSize - 1;
        }
    }
}
14 May 2011

Adam Green wrote:

Maybe you could read out a value from the buffer for playback and then store the newly recorded sample into the buffer where the data was just read out. Each time you finish recording a chunk, you could just reverse the direction of the buffer walk. I have included a sample that fakes ascending values for the recorded data and when played back, it will print out the values in reverse.

#include <mbed.h>

// Boolean types
#define TRUE 1
#define FALSE 0


int main(void)
{
    unsigned char        ReadSample = 0xFF;
    // Indices to track where the playback and recording should take place in the
    // audio buffer.  The recording can occur one sample behind the current playback
    // index since it is no longer required.
    int                  Index = 0;
    // Reverse the direction the buffer is walked between each iteration to save memory
    int                  Direction = 1;
    // Have audio to playback
    int                  Playback = FALSE;
    // The amount of data to be recorded before starting reverse playback
    // NOTE: Probably want this to be configured at runtime via a knob, etc.
    int                  ChunkSize = 256;
    // Allocate a buffer to be used for the audio recording
    // NOTE: Just showing a 20k buffer in a static for this example
    static const size_t  BufferSize = 20 * 1024;
    static unsigned char Buffer[BufferSize];
    
    // Infinite loop of recording and reverse playback
    for (;;)
    {
        unsigned char PlaySample;

        // Read out the sample from the buffer to be played back
        if (Playback)
        {
            PlaySample = Buffer[Index];
            // NOTE: Just printing out samples in reverse
            printf("%d: %d\r\n", Index, PlaySample);
            wait(0.2f);
        }
        
        // Obtain current audio sample from the A/D converter.
        // NOTE: I am just faking these values in this sample with an incrementing value
        ReadSample++;
        
        // 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;
            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;
            Index = ChunkSize - 1;
        }
    }
}

Ok cool great thanks was reading assembly language book in another world at the moment, I have to add a picofarad capacitor from gnd to which ever analog in pin I pick, before I connenct a microphone right? how do I calculate what the picofarad capacitor should be, I measure the output I get on my multimeter of the current and volts from the microphone:)

15 May 2011

I am using this mic for testing has a 1.27 current reading at 20k what is it that generally needs to be done when connecting a mic to the mbed like this?

/media/uploads/mbed2f/photo0751.jpg

15 May 2011

Why not just start with Vsergeev's echo effect project that you linked to in your first post and then modify the code to get a reverse effect? Vsergeev's circuit is documented at http://dev.frozeneskimo.com/embedded_projects/audio_echo_effect

15 May 2011

Adam Green wrote:

Why not just start with Vsergeev's echo effect project that you linked to in your first post and then modify the code to get a reverse effect? Vsergeev's circuit is documented at http://dev.frozeneskimo.com/embedded_projects/audio_echo_effect

because I am cheap and that is gonna cost me money:) can sombody tell me please, the mic has amp in it and it volt output is zero or 0.01, and that also means I don't learn anything:)

16 May 2011

The VDD/2 bias IC2B I don't understand that.

16 May 2011
16 May 2011

hahaah ok the schematics are confusing, the electric mic positive pole audio is line up with audio in on the negative pole in picture of lm358 but

it is suppose to be the GND of the mic lined up with the negative pole of lm358 right and then the VDD/2 bias is line up to positive pole right?

20 May 2011

I sorted the mic but I am just taking guesses at this

#include <mbed.h>

// Boolean types
#define TRUE 1
#define FALSE 0



#define MAX_DELAY   15000

/* ADC for the microphone/input, DAC for the speaker/output */
AnalogIn mic(p19);
AnalogOut speaker(p18);

int main(void)
{

unsigned short ReadSample[MAX_DELAY];  
    //unsigned         ReadSample = 0xFF; 
    // Indices to track where the playback and recording should take place in the
    // audio buffer.  The recording can occur one sample behind the current playback
    // index since it is no longer required.
    int                  Index = 0;
    // Reverse the direction the buffer is walked between each iteration to save memory
    int                  Direction = 1;
    // Have audio to playback
    int                  Playback = FALSE;
    // The amount of data to be recorded before starting reverse playback
    // NOTE: Probably want this to be configured at runtime via a knob, etc.
    int                  ChunkSize = 256;
    // Allocate a buffer to be used for the audio recording
    // NOTE: Just showing a 20k buffer in a static for this example
    //static const size_t  BufferSize = 20 * 1024;
    //static unsigned char Buffer[BufferSize];
    
    int delay = MAX_DELAY;
    
    int i;
    /* Fill up the sample buffer first */
    for (i = 0; i < delay; i++)
        ReadSample[i] += mic.read_u16();

    
    // Infinite loop of recording and reverse playback
    for (;;)
    {
        unsigned char PlaySample;

        // Read out the sample from the buffer to be played back
        if (Playback)
        {
            PlaySample =  ReadSample[i];
            // NOTE: Just printing out samples in reverse
            printf("%d: %d\r\n", Index, PlaySample);
            wait(0.2f);
            speaker.write_u16( PlaySample);
        }
        
        // Obtain current audio sample from the A/D converter.
        // NOTE: I am just faking these values in this sample with an incrementing value
        ReadSample[i]++;
        
        // Record the sample into the buffer right where a space was freed up from the PlaySample read above
      //  Buffer[Index] = ReadSample[i];
        
        // 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;
            Index = 0;
             speaker.write_u16(PlaySample);
        }
        else if (Index >= ChunkSize)
        {
            // Now have a chunk to be played back
            Playback = TRUE;
            // Reverse the direction of playback and recording
            Direction *= -1;
            Index = ChunkSize - 1;
             speaker.write_u16(PlaySample);
            
            
        }
    }
}
22 May 2011

Jesus christ is one of you going to help god for once in your life and finish the code please, I can't code my way out of a paper bag.

23 May 2011

Ha ha getting close lol

#include <mbed.h>

// Boolean types
#define TRUE 1
#define FALSE 0

AnalogIn mic(p19);
AnalogOut speaker(p18);

int main(void)
{
    unsigned char        ReadSample = 0xFF;
    // Indices to track where the playback and recording should take place in the
    // audio buffer.  The recording can occur one sample behind the current playback
    // index since it is no longer required.
    int                  Index = 0;
    // Reverse the direction the buffer is walked between each iteration to save memory
    int                  Direction = 1;
    // Have audio to playback
    int                  Playback = FALSE;
    // The amount of data to be recorded before starting reverse playback
    // NOTE: Probably want this to be configured at runtime via a knob, etc.
    int                  ChunkSize = 256;
    // Allocate a buffer to be used for the audio recording
    // NOTE: Just showing a 20k buffer in a static for this example
    //unsigned const size_t  BufferSize = 20 * 1024;
     //unsigned short Buffer[BufferSize];
    //unsigned short const size t Buffersize = 20 * 1024;
    int16_t Buffer[5000];
    //unsigned short Buffer;
    
    
    for(int i=0; i<5000; i++) {
        Buffer[i] = mic.read_u16()&0xFF;
        wait_ms(1);
//for (Buffer =0; Buffer<1024; Buffer++){
//Buffer =  mic.read_u16()&0xFF;
    

    
    // Infinite loop of recording and reverse playback
    for (;;)
    {
        unsigned char PlaySample;

        // Read out the sample from the buffer to be played back
        if (Playback)
        {
            PlaySample = Buffer[Index];
            // NOTE: Just printing out samples in reverse
            printf("%d: %d\r\n", Index, PlaySample);
            speaker.write_u16(PlaySample);
            wait(0.2f);
        }
        
        // Obtain current audio sample from the A/D converter.
        // NOTE: I am just faking these values in this sample with an incrementing value
        //mic.read_u16().PlaySample;
        ReadSample++;
        
        // Record the sample into the buffer right where a space was freed up from the PlaySample read above
        Buffer[Index] = ReadSample;
         // (Buffer[Index] = ReadSample += mic.read_u16());
        
        // 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;
            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;
            Index = ChunkSize - 1;
        }
    }
}
27 May 2011

Does anybody know what could be wrong I am just getting a clipping sound in speaker, I changed the chunk size to a smaller value and still nothing.

#include <mbed.h>
 
// Boolean types
#define TRUE 1
#define FALSE 0
/* ADC for the microphone/input, DAC for the speaker/output */
AnalogIn mic(p19);
AnalogOut speaker(p18);
 
// Allocate a buffer to be used for the audio recording
static const size_t   BufferSize = 10 * 1024;
static unsigned short Buffer[BufferSize];
 
int main(void)
{
    unsigned short        ReadSample = 0xFFFF;
    // Indices to track where the playback and recording should take place in the
    // audio buffer.  The recording can occur one sample behind the current playback
    // index since it is no longer required.
    int                  Index = 0;
    // Reverse the direction the buffer is walked between each iteration to save memory
    int                  Direction = 1;
    // Have audio to playback
    int                  Playback = FALSE;
    // The amount of data to be recorded before starting reverse playback
    // NOTE: Probably want this to be configured at runtime via a knob, etc.
    int                  ChunkSize = 256;
    
    // Infinite loop of recording and reverse playback
    for (;;)
    {
        unsigned short PlaySample;
 
        // Read out the sample from the buffer to be played back
        if (Playback)
        {
            PlaySample = Buffer[Index];
            speaker.write_u16(PlaySample);
            wait(0.2f);
        }
        
        // Obtain current audio sample from the A/D converter.
        // NOTE: I am just faking these values in this sample with an incrementing value
        ReadSample = mic.read_u16();    
        
        // 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 = -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 = -Direction;
            Index = ChunkSize - 1;
        }
    }
}
28 May 2011

I edited wait 0.2f out I now get the mic output to speaker but no reverse effect

#include <mbed.h>
 
// Boolean types
#define TRUE 1
#define FALSE 0
/* ADC for the microphone/input, DAC for the speaker/output */
AnalogIn mic(p19);
AnalogOut speaker(p18);
 
// Allocate a buffer to be used for the audio recording
static const size_t   BufferSize = 10 * 1024;
static unsigned short Buffer[BufferSize];
 
int main(void)
{
    unsigned short        ReadSample = 0xFFFF;
    // Indices to track where the playback and recording should take place in the
    // audio buffer.  The recording can occur one sample behind the current playback
    // index since it is no longer required.
    int                  Index = 0;
    // Reverse the direction the buffer is walked between each iteration to save memory
    int                  Direction = 1;
    // Have audio to playback
    int                  Playback = FALSE;
    // The amount of data to be recorded before starting reverse playback
    // NOTE: Probably want this to be configured at runtime via a knob, etc.
    int                  ChunkSize = 256;
    
    // Infinite loop of recording and reverse playback
    for (;;)
    {
        unsigned short PlaySample;
 
        // Read out the sample from the buffer to be played back
        if (Playback)
        {
            PlaySample = Buffer[Index];
            speaker.write_u16(PlaySample);
           // wait(0.2f);
        }
        
        // Obtain current audio sample from the A/D converter.
        // NOTE: I am just faking these values in this sample with an incrementing value
        ReadSample = mic.read_u16();    
        
        // 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 = -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 = -Direction;
            Index = ChunkSize - 1;
        }
    }
}
29 May 2011

Corrected the Direction *= -1; it still does not work. Is this on your part Adam is it even possible to do it this way, my friend checked the code and even he says it looks correct.

#include <mbed.h>
 
// Boolean types
#define TRUE 1
#define FALSE 0

//#define NUM_SAMPLES   15000
/* ADC for the microphone/input, DAC for the speaker/output */
AnalogIn mic(p19);
AnalogOut speaker(p18);
 
// Allocate a buffer to be used for the audio recording
static const size_t   BufferSize = 10 * 1024;
static unsigned short Buffer[BufferSize];
 //   int16_t Buffer[5000];
 //unsigned short Buffer[NUM_SAMPLES];
 
 
int main(void)
{

 //int i;
   // for (i = 0; ; )
    
   { unsigned short        ReadSample = 0xFFFF;
    // Indices to track where the playback and recording should take place in the
    // audio buffer.  The recording can occur one sample behind the current playback
    // index since it is no longer required.
    int                  Index = 0;
    // Reverse the direction the buffer is walked between each iteration to save memory
    int                  Direction = 1;
    // Have audio to playback
    int                  Playback = FALSE;
    // The amount of data to be recorded before starting reverse playback
    // NOTE: Probably want this to be configured at runtime via a knob, etc.
    int                  ChunkSize = 50;
    
    // Infinite loop of recording and reverse playback
    for (;;)
    {
        unsigned short PlaySample;
 
        // Read out the sample from the buffer to be played back
        if (Playback)
        {
            PlaySample = Buffer[Index];
            speaker.write_u16(PlaySample);
            //i = (i+0) % NUM_SAMPLES;
            
           //wait(0.2f);
        }
        
        // Obtain current audio sample from the A/D converter.
        // NOTE: I am just faking these values in this sample with an incrementing value
        ReadSample = mic.read_u16();    
        
        // 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;
            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;
            Index = ChunkSize - 1;
        }
    }
}
}
30 May 2011

You could try this version which bumps the size of the buffer up and maximizes the chunk size to use all of this buffer. I also added a wait_us(50); at the top of the for() loop to reduce the sampling to something less than 20kHz.

#include <mbed.h>
 
// Boolean types
#define TRUE 1
#define FALSE 0

/* ADC for the microphone/input, DAC for the speaker/output */
AnalogIn mic(p19);
AnalogOut speaker(p18);
 
// Allocate a buffer to be used for the audio recording
static const size_t   BufferSize = 15 * 1024;
static unsigned short Buffer[BufferSize];
 
 
int main(void)
{
    unsigned short        ReadSample = 0xFFFF;
    // Indices to track where the playback and recording should take place in the
    // audio buffer.  The recording can occur one sample behind the current playback
    // index since it is no longer required.
    int                  Index = 0;
    // Reverse the direction the buffer is walked between each iteration to save memory
    int                  Direction = 1;
    // Have audio to playback
    int                  Playback = FALSE;
    // The amount of data to be recorded before starting reverse playback
    // NOTE: Probably want this to be configured at runtime via a knob, etc.
    int                  ChunkSize = BufferSize;
    
    // Infinite loop of recording and reverse playback
    for (;;)
    {
        unsigned short PlaySample;
 
        // Slow down the sampling rate so that it doesn't exceed 20kHz
        wait_us(50);
        
        // Read out the sample from the buffer to be played back
        if (Playback)
        {
            PlaySample = Buffer[Index];
            speaker.write_u16(PlaySample);
        }
        
        // Obtain current audio sample from the A/D converter.
        ReadSample = mic.read_u16();    
        
        // 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;
            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;
            Index = ChunkSize - 1;
        }
    }
}
30 May 2011

Cool thanks alot Adam we got it workin yesturday:) will give this other code I go but I am happy with the other code tho:)

http://mbed.org/users/mbed2f/programs/reverseeffectsguitarspeech/lrxi2g

Adam Green wrote:

You could try this version which bumps the size of the buffer up and maximizes the chunk size to use all of this buffer. I also added a wait_us(50); at the top of the for() loop to reduce the sampling to something less than 20kHz.

#include <mbed.h>
 
// Boolean types
#define TRUE 1
#define FALSE 0

/* ADC for the microphone/input, DAC for the speaker/output */
AnalogIn mic(p19);
AnalogOut speaker(p18);
 
// Allocate a buffer to be used for the audio recording
static const size_t   BufferSize = 15 * 1024;
static unsigned short Buffer[BufferSize];
 
 
int main(void)
{
    unsigned short        ReadSample = 0xFFFF;
    // Indices to track where the playback and recording should take place in the
    // audio buffer.  The recording can occur one sample behind the current playback
    // index since it is no longer required.
    int                  Index = 0;
    // Reverse the direction the buffer is walked between each iteration to save memory
    int                  Direction = 1;
    // Have audio to playback
    int                  Playback = FALSE;
    // The amount of data to be recorded before starting reverse playback
    // NOTE: Probably want this to be configured at runtime via a knob, etc.
    int                  ChunkSize = BufferSize;
    
    // Infinite loop of recording and reverse playback
    for (;;)
    {
        unsigned short PlaySample;
 
        // Slow down the sampling rate so that it doesn't exceed 20kHz
        wait_us(50);
        
        // Read out the sample from the buffer to be played back
        if (Playback)
        {
            PlaySample = Buffer[Index];
            speaker.write_u16(PlaySample);
        }
        
        // Obtain current audio sample from the A/D converter.
        ReadSample = mic.read_u16();    
        
        // 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;
            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;
            Index = ChunkSize - 1;
        }
    }
}