Monday, February 15, 2010

Recording EOS movies with synced external audio

As long as you don’t film fine detail which causes heavy aliasing the current Canon DSLRs with EOS movie function record stunning images. The biggest flaw though is the audio automatic gain control (AGC) of those cameras. Whenever a scene is quiet the AGC pumps up the amplification of the microphone signal resulting in quite noticable noise hiss.

One solution to get high quality audio is to record it externally and sync the video and audio files later in the video editor. This means you have to start video and audio recording by pushing buttons on two different devices. It’s a hassle and you better not forget to turn on audio recording.


The Edirol R-09HR audio recorder has good internal microphones and records up to 24 bit/96 kHz audio. It also has 1/8” jack inputs for an external mic or line signal. But the best thing is that it comes with an infrared remote control.


An optional leather cover offers a 1/4" mounting thread. I removed the back to get to the SD card more easily.


All current Canon DSLRs with EOS movie function allow starting and stopping video recording via an optional infrared remote control. Just switch the camera into Live View and use the 2s delay setting on the Canon RC-1 remote to start and stop video recording.


This project uses an Arduino I/O board and two IR LEDs to start recording on the Edirol R-09HR audio recorder and the camera at the same time.


You can find the corresponding files with the help of the recording date but once you convert the h.264 files to lets say ProRes 422 files you’re altering the file date. A foolproof way is to set the cameras file numbering to “Auto reset” and the R-09HR audio recorder file naming to “Name”. This makes sure that file numbering starts with one on every blank storage card. Unfortunately the Canon EOS DSLRs do not differentiate between movie files and photo files so if you shoot photos make sure you also record a short audio file to keep file numbering paired.


Although both devices receive the IR signal at practically the same time (with just a few milliseconds delay) the EOS movie recording starts with a quite long delay. Fortunately both stop recording at the same time so syncing is easy. All that’s needed to sync the audio tracks with one frame accuracy is to align the track ends.

Is the synchronisation accurate enough? Since the R-09HR STOP signal takes about 73 milliseconds and the EOS REC signal takes just about 6 milliseconds it makes sense to send the shorter signal at last i.e. the movie recording stops about 6 milliseconds later than the audio recording. To put this into perspective lets look at the approximate frame duration of video files. 24 or 25 fps equal roughly 40 milliseconds per frame and 30 fps equals about 33 milliseconds per frame. The 6 millisecond delay is therefore well within frame accuracy. You will hear the external sound within the same frame even when it comes 6 milliseconds before the audio recorded in the camera.




It looks weird but it gives me EOS movies with synced 24 bit/96 kHz audio.

Does this setup produce good sound? Not really, the internal microphones of the R-09HR are omnidirectional and pick up sound from everywhere. You usually want to capture the sound of the scene you're filming by placing a directional microphone close to the action. So for best sound connect an external directional microphone.




The circuit.



The Arduino sketch

/*
Arduino sketch for simulating a Canon RC-1 and EDIROL R-09HR IR remote control
2010, Martin Koch
http://controlyourcamera.blogspot.com/
Huge thanks go to http://www.doc-diy.net/photo/rc-1_hacked/index.php for figuring out the Canon RC-1 IR code.
IR signal sending code is based on an example at http://luckylarry.co.uk/2009/07/arduino-ir-remote-intervalometer-for-nikon-d80-that-means-timelapse-photography-yarrr
*/
#define irLED_EOS 12 // connect a IR LED with a 180 ohms resistor in series to digital pin 12
#define irLED_R09 8 // connect a IR LED with a 180 ohms resistor in series to digital pin 8
#define statusLED 13 // Built in LED on Arduino board
#define recBUTTON 4 // connect a push button to digital pin 4 and GND
#define photoBUTTON 0 // connect a push button to digital pin 0 and GND
boolean rec = true;

void setup() {
pinMode(irLED_EOS, OUTPUT);
pinMode(irLED_R09, OUTPUT);
pinMode(statusLED, OUTPUT);
pinMode(recBUTTON, INPUT);
pinMode(photoBUTTON, INPUT);
digitalWrite(recBUTTON, HIGH); //turn on internal 20 k pullup resistor so the open input state is HIGH
digitalWrite(photoBUTTON, HIGH); //turn on internal 20 k pullup resistor so the open input state is HIGH
}

void loop() {
if (digitalRead(recBUTTON) == LOW) {
if (rec) {
digitalWrite(statusLED, HIGH);
R09_REC(); // Activate
delay(1000);
EOS_REC();
R09_REC();
rec = false;
delay(1000); // ignore button contact bouncing
}
else {
R09_STOP();
EOS_REC();
digitalWrite(statusLED, LOW);
rec = true;
delay(1000); // ignore button contact bouncing
}
}

if (digitalRead(photoBUTTON) == LOW) {
digitalWrite(statusLED, HIGH);
EOS_PHOTO();
delay(2000); // allow camera to write photo to card
}
}

void EOS_REC() {
for(int count=0; count<16; count++) { //Burst 1
digitalWrite(irLED_EOS, HIGH);
delayMicroseconds(11);
digitalWrite(irLED_EOS, LOW);
delayMicroseconds(11);
}

delayMicroseconds(5360); //Pause

for(int count=0; count<16; count++) { //Burst 2
digitalWrite(irLED_EOS, HIGH);
delayMicroseconds(11);
digitalWrite(irLED_EOS, LOW);
delayMicroseconds(11);
}
return;
}

void EOS_PHOTO() {
for(int count=0; count<16; count++) { //Burst 1
digitalWrite(irLED_EOS, HIGH);
delayMicroseconds(11);
digitalWrite(irLED_EOS, LOW);
delayMicroseconds(11);
}

delayMicroseconds(7330); //Pause

for(int count=0; count<16; count++) { //Burst 2
digitalWrite(irLED_EOS, HIGH);
delayMicroseconds(11);
digitalWrite(irLED_EOS, LOW);
delayMicroseconds(11);
}
return;
}

void R09_REC() {
unsigned long IR_Signal[68] = {
690,690,44,44,44,130,44,44,44,44,44,44,44,44,44,44,44,130,44,44,44,130,44,130,44,44,44,130,44,130,44,130,44,130,44,130,44,130,44,44,44,130,44,44,44,130,44,44,44,44,44,44,44,44,44,130,44,44,44,130,44,44,44,130,44,130,44,0 };
for (int i=0; i<68; i=i+2) {
unsigned long endBurst = micros() + IR_Signal[i] * 13;
while(micros() < endBurst) {
digitalWrite(irLED_R09, HIGH);
delayMicroseconds(13);
digitalWrite(irLED_R09, LOW);
delayMicroseconds(13);
}
unsigned long endPause = micros() + IR_Signal[i+1] * 13;
while(micros() < endPause);
}
}

void R09_STOP() {
unsigned long IR_Signal[68] = {
690,690,44,44,44,130,44,44,44,44,44,44,44,44,44,44,44,130,44,44,44,130,44,130,44,44,44,130,44,130,44,130,44,130,44,130,44,44,44,44,44,130,44,44,44,130,44,44,44,44,44,44,44,130,44,130,44,44,44,130,44,44,44,130,44,130,44,0 };
for (int i=0; i<68; i=i+2) {
unsigned long endBurst = micros() + IR_Signal[i] * 13;
while(micros() < endBurst) {
digitalWrite(irLED_R09, HIGH);
delayMicroseconds(13);
digitalWrite(irLED_R09, LOW);
delayMicroseconds(13);
}
unsigned long endPause = micros() + IR_Signal[i+1] * 13;
while(micros() < endPause);
}
}

1 comment:

  1. Martin how is it that NO ONE has commented on this?!!! This is revolutionary for Doc film makers and Journalists. I'm eager to give this a go.

    It seems preposterous that I can sidestep the one of my biggest hurdles to responding to the moment (did I remember to hit record on the audio recorder or is it just in "ready" mode) for about 50 bucks!

    Thank you so much!

    ReplyDelete