From 11dd88c1806e8b16179d1b6a2046fa4fa84ed0f8 Mon Sep 17 00:00:00 2001 From: nofish Date: Thu, 31 Aug 2017 15:19:52 +0200 Subject: [PATCH] #781 fix NF_GetMediaItemAverageRMS() calculation, add NF_GetMediaItemPeakRMS...() --- Breeder/BR_ReaScript.cpp | 17 ++++++- Breeder/BR_ReaScript.h | 2 + Misc/Analysis.cpp | 101 +++++++++++++++++++++++++++++++++++---- Misc/Analysis.h | 2 + ReaScript.cpp | 10 ++-- reascript_vararg.h | 16 +++++++ 6 files changed, 134 insertions(+), 14 deletions(-) diff --git a/Breeder/BR_ReaScript.cpp b/Breeder/BR_ReaScript.cpp index 99bc78580..9cd8f6349 100644 --- a/Breeder/BR_ReaScript.cpp +++ b/Breeder/BR_ReaScript.cpp @@ -937,10 +937,23 @@ double NF_GetMediaItemMaxPeak(MediaItem* item) return maxPeak; } +double NF_GetMediaItemPeakRMS_Windowed(MediaItem* item) +{ + double peakRMS = GetMediaItemPeakRMS_Windowed(item); + return peakRMS; +} + +double NF_GetMediaItemPeakRMS_NonWindowed(MediaItem* item) +{ + double peakRMSperChannel = GetMediaItemPeakRMS_NonWindowed(item); + return peakRMSperChannel; +} + double NF_GetMediaItemAverageRMS(MediaItem* item) { - double avrgRMS = GetMediaItemAverageRMS(item); - return avrgRMS; + double averageRMS = GetMediaItemAverageRMS(item); + return averageRMS; + } // #880 diff --git a/Breeder/BR_ReaScript.h b/Breeder/BR_ReaScript.h index f072b0d5c..63ee025bc 100644 --- a/Breeder/BR_ReaScript.h +++ b/Breeder/BR_ReaScript.h @@ -99,7 +99,9 @@ bool BR_Win32_WritePrivateProfileString (const char* sectionName, con // #781 double NF_GetMediaItemMaxPeak(MediaItem* item); +double NF_GetMediaItemPeakRMS_Windowed(MediaItem* item); double NF_GetMediaItemAverageRMS(MediaItem* item); +double NF_GetMediaItemPeakRMS_NonWindowed(MediaItem* item); // #880 bool NF_AnalyzeTakeLoudness_IntegratedOnly(MediaItem_Take* take, double* lufsIntegratedOut); diff --git a/Misc/Analysis.cpp b/Misc/Analysis.cpp index b6b2252aa..1544db035 100644 --- a/Misc/Analysis.cpp +++ b/Misc/Analysis.cpp @@ -268,15 +268,16 @@ double GetMediaItemMaxPeak(MediaItem* mi) } } -double GetMediaItemAverageRMS(MediaItem* mi) +double GetMediaItemPeakRMS_Windowed(MediaItem* mi) { - double curAvrgRMS = -150.0; - double maxAvrgRMS = -150.0; + // double curPeakRMS = -150.0; + // double maxPeakRMS = -150.0; // if MIDI item, don't scan double sampleRate = ((PCM_source*)mi)->GetSampleRate(); // will rtn. 0 for MIDI items if (sampleRate == 0.0) return -150.0; + /* int iChannels = ((PCM_source*)mi)->GetNumChannels(); if (iChannels) { @@ -285,21 +286,105 @@ double GetMediaItemAverageRMS(MediaItem* mi) a.iChannels = iChannels; a.dRMSs = new double[iChannels]; + // set window size + char str[100]; + GetPrivateProfileString(SWS_INI, SWS_RMS_KEY, "-20,0.1", str, 100, get_ini_file()); + char* pWindow = strchr(str, ','); + a.dWindowSize = pWindow ? atof(pWindow + 1) : 0.1; + + if (AnalyzeItem(mi, &a)) { for (int i = 0; i < iChannels; i++) { - curAvrgRMS = VAL2DB(a.dRMSs[i]); - if (maxAvrgRMS < curAvrgRMS) { - maxAvrgRMS = curAvrgRMS; + curPeakRMS = VAL2DB(a.dRMSs[i]); + if (maxPeakRMS < curPeakRMS) { + maxPeakRMS = curPeakRMS; } } } delete[] a.dRMSs; - return maxAvrgRMS; + return maxPeakRMS; + } else { + return -150.0; + } + */ + + ANALYZE_PCM a; + memset(&a, 0, sizeof(a)); + + char str[100]; + GetPrivateProfileString(SWS_INI, SWS_RMS_KEY, "-20,0.1", str, 100, get_ini_file()); + char* pWindow = strchr(str, ','); + a.dWindowSize = pWindow ? atof(pWindow + 1) : 0.1; + + if (AnalyzeItem(mi, &a)) { + return VAL2DB(a.dRMS); + } else { + return -150.0; + } +} + +double GetMediaItemPeakRMS_NonWindowed(MediaItem* mi) +{ + double curPeakRMS = -150.0; + double maxPeakRMS = -150.0; + + // if MIDI item, don't scan + double sampleRate = ((PCM_source*)mi)->GetSampleRate(); // will rtn. 0 for MIDI items + if (sampleRate == 0.0) return -150.0; + + + int iChannels = ((PCM_source*)mi)->GetNumChannels(); + if (iChannels) + { + ANALYZE_PCM a; + memset(&a, 0, sizeof(a)); + a.iChannels = iChannels; + a.dRMSs = new double[iChannels]; + + /* + // set window size + char str[100]; + GetPrivateProfileString(SWS_INI, SWS_RMS_KEY, "-20,0.1", str, 100, get_ini_file()); + char* pWindow = strchr(str, ','); + a.dWindowSize = pWindow ? atof(pWindow + 1) : 0.1; + */ + + if (AnalyzeItem(mi, &a)) + { + for (int i = 0; i < iChannels; i++) { + curPeakRMS = VAL2DB(a.dRMSs[i]); + if (maxPeakRMS < curPeakRMS) { + maxPeakRMS = curPeakRMS; + } + } + } + + delete[] a.dRMSs; + return maxPeakRMS; } else { + return -150.0; + } +} + +double GetMediaItemAverageRMS(MediaItem* mi) +{ + double sampleRate = ((PCM_source*)mi)->GetSampleRate(); // will rtn. 0 for MIDI items + if (sampleRate == 0.0) return -150.0; + + ANALYZE_PCM a; + memset(&a, 0, sizeof(a)); + a.dWindowSize = 0.0; // non-windowed + + + if (AnalyzeItem(mi, &a)) { + return VAL2DB(a.dRMS); + } + else { return -150.0; } -} // /#781 +} +// /#781 void FindItemPeak(COMMAND_T*) { diff --git a/Misc/Analysis.h b/Misc/Analysis.h index f709adaa3..aed3d46a7 100644 --- a/Misc/Analysis.h +++ b/Misc/Analysis.h @@ -52,4 +52,6 @@ bool AnalyzeItem(MediaItem* mi, ANALYZE_PCM* a); // #781 double GetMediaItemMaxPeak(MediaItem*); +double GetMediaItemPeakRMS_Windowed(MediaItem*); double GetMediaItemAverageRMS(MediaItem*); +double GetMediaItemPeakRMS_NonWindowed(MediaItem*); \ No newline at end of file diff --git a/ReaScript.cpp b/ReaScript.cpp index 6ced46e72..80cfa664b 100644 --- a/ReaScript.cpp +++ b/ReaScript.cpp @@ -231,9 +231,11 @@ APIdef g_apidefs[] = { APIFUNC(ULT_GetMediaItemNote), "const char*", "MediaItem*", "item", "[ULT] Get item notes.", }, { APIFUNC(ULT_SetMediaItemNote), "void", "MediaItem*,const char*", "item,note", "[ULT] Set item notes.", }, - // #781 - { APIFUNC(NF_GetMediaItemMaxPeak), "double", "MediaItem*", "item", "Returns the greatest max. peak value of active channels of an audio item active take, post item gain, post take volume envelope, post-fade, pre fader, pre item FX. Returns -150.0 if MIDI item or empty item.", }, - { APIFUNC(NF_GetMediaItemAverageRMS), "double", "MediaItem*", "item", "Returns the RMS peak level of active channels of an audio item active take, post item gain, post take volume envelope, post-fade, pre fader, pre item FX. Returns -150.0 if MIDI item or empty item.", }, + // #781 + { APIFUNC(NF_GetMediaItemMaxPeak), "double", "MediaItem*", "item", "Returns the greatest max. peak value of all active channels of an audio item active take, post item gain, post take volume envelope, post-fade, pre fader, pre item FX. \n Returns -150.0 if MIDI take or empty item.", }, + { APIFUNC(NF_GetMediaItemPeakRMS_Windowed), "double", "MediaItem*", "item", "Returns the average RMS peak level of all active channels of an audio item active take, post item gain, post take volume envelope, post-fade, pre fader, pre item FX. \n Obeys 'Window size for peak RMS' setting in 'SWS: Set RMS analysis/normalize options' for calculation. Returns -150.0 if MIDI take or empty item.", }, + { APIFUNC(NF_GetMediaItemPeakRMS_NonWindowed), "double", "MediaItem*", "item", "Returns the greatest overall (non-windowed) RMS peak level of all active channels of an audio item active take, post item gain, post take volume envelope, post-fade, pre fader, pre item FX. \n Returns -150.0 if MIDI take or empty item.", }, + { APIFUNC(NF_GetMediaItemAverageRMS), "double", "MediaItem*", "item", "Returns the average overall (non-windowed) RMS level of active channels of an audio item active take, post item gain, post take volume envelope, post-fade, pre fader, pre item FX. \n Returns -150.0 if MIDI take or empty item.", }, // #880 { APIFUNC(NF_AnalyzeTakeLoudness_IntegratedOnly), "bool", "MediaItem_Take*,double*", "take,lufsIntegratedOut", "Does LUFS integrated analysis only. Faster than full loudness analysis (NF_AnalyzeTakeLoudness) . Use this if only LUFS integrated is required." }, @@ -294,4 +296,4 @@ bool RegisterExportedAPI(reaper_plugin_info_t* _rec) } } return ok; -} \ No newline at end of file +} diff --git a/reascript_vararg.h b/reascript_vararg.h index 8572261f3..3616d4fc8 100644 --- a/reascript_vararg.h +++ b/reascript_vararg.h @@ -543,6 +543,22 @@ static void* __vararg_NF_GetMediaItemMaxPeak(void** arglist, int numparms) return p; } +static void* __vararg_NF_GetMediaItemPeakRMS_Windowed(void** arglist, int numparms) +{ + double* p =(double*)arglist[numparms-1]; + double d = NF_GetMediaItemPeakRMS_Windowed((MediaItem*)arglist[0]); + if (p) *p=d; + return p; +} + +static void* __vararg_NF_GetMediaItemPeakRMS_NonWindowed(void** arglist, int numparms) +{ + double* p =(double*)arglist[numparms-1]; + double d = NF_GetMediaItemPeakRMS_NonWindowed((MediaItem*)arglist[0]); + if (p) *p=d; + return p; +} + static void* __vararg_NF_GetMediaItemAverageRMS(void** arglist, int numparms) { double* p =(double*)arglist[numparms-1];