adrift in the sea of experience

Monday, February 4, 2008

Recording phone calls on a S60 phone. Part 3: getting rid of the beep

OK so recording phone calls turned out to be relatively easy, but what about that annoying beep inserted into recorded phone conversations? This beep comes after the first second of the conversation, and every 15 seconds after that. Turns out that there is a way around this: the trick to avoid the beep is to not record longer than 1 second.

That's a pretty short conversation, you say?

Not necessarily. You could, for example, stop the recording before the first second completes, then restart it immediately, etc... Unfortunately the speed at which code can be executed is limited, and this technique results in unacceptable gaps in the recording, especially if we use python. There is a commercial application called Total Recall which appears to use this technique. It worked for my N95 if I set the recording quality to "low", but like my python script, the recording gaps are unacceptable.

Is it possible to do better? Yes! If you start a new recording before stopping the previous one, the beep still doesn't surface, and there will be no lost audio. The following function does exactly that:


def start_recording(filename):
global recording
counter = 0
recording = True
sound_file = audio.Sound.open(filename+'_part'+str(counter)+'.wav')
sound_file.record()
start = True
while recording:
if start:
start = False
else:
e32.ao_sleep(.6)
counter = counter + 1
next_sound_file = audio.Sound.open(filename+'_part'+str(counter)+'.wav')
next_sound_file.record()
e32.ao_sleep(.3)
sound_file.stop()
sound_file.close()
sound_file = next_sound_file
print "stopping recording"
sound_file.stop()
sound_file.close()
concatenate_wavs(filename, counter)


This function will create a recording in fragments of less than 1 second, which overlap about .3 seconds. In practice, it turns out that the overlap is typically a bit less than that. Now we could post-process these audio fragments on a PC to stitch them together, but part of the usefullness of recording phone conversations is that you can immediately replay them on your phone. This implies the need to do the post-processing on the phone itself.

This is were the python wave module comes in. This module provides all the functionality you need to read and write valid .wav files, but unfortunately it is not included in the PyS60 implementation. Not one to be easily discouraged, I downloaded the official python 2.2 sources. This is the (old!) version upon which PyS60 is based. Unpack the source archive, copy the wave.py and chunk.py modules to the phone, and yes, it works!

Simply concatenating the wave samples will result in a little stutter in the recording though. The following function attempts to detect the overlap between fragments to fix this:


def concatenate_wavs(filename, max):
print "Processing "+str(max+1)+" audio chunks:"
merged = wave.open(filename+'.wav','w')
previousframes = None
for i in range(0,max+1):
partname = filename+'_part'+str(i)+'.wav'
part = wave.open(partname,'r')
frames = part.readframes(part.getnframes())
part.close()
os.remove(partname)
if i==0:
merged.setparams(part.getparams())
overlap=0
else:
overlap=frames.find(previousframes[-8:])+8
if overlap==7:
overlap=0
print overlap
previousframes=frames
merged.writeframes(frames[overlap:])

merged.close()
print "done!"


And there you go, a simple python script for recording phone conversations on a S60 3rd edition phone without beeps :) For some reason the overlap detection does not always work, but the casual stutter is not yet annoying enough to warrant further investigation. More important is the fact that this script still needs alot of work before it can be declared suitable for public consumption. It should get a proper GUI, be packaged as a standalone application which can be easily installed, and it should be started automatically whenever the phone is booted.

But I have not yet figured out all that stuff, so that's for another post... :)

No comments: