// Copyright 2019 , tb-software.com
// All rights reserved.
//
//Redistribution and use in source and binary forms, with or without modification, are permitted 
//provided that the following conditions are met:
//
//Redistributions of source code must retain the above copyright notice, this list of conditions 
//and the following disclaimer. 
//
//Redistributions in binary form must reproduce the above copyright notice, this list of conditions 
//and the following disclaimer in the documentation and/or other materials provided with the distribution. 
//
//The name of tb-software.com may not be used to endorse or 
//promote products derived from this software without specific prior written permission. 
//
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 
//IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
//FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 
//BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
//(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
//PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
//STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
//THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// EBUR128 Loudness Measurement
// by TBProAudio 2019 (www.tb-software.com)

// Changelog
// 1.0: First public release
// 1.1: Changed of usage of Memory Manager, Write automation data
// 1.2: Added TimerClass to controll update of display and automation data more precisely
// 1.3: Rearrangement of includes
// 1.4: Increased precision, Multichannel Support, reduced number of ext libraries
// 1.5: Improved TP Measurement
// 1.6: Added srate
// 1.7: TP Measurement based on ITU 1770
// 1.8: Synced Measurement
// 1.9: Small fixes
// 2.0: TP measurement adjusted according BS 1770 beyond 44/48K
// 2.1: SL/ML update every 100ms according EBU R128 spec
// 2.2: Small adjustment of 2x FIR filter
// 2.3: TB-Measurement according BS.1770-4
// 2.4: More LRA info, LRA buffer fix
// 2.5: TP display fix
// 2.6: Automation timer set to 100ms
// 2.7: add. Automation data switch, off avoids undo data; fix sync mode (sync resets before start playing)
// 2.8: Small adjustments for tiny EBU
// 2.9: Small adjustments for tiny EBU
// 2.10: Fixed DAW sync while recording

desc:EBUR128 Loudness Measurement V2.10 (TBProAudio)
import memorymanager.jsfx-inc
import ebur128.jsfx-inc

//////////////////////////////////////
// Hidden Slider to provide Automation data
slider1:-144<-70,24,0.1>-_OUT: IL Disp
slider2:-144<-144,24,0.1>-_OUT: ML Disp
slider3:-144<-144,24,0.1>-_OUT: ML Max Disp
slider4:-144<-144,24,0.1>-_OUT: SL Disp
slider5:-144<-144,24,0.1>-_OUT: SL Max Disp
slider6:-144<-144,24,0.1>-_OUT: TP Disp
slider7:0<0,144,0.1>-_OUT: LRA Disp
////////////////////////////////////////

slider9:0<0,3,{2.0 Stereo,4.0 Surround,4.1 Surround,5.1 Surround>Channel Config
slider11:-144<-70,24,0.1>IL LUFS
slider12:-144<-144,24,0.1>ML LUFS
slider13:-144<-144,24,0.1>ML Max LUFS
slider14:-144<-144,24,0.1>SL LUFS
slider15:-144<-144,24,0.1>SL Max LUFS
slider16:-144<-144,24,0.1>TP dB
slider17:0<0,144,0.1>LRA LU

slider61:1<0,1,1{Off,On}>Synced
slider62:1<0,1,1{Off,On}>Automation Data

slider21:-144<-144,6,0.01>-test
slider22:-144<-144,6,0.01>-test
slider23:-144<-144,6,0.01>-test
slider24:0<0,36000,1>-test

@init
  // Init our small mem manager, just to manage our own memory and align to foreign code/mem
  MM.MemMgr_Init(0);

  // EO@function

  EBUR128LM.LM_EBUR128_Init_MultiCh(srate);
  timer.EBU_Time_Init_Ms(100, srate);
 
  (slider62) ?
  (    
    slider1 = slider11;
    slider2 = slider12;
    slider3 = slider13;
    slider4 = slider14;
    slider5 = slider15;
    slider6 = slider16;
    slider7 = slider17;

    slider_automate(slider1);
    slider_automate(slider2);
    slider_automate(slider3);
    slider_automate(slider4);
    slider_automate(slider5);
    slider_automate(slider6);
    slider_automate(slider7);
  ); 
  
  SHOW_RLA_INFO = 0;
  
  ext_noinit = 1;
  last_play_state = play_state;

// EO@init

@slider
// EO@slider 

@block
// EO@block
 
@sample
  
  do_measure = 0;
  (slider61 == 0) ?
  (
    do_measure = 1;
  ):
  (
    ((play_state == 1) || (play_state == 5))? 
      do_measure = 1;

    (last_play_state != play_state) ?
      EBUR128LM.LM_EBUR128_Reset_MultiCh();  
  );

 last_play_state = play_state;

 (do_measure) ? 
  (
    EBUR128LM.LM_EBUR128_Process_MultiCh(spl0, spl1, spl2, spl3, spl4, spl5, slider9, 1, 1);
    
    (timer.EBU_Time_Count()) ?
    (    
      slider11 = EBUR128LM.LM_EBUR128_GetIL_LUFS();
      slider12 = EBUR128LM.LM_EBUR128_GetML_LUFS();
      slider13 = EBUR128LM.LM_EBUR128_GetMLMax_LUFS();
      slider14 = EBUR128LM.LM_EBUR128_GetSL_LUFS();
      slider15 = EBUR128LM.LM_EBUR128_GetSLMax_LUFS();
      slider16 = EBUR128LM.LM_EBUR128_GetTP_dbFS();
      slider17 = EBUR128LM.LM_EBUR128_GetLRA_LU();
      
      slider21 = EBUR128LM.LM_EBUR128_GetLRA_Low();
      slider22 = EBUR128LM.LM_EBUR128_GetLRA_High();
      slider23 = EBUR128LM.LM_EBUR128_GetLRA_LU();
      slider24 = EBUR128LM.LM_EBUR128_GetLRA_Count();
  
      (slider62) ?
      (    
        slider1 = slider11;
        slider2 = slider12;
        slider3 = slider13;
        slider4 = slider14;
        slider5 = slider15;
        slider6 = slider16;
        slider7 = slider17;
        
        slider_automate(slider1);
        slider_automate(slider2);
        slider_automate(slider3);
        slider_automate(slider4);
        slider_automate(slider5);
        slider_automate(slider6);
        slider_automate(slider7);    
      );
    )
  );
// EO@sample

@gfx 400 50

  (SHOW_RLA_INFO)?
  (
  // Max dB Value
  gfx_r=gfx_g=gfx_b=1.0; gfx_a=1.0;
  gfx_x = 0;
  gfx_y = 10;
  gfx_drawstr("LRA Low : ");
  gfx_drawnumber(slider21,2);
  gfx_drawstr(" db"); 

  gfx_x = 0;
  gfx_y = 20;
  gfx_drawstr("LRA High: ");
  gfx_drawnumber(slider22,2);
  gfx_drawstr(" db"); 

  gfx_x = 0;
  gfx_y = 30;
  gfx_drawstr("LRA Diff: ");
  gfx_drawnumber(slider23,2);
  gfx_drawstr(" db"); 

  gfx_x = 0;
  gfx_y = 40;
  gfx_drawstr("LRA Cont: ");
  gfx_drawnumber(slider24,0);
  );
  // Reset
  gfx_r = 0.0;
  gfx_g = 1.0;
  gfx_b = 0.0;
  gfx_a = 1.0;
  
  resetx = 380;
  reset_posY = 10;
    
  gfx_x = resetx;
  gfx_y = reset_posY;
  gfx_drawchar($'R');
  gfx_drawchar($'E');
  gfx_drawchar($'S');
  gfx_drawchar($'E');
  gfx_drawchar($'T');
  resetx2 = gfx_x;
  
  doreset = 0;
  mouse_cap ?
  (
    mouse_x >= resetx && 
    mouse_x <= resetx2 && 
    mouse_y >= reset_posY && 
    mouse_y <= reset_posY+gfx_texth 
    ? doreset = 1;
  );
  
  doreset ?
  (
    
      EBUR128LM.LM_EBUR128_Reset_MultiCh();
    
      slider11 = EBUR128LM.LM_EBUR128_GetIL_LUFS();
      slider12 = EBUR128LM.LM_EBUR128_GetML_LUFS();
      slider13 = EBUR128LM.LM_EBUR128_GetMLMax_LUFS();
      slider14 = EBUR128LM.LM_EBUR128_GetSL_LUFS();
      slider15 = EBUR128LM.LM_EBUR128_GetSLMax_LUFS();
      slider16 = EBUR128LM.LM_EBUR128_GetTP_dbFS();
      slider17 = EBUR128LM.LM_EBUR128_GetLRA_LU();
      
      slider21 = EBUR128LM.LM_EBUR128_GetLRA_Low();
      slider22 = EBUR128LM.LM_EBUR128_GetLRA_High();
      slider23 = EBUR128LM.LM_EBUR128_GetLRA_LU();
      slider24 = EBUR128LM.LM_EBUR128_GetLRA_Count();
  
      (slider62) ?
      (    
  
        slider1 = slider11;
        slider2 = slider12;
        slider3 = slider13;
        slider4 = slider14;
        slider5 = slider15;
        slider6 = slider16;
        slider7 = slider17;
      
        slider_automate(slider1);
        slider_automate(slider2);
        slider_automate(slider3);
        slider_automate(slider4);
        slider_automate(slider5);
        slider_automate(slider6);
        slider_automate(slider7); 
      );
  );
// EOL@GFX
