ElvishArtisan / rivendell

A full-featured radio automation system targeted for use in professional broadcast and media environments
204 stars 63 forks source link

Voice Tracker Normalization #226

Open deltecent opened 5 years ago

deltecent commented 5 years ago

I've been doing some testing with Voice Tracker normalization and from what I can tell, it doesn't work.

I've dug through the source code in both "stable" and "master" and cannot figure out where the normalization takes place.

I'm hoping one of the Rivendell development masters can tell me where to look in the source code for where the normalization takes place.

ElvishArtisan commented 5 years ago

On Sep 2, 2018, at 23:36, Deltec Enterprises notifications@github.com wrote:

I've been doing some testing with Voice Tracker normalization and from what I can tell, it doesn't work.

I've dug through the source code in both "stable" and "master" and cannot figure out where the normalization takes place.

Look in the ‘RDAudioConvert’ class (in ‘lib/rdaudioconvert.[cpp,h])’. Specifically, in the ‘Stage2Convert()’ method.

Cheers!

---------------------------------------------------------------------- Frederick F. Gleason, Jr. Chief Developer Paravel Systems
A room without books is like a body without a soul.
-- Cicero
----------------------------------------------------------------------
deltecent commented 5 years ago

Fred, thanks. I should have given more detail. If found RDAudioConvert::convert() where normalization seems to take place. What I cannot find is how a recorded voice track ever gets processed by convert().

The normalization level for voice tracking is stored by RDLogeditConf::setRipperLevel and retrieved by RDLogeditConf::ripperLevel().

I cannot find anywhere within rdlogedit where RDLogeditConf::ripperLevel is even looked at.

The flow seems to be:

rda->cae()->loadRecord() rda->cae()->record() rda->cae()->stopRecord() rda->cae()->unloadRecord() checkInRecording() RDRehash::rehash setSampleRate() updateLength()

I don't know enough about the internals of Rivendell to say that this feature has never been (or currently isn't) implemented, but I'm leaning in that direction. I'm hoping to get some confirmation that it hasn't been implemented so I can work on getting it into master. It is a feature I'd really like to have.

ElvishArtisan commented 5 years ago

On Sep 3, 2018, at 12:23, Deltec Enterprises notifications@github.com wrote:

Fred, thanks. I should have given more detail. If found RDAudioConvert::convert() where normalization seems to take place. What I cannot find is how a recorded voice track ever gets processed by convert().

The normalization level for voice tracking is stored by RDLogeditConf::setRipperLevel and retrieved by RDLogeditConf::ripperLevel().

I cannot find anywhere within rdlogedit where RDLogeditConf::ripperLevel is even looked at.

Ah, I see what’s going on. Normalization will only happen when it’s a file being imported into a voice track. A live capture will indeed bypass that process completely, on the (perhaps naive?) assumption that the person recording the track will ensure correct levels.

Cheers!

---------------------------------------------------------------------- Frederick F. Gleason, Jr. Chief Developer Paravel Systems
A room without books is like a body without a soul.
-- Cicero
----------------------------------------------------------------------
deltecent commented 5 years ago

Bingo! So, since we have all types of people, including middle school students, voice tracking, would normalizing live capture be something of interest? I totally get that it shouldn't be necessary, but in our case, on a shoe-string budget for microphone processing and various levels of experience using the equipment, I thought the feature would be nice to have.

What lead me down this path is a discrepancy between the level meters when recording and the resulting waveform in the voice tracker. The waveform in the voice tracker always ends up at a much lower level than the meters are showing during recording. I figured there was some normalization going on but always at a (lower than I want) static level other than what I was setting it to in RDAdmin.

rlwoods commented 5 years ago

I noticed a long time ago that normalization did not occur on live tracking. I would very much prefer that it did as it is naieve to think that a jock would pay attention to their levels!

RW

On Sep 3, 2018 1:10 PM, "Fred Gleason" notifications@github.com wrote:

On Sep 3, 2018, at 12:23, Deltec Enterprises notifications@github.com wrote:

Fred, thanks. I should have given more detail. If found RDAudioConvert::convert() where normalization seems to take place. What I cannot find is how a recorded voice track ever gets processed by convert().

The normalization level for voice tracking is stored by RDLogeditConf::setRipperLevel and retrieved by RDLogeditConf::ripperLevel().

I cannot find anywhere within rdlogedit where RDLogeditConf::ripperLevel is even looked at.

Ah, I see what’s going on. Normalization will only happen when it’s a file being imported into a voice track. A live capture will indeed bypass that process completely, on the (perhaps naive?) assumption that the person recording the track will ensure correct levels.

Cheers!

---------------------------------------------------------------------- Frederick F. Gleason, Jr. Chief Developer Paravel Systems
A room without books is like a body without a soul.
-- Cicero
----------------------------------------------------------------------

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ElvishArtisan/rivendell/issues/226#issuecomment-418163553, or mute the thread https://github.com/notifications/unsubscribe-auth/ASa9rwQjtDRXA6kwy_sb86L-bD5fEfLgks5uXWJ6gaJpZM4WW7CF .

ElvishArtisan commented 5 years ago

On Sep 3, 2018, at 13:20, Deltec Enterprises notifications@github.com wrote:

Bingo! So, since we have all types of people, including middle school students, voice tracking, would normalizing live capture be something of interest? I totally get that it shouldn't be necessary, but in our case, on a shoe-string budget for microphone processing and various levels of experience using the equipment, I thought the feature would be nice to have.

Probably true!

However, it wouldn’t be trivial to implement. Normalization is inherently a multi-pass process as there is no way of determining the required gain change until the entire audio piece has been captured. The way we handle this sort of situation in rdcatchd(8) is to capture the audio to a temporary file, then import that to the final destination in the audio store when the capture is complete, which also has the advantage of letting us use the same methods that handle straight file importation. The problem with this approach in the voice tracker is that it will create a race — the importation takes time, during which the final, normalized file is not available for audition or visualization by the user on the voice-tracker. Short of freezing the tracker UI until this process can complete, there is no easy way to handle this. (This, BTW, is also precisely the reason why play-while-recording in rdcatch(1) does not work if normalization is enabled on the recording).

I’m open to ideas...

Cheers!

---------------------------------------------------------------------- Frederick F. Gleason, Jr. Chief Developer Paravel Systems
A room without books is like a body without a soul.
-- Cicero
----------------------------------------------------------------------
ElvishArtisan commented 5 years ago

On Sep 3, 2018, at 13:21, rlwoods notifications@github.com wrote:

I noticed a long time ago that normalization did not occur on live tracking. I would very much prefer that it did as it is naieve to think that a jock would pay attention to their levels!

Sad, but all too true…

Cheers!

---------------------------------------------------------------------- Frederick F. Gleason, Jr. Chief Developer Paravel Systems
A room without books is like a body without a soul.
-- Cicero
----------------------------------------------------------------------
deltecent commented 5 years ago

I'll think about it. For now, I'll try and figure out why there is a level difference between the meters when recording and the resulting waveform. I would also suggest changing the "Normalization Level:" and "Auto Trim Threshold:" labels in RDLogEdit Voice Tracker Settings to maybe include "Import" to make it more clear or update the documentation to state those settings do not apply to live recording.

I may have some ideas for adding normalization after I better understand how Rivendell's audio recording works.

SM0VXI commented 4 years ago

Probably true! However, it wouldn’t be trivial to implement. Normalization is inherently a multi-pass process as there is no way of determining the required gain change until the entire audio piece has been captured. The way we handle this sort of situation in rdcatchd(8) is to capture the audio to a temporary file, then import that to the final destination in the audio store when the capture is complete, which also has the advantage of letting us use the same methods that handle straight file importation. The problem with this approach in the voice tracker is that it will create a race — the importation takes time, during which the final, normalized file is not available for audition or visualization by the user on the voice-tracker. Short of freezing the tracker UI until this process can complete, there is no easy way to handle this. (This, BTW, is also precisely the reason why play-while-recording in rdcatch(1) does not work if normalization is enabled on the recording). I’m open to ideas...

I have used the ffmpeg loudnorm filter in a similar but unrelated context. The loudnorm filter allows for a dynamic one-pass normalisation approach, which makes it suitable for live streams. It consists of a specially designed loudness-tuned AGC followed by a transparent look-ahead true peak limiter. Perhaps the same approach can be used in this context too.

It is explained in detail here by the designer: http://k.ylo.ph/2016/04/04/loudnorm.html

Comprehensive info here: https://ffmpeg.org/ffmpeg-filters.html#loudnorm

If this part of the code book is opened it would also be super nice with native support for loudness normalisation of imported files.