Getting audio measurement
Audio loudness information is kept in M_AUDIO_LOUDNESS structure. To get this information you should grab a frame from a source and get M_AV_PROPS structure from the frame object.
MPlatform
You can get a frame either with the ObjectFrameGet method or by using an OnFrame event:
MFrame myFrame;
mySourceObject.ObjectFrameGet(out myFrame);
M_AV_PROPS myProps;
myFrame.FrameAVPropsGet(out myProps);
or
((MPlaylistClass)m_pMAudio).OnFrame += new MAudioControl_OnFrame;
void MAudioControl_OnFrame(string bsChannelID, object pMFrame)
{
M_AV_PROPS myProps;
((IMFrame)pMFrame).FrameAVPropsGet(out myProps);
}
MFormats
You can get a frame with the SourceFrameGet method or any similar
MFFrame myFrame;
mySource.SourceFrameGet(-1, out myFrame, "");
M_AV_PROPS myProps;
int audioSamples;
myFrame.MFAVPropsGet(out myProps, out audioSamples);
The M_AV_PROPS structure contains an ancData field, that is a M_ANC_DATA structure with input and output audio loudness information (audOriginal and audOutput fields). The M_AUDIO_LOUDNESS structure contains the lufs field of LUFS_METERS type where the data is stored.
LUFS_METERS structure
The structure which contains fields:
Name | Type | Description |
---|---|---|
fM | float | Moment (400 msec) ‘EBU Mode’ metering, original and output audio |
fS | float | Short (3000 msec) ‘EBU Mode’ metering, original and output audio |
fI | float | Intermediate (from start) ‘EBU Mode’ metering, original and output audio |
fLRA | float | Loudness Range value |
fMaxTPL | float | Maximal True Peak Level value |
arrTPL | array of float | EBU TPL (True Peak Level) peaks for one frame |
arrReserved | array of float | Reserved for future usage |
Make audio meters
By getting the audio loudness information using a timer or for each processed frame, you can build audio meters of different types (RMS, VU, LUFS meters).
In MFormats, you can use LUFS data to implement an audio normalization algorithm. In MPlatform, there is internal audio normalization option.
Enable LUFS measurement
LUFS meters are disabled by default. A calculation increases a time to process each frame to 2ms. If the feature is not necessary for your project or you need better performance in frame processing (e.g. for 60 fps or higher each millisecond is important), it is better to keep it disabled. To enable LUFS measurement, you should set "audio.lufs" property to "true" using the PropsSet method.
It works for all source objects in MPlatform (MFile, MPlaylist, MLive - use "object::audio.lufs" property) and MFormats (MFReader, MFLive - just "audio.lufs").
mySourceObject.PropsSet("object::audio.lufs", "true");
Additional features
It's possible to add the lufs only for required channels, for example, to avoid lufs calculating from Dolby-E channels(in the SDK, at this moment, we can't decode it).
Just change with the PropsSet method value of the "audio.lufs_channels" property.
m_objMFReader.PropsSet("audio.lufs_channels", "2,3");
If you change lufs dynamically after playback you should reset the lufs calculations with audio.lufs_state property.
m_objMFReader.PropsSet("audio.lufs_state", "reset");
Recalculation of audio data
In some scenarios like filling a frame with audio data from a buffer, or like getting modified audio data after mixing of several frames, e.g. with MFOverlay method, you need to recalculate the M_AV_PROPS values to get correct results. To do so, you need to call MFAudioGain method in this way:
pFrame.MFAudioGain("recalc_vu_meters", 0.0, 0.0);