Announcement

Collapse
No announcement yet.

Tok'ra/Goa'uld voice changer

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Tok'ra/Goa'uld voice changer

    I am still hashing things out but I THINK, this might be a doable option for realtime voice processing that many desire. I hopped over to this project after I burned out a second wii nunchuck trying to hash out some wiring issues.

    I will still have to play with things some but the voice changer will allow any number of voice effects. I am still trying to hash out the code to get a static Gou'ld or Tok'ra sounding voice, but the adjustable pot allows for many more uses as well. This will also do a decent darth vader voice as well.

    This just takes Adafruit's wave shield, max4466 microphone, adjustable potentiometer, arduino uno. and a bit of soldering.

    This is based off of this tutorial:
    https://learn.adafruit.com/wave-shield-voice-changer

    I am trying to streamline the code a little bit more.





    /* ADAVOICE is an Arduino-based voice pitch changer plus WAV playback.
    Fun for Halloween costumes, comic convention getups and other shenanigans!
    Hardware requirements:
    - Arduino Uno, Duemilanove or Diecimila (not Mega or Leonardo compatible)
    - Adafruit Wave Shield, Speaker attached to Wave Shield output, Battery for portable use
    If using the voice pitch changer, you will also need:
    - Adafruit Microphone Breakout, 10K potentiometer for setting pitch (or hardcode in sketch)
    Software requirements: WaveHC library for Arduino, Demo WAV files on FAT-formatted SD card
    Connections:
    - 3.3V to mic amp+, 1 leg of potentiometer and Arduino AREF pin
    - GND to mic amp-, opposite leg of potentiometer
    - Analog pin 0 to mic amp output
    - Analog pin 1 to center tap of potentiometer
    - Wave Shield output to speaker or amplifier
    - Wave shield is assumed wired as in product tutorial
    Potentiometer sets playback pitch. Pitch adjustment does NOT work in
    realtime -- audio sampling requires 100% of the ADC. Pitch setting is
    read at startup (or reset) and after a WAV finishes playing. POINT SPEAKER AWAY FROM MIC to avoid feedback.
    Written by Adafruit industries, with portions adapted from the 'PiSpeakHC' sketch included with WaveHC library.
    */
    #include <WaveHC.h>
    #include <WaveUtil.h>
    WaveHC wave; // This is the only wave (audio) object, -- we only play one at a time
    #define ADC_CHANNEL 0 // Microphone on Analog pin 0. Wave shield DAC: digital pins 2, 3, 4, 5
    #define DAC_CS_PORT PORTD
    #define DAC_CS PORTD2
    #define DAC_CLK_PORT PORTD
    #define DAC_CLK PORTD3
    #define DAC_DI_PORT PORTD
    #define DAC_DI PORTD4
    #define DAC_LATCH_PORT PORTD
    #define DAC_LATCH PORTD5
    uint16_t in = 0, out = 0, xf = 0, nSamples; uint8_t adc_save;// Audio sample counters, ADC Mode
    // WaveHC didn't declare it's working buffers private or static,
    // so we can be sneaky and borrow the same RAM for audio sampling!
    extern uint8_t
    buffer1[PLAYBUFFLEN], // Audio sample LSB
    buffer2[PLAYBUFFLEN]; // Audio sample MSB
    #define XFADE 16 // Number of samples for cross-fade
    #define MAX_SAMPLES (PLAYBUFFLEN - XFADE) // Remaining available audio samples
    #define DEBOUNCE 10 // Number of iterations before button 'takes'
    //////////////////////////////////// SETUP
    void setup() {
    uint8_t i; Serial.begin(9600); pinMode(2, OUTPUT); pinMode(3, OUTPUT); pinMode(4, OUTPUT); pinMode(5, OUTPUT); digitalWrite(2, HIGH); // Chip select, Serial clock, Serial data, Latch, Set chip select high
    TIMSK0 = 0; analogReference(EXTERNAL); adc_save = ADCSRA; startPitchShift();// 3.3V to AREF, Save ADC setting, Start pitch-shift
    }
    void loop() { if(!wave.isplaying && !(TIMSK2 & _BV(TOIE2))) startPitchShift(); }
    //////////////////////////////////// PITCH-SHIFT CODE
    void startPitchShift() { // Read analog pitch setting before starting audio sampling:
    int pitch = analogRead(1); Serial.print("Pitch: "); Serial.println(pitch); nSamples = 128;
    memset(buffer1, 0, nSamples + XFADE); memset(buffer2, 2, nSamples + XFADE); // (set all samples to 512)
    TCCR2A = _BV(WGM21) | _BV(WGM20); // Mode 7 (fast PWM), OC2 disconnected
    TCCR2B = _BV(WGM22) | _BV(CS21) | _BV(CS20); // 32:1 prescale
    OCR2A = map(pitch, 0, 1023,
    F_CPU / 32 / (9615 / 2), // Lowest pitch = -1 octave
    F_CPU / 32 / (9615 * 2)); // Highest pitch = +1 octave
    // Start up ADC in free-run mode for audio sampling:
    DIDR0 |= _BV(ADC0D); // Disable digital input buffer on ADC0
    ADMUX = ADC_CHANNEL; // Channel sel, right-adj, AREF to 3.3V regulator
    ADCSRB = 0; // Free-run mode
    ADCSRA = _BV(ADEN) | // Enable ADC
    _BV(ADSC) | // Start conversions
    _BV(ADATE) | // Auto-trigger enable
    _BV(ADIE) | // Interrupt enable
    _BV(ADPS2) | // 128:1 prescale...
    _BV(ADPS1) | // ...yields 125 KHz ADC clock...
    _BV(ADPS0); // ...13 cycles/conversion = ~9615 Hz
    TIMSK2 |= _BV(TOIE2); // Enable Timer2 overflow interrupt
    sei(); // Enable interrupts
    }
    ISR(ADC_vect, ISR_BLOCK) { // ADC conversion complete
    // Save old sample from 'in' position to xfade buffer:
    buffer1[nSamples + xf] = buffer1[in]; buffer2[nSamples + xf] = buffer2[in]; if(++xf >= XFADE) xf = 0;
    // Store new value in sample buffers:
    buffer1[in] = ADCL; buffer2[in] = ADCH; if(++in >= nSamples) in = 0; } // MUST read ADCL first!
    ISR(TIMER2_OVF_vect) { // Playback interrupt
    uint16_t s; uint8_t w, inv, hi, lo, bit; int o2, i2, pos;
    // Cross fade around circular buffer 'seam'.
    if((o2 = (int)out) == (i2 = (int)in)) {
    // Sample positions coincide. Use cross-fade buffer data directly.
    pos = nSamples + xf; hi = (buffer2[pos] << 2) | (buffer1[pos] >> 6); lo = (buffer1[pos] << 2) | buffer2[pos]; } //Expand 10-bit data to 12 bits
    if((o2 < i2) && (o2 > (i2 - XFADE))) {
    // Output sample is close to end of input samples. Cross-fade to avoid click. The shift operations here assume that XFADE is 16;
    w = in - out; inv = XFADE - w; // Weight of sample (1-n)+ xfade
    pos = nSamples + ((inv + xf) % XFADE); s = ((buffer2[out] << 8) | buffer1[out]) * w + ((buffer2[pos] << 8) | buffer1[pos]) * inv;
    hi = s >> 10; lo = s >> 2;// Shift 14 bit result down to 12 bits
    } else if (o2 > (i2 + nSamples - XFADE)) { // More cross-fade condition
    w = in + nSamples - out; inv = XFADE - w; pos = nSamples + ((inv + xf) % XFADE); s = ((buffer2[out] << 8) | buffer1[out]) * w +
    ((buffer2[pos] << 8) | buffer1[pos]) * inv; hi = s >> 10; lo = s >> 2;// Shift 14 bit result down to 12 bits
    } else { // Input and output counters don't coincide -- just use sample directly.
    hi = (buffer2[out] << 2) | (buffer1[out] >> 6); lo = (buffer1[out] << 2) | buffer2[out]; } // Expand 10-bit data to 12 bits
    // Might be possible to tweak 'hi' and 'lo' at this point to achieve different voice modulations -- robot effect, etc.?
    DAC_CS_PORT &= ~_BV(DAC_CS); // Select DAC Clock out 4 bits DAC config (not in loop because it's constant)
    DAC_DI_PORT &= ~_BV(DAC_DI); // 0 = Select DAC A, unbuffered
    DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK);
    DAC_DI_PORT |= _BV(DAC_DI); // 1X gain, enable = 1
    DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK);
    for(bit=0x08; bit; bit>>=1) { // Clock out first 4 bits of data
    if(hi & bit) DAC_DI_PORT |= _BV(DAC_DI);
    else DAC_DI_PORT &= ~_BV(DAC_DI); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); }
    for(bit=0x80; bit; bit>>=1) { // Clock out last 8 bits of data
    if(lo & bit) DAC_DI_PORT |= _BV(DAC_DI);
    else DAC_DI_PORT &= ~_BV(DAC_DI); DAC_CLK_PORT |= _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK); }
    DAC_CS_PORT |= _BV(DAC_CS); if(++out >= nSamples) out = 0; // Unselect DAC
    }

    #2
    Shol'va.
    "I was hoping for another day. Looks like we just got a whole lot more than that. Let's not waste it."

    "Never underestimate your audience. They're generally sensitive, intelligent people who respond positively to quality entertainment."

    "Individual science fiction stories may seem as trivial as ever to the blinder critics and philosophers of today, but the core of science fiction, its essence, has become crucial to our salvation, if we are to be saved at all."

    Comment


      #3
      I'd be curious to know if anyone has a reliable way of doing this in post-production with Audacity or the Adobe equivalent? I looked into it in the past, but can't remember finding anything reliable.
      sigpic
      Stargate Destiny - Coming Again Soon

      Comment


        #4
        Originally posted by Elite Anubis Guard View Post
        I'd be curious to know if anyone has a reliable way of doing this in post-production with Audacity or the Adobe equivalent? I looked into it in the past, but can't remember finding anything reliable.
        From an interview with Peter (Apophis):

        Q: How is the Goa'uld voice effect made?
        A: PW said that he speaks his lines normally then they take his voice out to a lab in California to have it "flanged". And yes, they do return his voice to him. He said that many times the actors who have played a Goa'uld or Tokra will ask each other if they have been "flanged" yet. Now we will know what they mean by that.


        Definition of flanging:

        Flanging /?flænd???/ is an audio effect produced by mixing two identical signals together, one signal delayed by a small and gradually changing period, usually smaller than 20 milliseconds.

        ***

        And to answer your question whether it can be done in post-production in Adobe Premiere, for example, the answer is yes:

        Flanging is an audio effect caused by mixing a varying, short delay in roughly equal proportion to the original signal. It was originally achieved by sending an identical audio signal to two reel?to?reel tape recorders, and then pressing the flange of one reel to slow it down. Combining the two resulting recordings produced a phase?shifted, time?delay effect, characteristic of psychedelic music of the 1960s and 1970s.

        The Flanger effect lets you create a similar result by slightly delaying and phasing a signal at specific or random intervals.

        Initial Delay Time:
        Sets the point in milliseconds at which flanging starts behind the original signal. The flanging effect occurs by cycling over time from an initial delay setting to a second (or final) delay setting.

        Final Delay Time: Sets the point in milliseconds at which flanging ends behind the original signal.

        Stereo Phasing: Sets the left and right delays at separate values, measured in degrees. For example, 180° sets the initial delay of the right channel to occur at the same time as the final delay of the left channel. You can set this option to reverse the initial/final delay settings for the left and right channels, creating a circular, psychedelic effect.

        Feedback: Determines the percentage of the flanged signal that is fed back into the flanger. With no feedback, the effect uses only the original signal. With feedback added, the effect uses a percentage of the affected signal from before the current point of playback.

        Modulation Rate: Determines how quickly the delay cycles from the initial to final delay times, measured either in cycles per second (Hz) or beats per minute (beats). Small setting adjustments produce widely varying effects.

        Mode: Provides three ways of flanging:

        Inverted: Inverts the delayed signal, canceling out audio periodically instead of reinforcing the signal. If the Original ? Expanded mix settings are set at 50/50, the waves cancel out to silence whenever the delay is at zero.

        Special Effects: Mixes the normal and inverted flanging effects. The delayed signal is added to the effect while the leading signal is subtracted.

        Sinusoidal: Makes the transition from initial delay to final delay and back follow a sine curve. Otherwise, the transition is linear, and the delays from the initial setting to the final setting are at a constant rate. If Sinusoidal is selected, the signal is at the initial and final delays more often than it is between delays.

        Mix: Adjusts the mix of original (Dry) and flanged (Wet) signal. You need some of both signals to achieve the characteristic cancellation and reinforcement that occurs during flanging. With Original at 100%, no flanging occurs at all. With Delayed at 100%, the result is a wavering sound, like a bad tape player.
        Heightmeyer's Lemming -- still the coolest Lemming of the forum

        Proper Stargate Rewatch -- season 10 of SG-1

        Comment


          #5
          I knew it could be done, I'd just never seen a good tutorial on how to do it when I first looked! I also knew it was called flanging. But I never knew that was a technical term! And it's a simple effect in Audition! lol Time to experiment. Thanks Falcon. Very much appreciated.

          Edit: So using the Heavy Flange setting, and stepping down the pitch 2 semi-tones has turned out a pretty good result!
          Last edited by Elite Anubis Guard; 26 May 2020, 03:13 AM.
          sigpic
          Stargate Destiny - Coming Again Soon

          Comment


            #6
            By which EAG means to say, they have now changed the voice on their voicemail...
            Heightmeyer's Lemming -- still the coolest Lemming of the forum

            Proper Stargate Rewatch -- season 10 of SG-1

            Comment

            Working...
            X