Announcement

Collapse
No announcement yet.

Trying to port the C++ code for Microsoft sample of Peak Meter to PowerBASIC

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • #21
    ISOBJECT is your friend.

    Comment


    • #22
      Hi Francisco,

      Thanks for a such an interesting thread

      Re. COM tutorials, Larry Charlton wrote a set of most helpful notes on creating Objects here.

      I couldn't find any reference to CoCreateInstance() in those notes nor in PB's help file though so I'm not sure how it compares with using NEWCOM CLSID ClassID$..
      Maybe it's part of the things that PB takes care of behind the scenes?

      Still very much a newby on the COM path but here's another take on a DDT version of the Peak Meter I've been playing with while trying to keep up with the expert advice you've been getting.

      [CODE]'
      Code:
      #Compile Exe                            ' JR Includes
      #Dim All
      #INCLUDE "WIN32API.INC"
      #INCLUDE "mmdeviceapi.inc"
      #INCLUDE "endpointvolume.inc"
      
      %IDC_STATIC_MINVOL  = 1001
      %IDC_STATIC_MAXVOL  = 1002
      %IDC_PEAK_METER     = 1003
      '------------------
      
      CallBack Function DlgProc()
       Static pEnumerator As IMMDeviceEnumerator         ' Objvar to enumerate multimedia device resources
       Static pDevice     As IMMDevice                   ' Objvar for (default) audio endpoint Interface
       Static pMeterInfo  As IAudioMeterInformation      ' Objvar for audio stream peak meter interface
      
        Select Case As Long Cb.Msg
          Case %WM_InitDialog
           Local hr As Long
      
            pEnumerator = NEWCOM CLSID $CLSID_MMDeviceEnumerator    ' Obtain COM Object reference / Instance variable
            If IsObject(pEnumerator) Then
              pEnumerator.GetDefaultAudioEndpoint(%EDataFlow_eRender, %DEVICE_STATE_ACTIVE, pDevice)
              If IsObject(pDevice) Then
                pDevice.Activate($IID_IAudioMeterInformation, %CLSCTX_ALL, $NUL, pMeterInfo)
                If IsNothing(pMeterInfo) Then Function = 0 : Exit Function
              End If
            Else
              ? "COM Error" : Function = 0 : Exit Function
            End If
      
            SetTimer Cb.Hndl, %IDC_PEAK_METER, 025, 0   ' use Peak Meter ID as idTimer :)
      
          CASE %WM_TIMER
            Select Case As Long Cb.wParam
              CASE %IDC_PEAK_METER
               Local peak As Single, colour As Long
                hr = pMeterInfo.GetPeakValue(peak)
                colour = IIF(peak>0.85 , %Red, %Green)
                Control Send Cb.Hndl, %IDC_PEAK_METER, %PBM_SETBARCOLOR, 0, colour
                ProgressBar Set Pos Cb.Hndl, %IDC_PEAK_METER, peak*100
            End Select
      
          Case %WM_Command
            Select Case As Long Cb.Ctl
              Case %IdCancel
                If Cb.CtlMsg = %BN_Clicked Then
                  Dialog End Cb.Hndl
                End If
            End Select
      
          Case %WM_SysCommand
            If (CbWParam And &HFFF0) = %SC_Close Then
              Dialog End Cb.Hndl, 0
            End If
      
          Case %WM_Destroy
            KillTimer Cb.Hndl, %IDC_PEAK_METER
            pMeterInfo  = Nothing
            pDevice     = Nothing
            pEnumerator = Nothing
        End Select
      End Function
      '------------------/DlgProc
      
      Function PBMain()
       Local hDlg  As Dword
        Dialog Font "Arial Rounded MT Bold", 8
        Dialog New 0, "Peak Meter", 10, 10, 150, 40, %WS_Caption Or %WS_SysMenu, To hDlg
          Control Add Progressbar, hDlg, %IDC_PEAK_METER, "",34,14,82,5, %PBS_SMOOTH
          Control Add Label, hDlg, %IDC_STATIC_MINVOL, "Min",10,12,20,12
          Control Add Label, hDlg, %IDC_STATIC_MAXVOL, "Max",120,12,20,12
        Dialog Show Modal hDlg, Call DlgProc
      End Function
      '------------------/PbMain
      Rgds, Dave

      Comment


      • #23
        Hi Dave, Interesting the use you do to the progressbar. Neat.

        Thanks for your posting


        I wonder why you, as well as Pierre, assign a value of 25 ms to the timer instead of 1 ms or greater than 25 ms. Peaks are very fast transients and the meter should be able to detect and show them. If the bar changes color is very easy to spot this peaks, otherwise they are hidden between measurements.

        I took the following from a recording engineer guru, John M. Woram "The Recording Studio Handbook", First Edition, 1982, Sixth Printing, Updated, page 41:

        The Peak Reading Meter

        The peak reading meter is more responsive to actual program peaks. Its ballistics are such that it will more accurately track the attacks of sudden high-level transient peaks. But since these peaks may be over just as suddenly as they occur, the movement is usually tailored to provide a more gradual fall-off, lest the rapid up and down movement be too fast for the eye to see.


        From the above we can gather that the fast and sudden surge in the peak value must be shown but it also be kept lingering a little longer than the rapid fall of the peak allows so it can be easily noticed by the eye. The fisrt part is already achieved by using the minimum possible value for the timer to update the meter (whatever that may be) but up to now the second part is not addressed in all our codes (and I wouldn't know how, just from the top of my head) but it would be nicer if we can find a way to do it. I will try to find out a way. Someday.

        Also I would suggest that the meter could be tweeked to choose the attact, release and calibration values desired by the user.
        And what about making a stereo peak meter or right out a multichannel one (for 5.1 and 7.1 outputs) to begin with.

        For non-profesional use this meters are fantastic but if you wanted a more accurate meter it would need to have some improvements. I'll keep looking around to see if there's any available.
        Last edited by Francisco Castanedo; 3 Dec 2018, 08:16 PM.
        Francisco J Castanedo
        Software Developer
        Distribuidora 3HP, C.A.
        [URL]http://www.distribuidora3hp.com[/URL]

        Comment


        • #24
          > but up to now the second part is not addressed in all our codes (and I wouldn't know how, just from the top of my head) but it would be nicer if we can find a way to do it. I will try to find out a way. Someday.

          Something along the lines of the following aircode should do it.


          Code:
          ...
          Static delay as long
          Static LastPeak as single
          local lngDwellTime as long
          lngDwellTime = 50
          ...  
          CASE %IDC_PEAK_METER
                   Local peak As Single, colour As Long
                Incr delay
                  hr = pMeterInfo.GetPeakValue(peak)
                  colour = IIF(peak>0.85 , %Red, %Green)
                  Control Send Cb.Hndl, %IDC_PEAK_METER, %PBM_SETBARCOLOR, 0, colour
                if peak > lastpeak or delay > lngDwellTime  'only update the meter if the peak is higher or the "dwell time" has expired
                        ProgressBar Set Pos Cb.Hndl, %IDC_PEAK_METER, peak*100
                       Delay = 0
                      lastpeak = peak
                  end if 

          Comment


          • #25
            Francisco, the 25 millisecond choice was purely arbitrary on my side, so, no real meaning behind it...

            Comment


            • #26
              I used 25ms so that I could run your code from post#11 alongside Pierre's and mine all at the same time to see if I could spot any differences in performance

              Wikipedia has an image that shows a 'typical' VU meter response against the instantaneous output that it follows..

              Click image for larger version

Name:	375px-VU-meter-reponse-graph_svg.png
Views:	1
Size:	25.0 KB
ID:	776783
              It would be interesting to plot the 'peak' values that pMeterInfo.GetPeakValue(peak) provides to see if they appear to have been subjected to some 'shaping' at source?

              The MS original article says "If the audio endpoint device implements the peak meter in hardware, the IAudioMeterInformation interface uses the hardware peak meter. Otherwise, the interface implements the peak meter in software"... 'implements' is a suggestive word !
              Rgds, Dave

              Comment


              • #27
                I Love this topic and I will dwelve deeper into it. Unfortunately I'm going out of town for a few days and I won´t have a computer or the time to do it.
                Once I'm back I'll get down to make a better peak meter, and who knows if we can get into the VU meters as well.
                Francisco J Castanedo
                Software Developer
                Distribuidora 3HP, C.A.
                [URL]http://www.distribuidora3hp.com[/URL]

                Comment


                • #28
                  Have a safe trip Francisco!
                  Rgds, Dave

                  Comment


                  • #29
                    Greetings!
                    Back at home safely again! And with a lot of work in front of me. I'll retake the meter improvement in a short time.

                    Thanks for your whish Dave.



                    Francisco J Castanedo
                    Software Developer
                    Distribuidora 3HP, C.A.
                    [URL]http://www.distribuidora3hp.com[/URL]

                    Comment

                    Working...
                    X