3
$\begingroup$

After importing a sound file, how can I add an echo to it?

 sound = Import["test.wav", "SampleRate"]

It needs to be apply after time specified by user. This is as far as I have got:

 addEcho[sound_, time_] :=
   Module[{tmp = sound, channels, samples, duration},
     {channels, samples} = Dimensions[Import["test.wav", "Data"]];
     duration = samples/tmp // N;
     result]
$\endgroup$
  • 3
    $\begingroup$ Honestly, I'm not sure that Mathematica is the tool for the job. There are plenty of sound editors that will do this more quickly and, frankly, much better. Take a look at Audacity, for example. $\endgroup$ – MarcoB May 31 '16 at 22:38
  • 2
    $\begingroup$ Can you just delay and combine? $\endgroup$ – Henricus V. Jun 1 '16 at 0:22
  • 1
    $\begingroup$ @MarcoB Actually this is just a convolution and Mathematica should be very good at that (ListConvolve). $\endgroup$ – Szabolcs Jun 1 '16 at 16:03
3
$\begingroup$

The idea is to delay the sound (sometimes also reduce its amplitude) and add it to your original signal. Assuming that

Import["yourWavfile.wav", "Elements"] yields: {AudioChannels,AudioEncoding,Data,SampledSoundList,SampleRate,Sound}

the duration (in seconds) of your sound file is the length of your Data over the SampleRate (e.g. 20000). Thus to delay your signal by e.g. 0.2 seconds simply drop the first 0.2*20000=4000 points and add 4000 zeros at the end of the resulting list. In some cases you may also wish to reduce the intensity of the shifted measurements by multiplying by a given factor 0.5, 0.8 etc. (initially set it to 1). Finally, add the shifted signal to the original one and you should have an echo effect. I am sure there are more elegant ways to do it, here is my attempt (note that snd[[5,2]] is the SampleRate and snd[[3,2,1]] are your raw data):

echo[sound_, delay_, intens_]:=Module[{snd, shift, secondSnd, echoSound},snd = Import[sound, "Rules"];shift = delay*snd[[5,2]];secondSnd=PadRight[Drop[snd[[3, 2, 1]], shift], Length[snd[[3, 2, 1]]]];echoSound = intens*secondSnd + snd[[3, 2, 1]];Sound[SampledSoundList[echoSound, snd[[5, 2]]]]]

Try echo["MyWavFile.wav", 0.2, 1] in which 0.2 is the delay in seconds and 1 is the amplitude of the shifted sound.

$\endgroup$
6
$\begingroup$

Since version 11.0, AudioReverb does this in a single go. There are several impulse responses that come with Mathematica as example data. Try ExampleData["Audio"] and look for names starting with IR.


An echo can be added by convolving the waveform with an appropriate impulse response.

You can find many real recorded impulse responses at http://www.echothief.com/ Download the package and extract it.

Then we can do something like this:

echo = Import["~/Downloads/EchoThiefImpulseResponseLibrary/Miscellaneous/ConvocationMall.wav"] (* import from appropriate location *)

sound = ExampleData[{"Sound", "BlackcapWarbler"}]

sounddata = sound[[1, 1, 1]]; (* I'm lazy so I'll throw away the second channel *)
echodata = echo[[1, 1, 1]];

ListPlay[
  ListConvolve[echodata, sounddata], 
  SampleRate -> 44100, PlayRange -> All
]

Make sure that the impulse response has the same sample rate as the sound you are convolving it with.


Note that simply adding a delay is equivalent to convolving with a list which has all zero elements except for the first and last one.

For example, to add a delay of t seconds, with a sample rate of 44100, use

t = 0.1;
echodata = Developer`ToPackedArray@Join[{1.}, ConstantArray[0., Round[44100 t]], {0.5}];
$\endgroup$
  • $\begingroup$ Very cool! I wasn't aware of the relationship between echo and convolution for sound waves. (+1) $\endgroup$ – MarcoB Jun 1 '16 at 16:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.