4
$\begingroup$

I'm trying to seamlessly loop an audio signal. When I loop the current audio signal I have, I hear audible clicks or pops right as it loops back to the beginning. I want to be able to loop the audio signal without having any pops.

I have tried changing the signal near the end by writing an interpolation which follows this formula $$ B_n=\frac{(A_n d_1) + (Cd_2)}{d_1+d_2} $$ Where $B$ is the output, $A$ is the audio signal itself, and $C$ is the first signal value within the audio signal. $d_1$ equals to how many signal values until the first sample. $d_2$ equals how many signal values since the specified start. And I choose when the specified start is based on how many milliseconds I wish for the interpolation to be. In this case I gave 15ms a try. So, the specified start will be 15ms before the end of the signal.

And in simple terms; it's a crossfader that is linearly transitioning from the signal source $A$ onto the single value $C$.

The end result is this.

Linear crossfading onto a single signal value

The transition points are highlighted via the cursor. Also, do not mind that both signals are not exactly the same. For the upper signal, I cut a portion of the start so that it would start at a non-0 value.

Since the crossfade is fairly quick for human ears (15ms), I did not manage to hear any disintegration of audio. But is this good practice? I am new to signal processing and cannot tell whether or not this will work for all types of signals I might have. Is there any other way this could be done in a more "proper" manner?

$\endgroup$
3
  • $\begingroup$ Your approach seems solid to me; it works and doesn't require a lot of processing. If you wanted to make more "optimized" transitions you could use FFT's and windowing but that would be a lot more processing and wouldn't make an audible difference. However I wish to understand the signals in your figure and can't make out what each row is, can you clarify that further in your question? $\endgroup$ May 15 at 13:07
  • $\begingroup$ @DanBoschen The top two waveforms above are the left and right channels of the first audio file. The first audio file is the same as the one below but the starting sample was changed to be something bigger than 0. Before the cursor is the end of the audio file, and starting from the cursor the beginning of the audio file shown so that it's easy to see that the crossfader does indeed make the signal converge into the first sample found within the audio file. And the bottom two are the same as above but with the original audio which starts from 0. $\endgroup$ May 15 at 17:14
  • $\begingroup$ Are you trying to do this to one signal, manually? Or are you trying to do it to many signals, but with you supervising a tool? Or are you tying to write a tool to do it completely autonomously? It makes a difference to what sort of investment is appropriate, and what sort of measures are available to the process. $\endgroup$
    – Neil_UK
    May 17 at 7:24
8
$\begingroup$

But is this good practice?

Yes, that's a perfectly reasonable approach.

Will this will work for all types of signals I might have ?

There are a LOT of signals out there and there is always an outlier. In your case, I think the most "vulnerable" would be low frequency sine waves. A 40 Hz sine wave has a period of 25 ms and looping one at an inconvenient point without audible artifact is tricky. So this all boils down to: how likely are these signal for your application, what level audibility is acceptable and what are the constraints around resources, looping points & length, etc.

Is there any other way this could be done in a more "proper" manner?

  1. If you have some leeway with the exact loop length and loop points, try to put the loop points at the nearest zero crossing. Ideally both zero crossing go in the same direction.
  2. You can do an energy cross fade instead of a linear cross fade. This will minimize the volume dip in the middle of the cross fade, but at 15ms it's not going to make much of an audible difference.
$\endgroup$
1
  • $\begingroup$ Sadly the scenario you described with the 40 Hz sine wave does sound like it would end up leaving an audio artifact. I also have my hands tied with where I can start and end the loop of these files as I have other audio files that when played at the same time, they sync with one another. But I will give energy cross fade a look and see what that is about, thanks! $\endgroup$ May 15 at 17:26
3
$\begingroup$

Fully agreeing with Hilmar, to add to

Is there any other way this could be done in a more "proper" manner?

Well, you can try to make sure that the spectrum of your signal stays the same, without the discontinuity. The way I'd approach that mathematically:

  1. Take a low-pass filter. In this case, preferably a FIR, for you'll need the impulse response to be done after a finite time. Let it have impulse response length $L$
  2. Take the last $L$ samples of your signal, and copy them, prepending them to the beginning of your signal.
  3. Filter the whole thing with your FIR
  4. Crop away the first $L$ samples again. The result should have the same length as the original signal.

This ensures that there's no discontinuity at the end of your signal. The idea is very much stolen directly from cyclic prefix OFDM, where it is used to make it look like the channel (== an FIR filter) is applied in a cyclic matter to the signal. Here, you want your channel to suppress the high-frequency content that leads to "pops".

Notice that the effect is quite similar to your static value, just that it doesn't linearly interpolate to the start sample, but linearly combines a weighting of the last $L-n$ samples with the first $n$ samples (which is the definition of a digital FIR filter).

$\endgroup$
6
  • 1
    $\begingroup$ Sorry, I have trouble following this: Wouldn't that lowpass filter the entire loop ? Do you apply the low pass only to the overlapped section ? $\endgroup$
    – Hilmar
    May 15 at 16:01
  • $\begingroup$ it'd filter the full loop, but: usually, your audio is a low-pass signal, anyways! So filtering wouldn't change the signal significantly (it would introduce a cyclic shift by the group delay, but that's inaudible - we're looping anyways $\endgroup$ May 15 at 16:31
  • $\begingroup$ Sorry, but this is nonsense. The low-pass would profoundly change the sound (and the spectrum, for that matter). $\endgroup$ May 15 at 22:53
  • 1
    $\begingroup$ @leftaroundabout how can you be so determined about that without knowing the filter? Typically, audio is sampled at frequencies like 48 kHz, and depending on who you ask, human perception ends above 16 to 21 kHz , so there's plenty of space for a inaudible low-pass filter. When you look at the samples in the question above, I'd be surprised if there's any spectral content above ¼ of the sampling rate. So, I'd design my low-pass filter to maybe cut off somewhere above 12 kHz, and have a rather relaxed transition to stopband. $\endgroup$ May 15 at 23:01
  • 1
    $\begingroup$ If you only filter above 12 kHz, you'll do basically nothing about the audible click at the looping point either. Note that the OP's 15 ms transition region corresponds to more like filtering everything above 60 Hz! $\endgroup$ May 15 at 23:25
3
$\begingroup$

Let me edit your statement to totally change its meaning, but which question I think you should ask.

Is there ... a ... "proper" manner?

If you had asked this, and had meant "is there any universally accepted yardstick by which one processes audio?" Well, no. You do what sounds good (if it's for artistic purposes), or what's most intelligible most of the time (for communications purposes), or what tires people out the least (for human factors purposes), etc.

Is there any other way this could be done in a more "proper" manner?

If there's no defined universal "proper", then there's no "more proper".

If you can stand to lose a bit of information, then instead of fading in the very first sample of your audio, it may sound better to fade in the first section of your audio. I'm going to mess with your notation, but let's say you have an audio clip $A_n$ starting at sample 0 and continuing to sample $N$, and that you're going to transition over $m$ samples. Then at last $m$ samples you go:

$$B_n = \frac{N - n}{m} A_n + \frac{n - m + N}{m} A_{n - m + N}$$

This should smoothly taper the end of the clip to 0 at the same time it's taking the beginning of the clip at 0 and smoothly ramping it up to full volume.

It may or may not sound better. If you're trying to do something like play one sustained trumpet note forever, then probably not because the note's beginning and end are highly correlated, and the components are almost guaranteed to not be in phase at the transition. But if you're trying to have a speech clip repeat over and over again, or the same musical passage, then probably, because the components won't be highly correlated, so they can be mashed together without constructive or destructive interference.

$\endgroup$

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.