From ba89a58ecef0ac976160e2287ee0ae692ed197ef Mon Sep 17 00:00:00 2001 From: onyx-and-iris Date: Sat, 27 May 2023 19:16:48 +0100 Subject: [PATCH] Add project files. --- .gitattributes | 63 + .gitignore | 363 +++ INSTALL.md | 23 + LICENSE | 22 + README.md | 14 + vmr_streamer.sln | 31 + vmr_streamer/Resource.h | 30 + vmr_streamer/framework.h | 15 + vmr_streamer/img/vm1-inst.png | Bin 0 -> 12773 bytes vmr_streamer/img/vm2-inst.png | Bin 0 -> 940290 bytes vmr_streamer/img/vm3-inst.png | Bin 0 -> 37056 bytes vmr_streamer/img/vm4-inst.png | Bin 0 -> 21711 bytes vmr_streamer/img/vm5-inst.png | Bin 0 -> 27799 bytes vmr_streamer/small.ico | Bin 0 -> 46227 bytes .../source/SourceCodeOrganization.jpg | Bin 0 -> 178255 bytes vmr_streamer/source/StripCTL_Design.jpg | Bin 0 -> 112623 bytes vmr_streamer/source/Thumbs.db | Bin 0 -> 23040 bytes vmr_streamer/source/VoicemeeterRemote.h | 974 ++++++ vmr_streamer/source/streamer_ctrl.c | 1924 ++++++++++++ vmr_streamer/source/streamer_ctrl.h | 199 ++ vmr_streamer/source/vban_cmd.c | 600 ++++ vmr_streamer/source/vban_cmd.h | 121 + vmr_streamer/source/vmr_streamer.c | 2768 +++++++++++++++++ vmr_streamer/source/vmr_streamer.h | 83 + vmr_streamer/source/vmr_streamer.ico | Bin 0 -> 7358 bytes vmr_streamer/source/vmr_streamer.rc | 78 + vmr_streamer/targetver.h | 6 + vmr_streamer/vmr_streamer.cpp | 180 ++ vmr_streamer/vmr_streamer.vcxproj | 165 + vmr_streamer/vmr_streamer.vcxproj.filters | 58 + 30 files changed, 7717 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 INSTALL.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 vmr_streamer.sln create mode 100644 vmr_streamer/Resource.h create mode 100644 vmr_streamer/framework.h create mode 100644 vmr_streamer/img/vm1-inst.png create mode 100644 vmr_streamer/img/vm2-inst.png create mode 100644 vmr_streamer/img/vm3-inst.png create mode 100644 vmr_streamer/img/vm4-inst.png create mode 100644 vmr_streamer/img/vm5-inst.png create mode 100644 vmr_streamer/small.ico create mode 100644 vmr_streamer/source/SourceCodeOrganization.jpg create mode 100644 vmr_streamer/source/StripCTL_Design.jpg create mode 100644 vmr_streamer/source/Thumbs.db create mode 100644 vmr_streamer/source/VoicemeeterRemote.h create mode 100644 vmr_streamer/source/streamer_ctrl.c create mode 100644 vmr_streamer/source/streamer_ctrl.h create mode 100644 vmr_streamer/source/vban_cmd.c create mode 100644 vmr_streamer/source/vban_cmd.h create mode 100644 vmr_streamer/source/vmr_streamer.c create mode 100644 vmr_streamer/source/vmr_streamer.h create mode 100644 vmr_streamer/source/vmr_streamer.ico create mode 100644 vmr_streamer/source/vmr_streamer.rc create mode 100644 vmr_streamer/targetver.h create mode 100644 vmr_streamer/vmr_streamer.cpp create mode 100644 vmr_streamer/vmr_streamer.vcxproj create mode 100644 vmr_streamer/vmr_streamer.vcxproj.filters diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9491a2f --- /dev/null +++ b/.gitignore @@ -0,0 +1,363 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd \ No newline at end of file diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000..76869e7 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,23 @@ +# Step by step + +These instructions should work for both Debug/Release builds. In this case we target Release x64. + +![Release][release] + +Open up project properties.
+![Properties][properties] + +In advanced properties ensure `Character Set` is set to `Not Set` +![Character Set][char_set] + +Check that `_CRT_SECURE_NO_DEPRECATE` and if targeting an x64 build `VB_X64` are in the preprocessor definitions. +![Preprocessor Definitions][pp_def] + +Ensure `Ws2_32.lib` is included as an additional dependency. +![Linker dependencies][linker] + +[release]: vmr_streamer/img/vm1-inst.png +[properties]: vmr_streamer/img/vm2-inst.png +[char_set]: vmr_streamer/img/vm3-inst.png +[pp_def]: vmr_streamer/img/vm4-inst.png +[linker]: vmr_streamer/img/vm5-inst.png diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c75366d --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +MIT License (with one restriction) + +Copyright (c) 2021 Vincent Burel + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software and the created Software Application +must interact with the VoicemeeterRemote API. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..03e5463 --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +# Voicemeeter Streamer View App + +Source files for [Voicemeeter Streamer View App][streamer_view_app] which can be found in the [applications SDK](https://github.com/vburel2018/Voicemeeter-SDK). + +### Build + +For a step-by-step follow [these instructions][install]. + +### Special Thanks + +Vincent Burel for creating Voicemeeter, its SDK and the various apps released as part of it. + +[install]: INSTALL.md +[streamer_view_app]: https://voicemeeter.com/the-voicemeeter-streamer-view-app-overview/ diff --git a/vmr_streamer.sln b/vmr_streamer.sln new file mode 100644 index 0000000..723514c --- /dev/null +++ b/vmr_streamer.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.6.33723.286 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vmr_streamer", "vmr_streamer\vmr_streamer.vcxproj", "{CB959FDD-2AA4-4ECD-8A50-41777BF38EEA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CB959FDD-2AA4-4ECD-8A50-41777BF38EEA}.Debug|x64.ActiveCfg = Debug|x64 + {CB959FDD-2AA4-4ECD-8A50-41777BF38EEA}.Debug|x64.Build.0 = Debug|x64 + {CB959FDD-2AA4-4ECD-8A50-41777BF38EEA}.Debug|x86.ActiveCfg = Debug|Win32 + {CB959FDD-2AA4-4ECD-8A50-41777BF38EEA}.Debug|x86.Build.0 = Debug|Win32 + {CB959FDD-2AA4-4ECD-8A50-41777BF38EEA}.Release|x64.ActiveCfg = Release|x64 + {CB959FDD-2AA4-4ECD-8A50-41777BF38EEA}.Release|x64.Build.0 = Release|x64 + {CB959FDD-2AA4-4ECD-8A50-41777BF38EEA}.Release|x86.ActiveCfg = Release|Win32 + {CB959FDD-2AA4-4ECD-8A50-41777BF38EEA}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {00B208A7-9AA5-482F-9929-0DE2CB5EA336} + EndGlobalSection +EndGlobal diff --git a/vmr_streamer/Resource.h b/vmr_streamer/Resource.h new file mode 100644 index 0000000..af1e53f --- /dev/null +++ b/vmr_streamer/Resource.h @@ -0,0 +1,30 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by vmr_streamer.rc + +#define IDS_APP_TITLE 103 + +#define IDR_MAINFRAME 128 +#define IDD_VMRSTREAMER_DIALOG 102 +#define IDD_ABOUTBOX 103 +#define IDM_ABOUT 104 +#define IDM_EXIT 105 +#define IDI_VMRSTREAMER 107 +#define IDI_SMALL 108 +#define IDC_VMRSTREAMER 109 +#define IDC_MYICON 2 +#ifndef IDC_STATIC +#define IDC_STATIC -1 +#endif +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS + +#define _APS_NO_MFC 130 +#define _APS_NEXT_RESOURCE_VALUE 129 +#define _APS_NEXT_COMMAND_VALUE 32771 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 110 +#endif +#endif diff --git a/vmr_streamer/framework.h b/vmr_streamer/framework.h new file mode 100644 index 0000000..33a6be6 --- /dev/null +++ b/vmr_streamer/framework.h @@ -0,0 +1,15 @@ +// header.h : include file for standard system include files, +// or project specific include files +// + +#pragma once + +#include "targetver.h" +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files +#include +// C RunTime Header Files +#include +#include +#include +#include diff --git a/vmr_streamer/img/vm1-inst.png b/vmr_streamer/img/vm1-inst.png new file mode 100644 index 0000000000000000000000000000000000000000..60a66f3e78803c14259a6966cfd53f3c65364a48 GIT binary patch literal 12773 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 literal 0 HcmV?d00001 diff --git a/vmr_streamer/img/vm2-inst.png b/vmr_streamer/img/vm2-inst.png new file mode 100644 index 0000000000000000000000000000000000000000..73dcd963db52979f97a1f751b0bd9226d654bf2d GIT binary patch literal 940290 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
lpnIm%y32Mi*b%+n$KY_Mav3N0rD$H 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 T+6BFZ0#E=7EJJ}a&iMZU173)b literal 0 HcmV?d00001 diff --git a/vmr_streamer/img/vm3-inst.png b/vmr_streamer/img/vm3-inst.png new file mode 100644 index 0000000000000000000000000000000000000000..311ffe4959ffee26dc1360ccfae930708ca9272a GIT binary patch literal 37056 zcmZU41yqya+dfJwjS7gQq)13gi}9Ukr3(HXhcLBBnJ!_(lAC3 z*oggS{J!7!Ki_-K4re_Wa^`0^nEJe>B;NtK+XYhoe`YtJ`c+O5OE{?%pxVJu!H6Pcno)*Umkbp z1C{Ubqenvf%RSLqRMda3*bmsSbF9+8>wZWV1^eIYE-xA2U!$>SRyAQC{$46K!kGRw z7S*HQVg1{zZ+W6YK>i_BB`~THJLD`wwY7L%R zf#l?5dn289^OIL=;3D(stE(1{r=Sft-Sc zSkSz#FMCS4{QhX1lL?XOsht^s**3>3HHZfxp_k>^u%s)mz5FWjZ`U!8_AQBl_q_4r zH_8|hdd*BUnd(xJHzcu-=J0CP?D_pJ!=DhY(4(kb8fn zB@1W*>DX>3WqZ;CgWo-k#MF?_4rF@6%2^@7LKk)*S*!8t*O=ZAO54LJZ`olOewWF5 ziyH)Xfo?;b_^_AySZ{tPdFN?@YJqsNCHI;@w47f`q-pm~MBBUWynth-fkCYhxxHZU zLwEEukVd*&{8ZXUHFCu?mw?T$7|Mg6*o}46RVOwQjeUL`=AW34J!}r#sJ=4jsC#g@ zA|KqdaCkVg^rMC-;ZMgu2jJfXWJExjbA4MZGoZnKe%e|anxm9tvwbo%iQlKxFRd^g z0_k}rLtuzIvM+ZsD095s%`oZE80ji9Y2za9erS9pyw~reF^QAxXUJW%m1$$_~X3FH6Gn3TUT4vW{ z!ac4_pVq*;`RwIod9*qr=TV194~X=%z1{p6IYe>fQI@w(eBQ)57LD!GIKf`&6dO37 zt=ZSddAsc04popp+pG2>0Dv%6Uc^F_ja@9O5j@O`Cryuc7?GtSKotQT)!?1 z;x}kH-A{BiBy{03@A*ce>XHizBNQdBB`YvdYBK=!3wCv18`~d2 z#0Y!GW`4MBXSc^;e%u9Hb)L86SFVIXxWs1Lo=1!*@Kp|c4MR>{*ljgJ2ZS(iECg%j zcGVwo2)~4YUQzljVQYWCE-xdzhQ@{AfmkGYNFSkapoi2tKj{T3EJgz zVZr>%IWx2rkmKUGO08Z|SxCm#Vxp~EWha3e7X1r>TWbLk$!8JSGav6=dGE;$&q4e3 zkMgnk8gG_QDN-+k%#?y(xR;x`n7Ck0vGnKOazw3_MzV0M&B6&1{^&gDBpRN?f@lHJ zYm^^~W><9@>hyN}i4Vt~Op-HW?gcBMa+Vu{h_IvS`x0x%U#ZBOvl4Q1O%Cy7ZwW{% zL?yp{8Fa$1A=K_=Gs?rTZGO&hy2+Og5g%Ip~dT%ucCA zqWsx1_psdJBCW;P+J+8RucK@&5Zl{nHX7zRHWDd;ZL|8^kIpZUCGLH@;tVwyG#Qn^ z_A6wAt_2`@&Qy)3A(}=r>+tly@nkVElpf_gD3fal#zs!K?OpH!Cl;M9)V68~!!qhzV01xS zFrK|+%zpe~4qADxv6?~JLA8GA>%;Jaz}-TBq@eGK@6SAVGK>6U60TXmoa@wrygLjx zf;!yDf$rM5)7a!pn%_uD9&w*gdIxfHRczAF`{+pdU6q06(su$Kw@rM^B;kYw+qsYt z9N;d+(H}wobPS|Jw3FGCD|+otiodcOYmdvs#u0G8r(q=#+`X`V8h$4wsbW3gWnN)> zdLon;8@#L+G_GB}@;DD5H5I|kE|C{L1U@cLPWoQGyeZxa_Z}d%w>n_C$!bw*gG#rG zxU%e`%Bh`o9-$~rkyxrd$DU(Pm^SgG-}Mk(1Ax#F_9KwLBaem%*Yv>xL-J`gsKUQ7 z2efa-aRm;%(@t^R6?iK6{di}yCxe!>?7Y8I^}g~TMwYgyW>DzFmfqV0mU_xw67Baw=mgD0hicBQBKQt>rAyD*8ca5k``%J){Ws#Eq}Ou@Hyb=fQj#ya zk1$FB4f$x<*u?;BN!wAZvTtQOjs*-L+=HjgoGH9~F5Uy8b!Ha6FE$+xWk2; z;_UF8!>sUyonpN!J#!eK&@_h*rk!#gFA%e->1wrggGO{pF;UN^# z?+Cq~S$0s|JObc_mtK%2b)G9ucv&t_&;m;N# zlCE#Qqty>JiKPB=Ajjj}Evtur+A1lD0&$$NP@nY3e~Iq-<9C0l%f4zd{}NN` z*c1_z^FyVt7B+0`?02>E(UaWshPd0Pis;EoPoFA3{rFB(TRY26mU{ff#nMiH_h>8E zQ_0HU1-1W>QrbttT@(aTyIR~uhx_W6rFQw@ZiqBlZv1~w$R)i`z4HVfI~nWK52uKX z8J3ECkeM?Ms{Ie|HF`wT6~}$f9(jJMR3gyK8{r?(wEC2OvF;_y>m(D4YRaHl3!RLM zpKkd|+NWL1`-K#2p8;vP# zl$CFHJ`6NFTJn*|O68TGzSPM$rT;Txj^43DLTN|o2YXHaxv$_7ArSnMzN4Rh^Hm*YO| zVMY(82(}?y91EeA>X0}f*`EpYmWt7=S>a`;+P%1ko_$2?N96%@l7XwfEo4uwF43Y| z#qkNd(OCtm`#34A+&`G`xNfz0~XMD(X2V8 z1$O0h^_-r9U0%3bMDBbGE`gTAY@RX#mHi-W*myB4=fV{}IxX-#Cix|jfQ$` z@cA4qDZw2d(q{(gbvtU7wHyJQ8ylP#(>!^NvLSAPKGYbw2sk-Lbl<=3C77u?xIt@Y3upt6iNMwGW zgxF>8A?z^qXs>@1yM4s9*Ai$52_9VSRy>yi%U&jlc(3A!bSTT^P5!+F%$rQX3tFvH z1vH81Ss321Xt|9AV*e;D(y}Mx;u-VhR{GjWc0N=%nB%bLbX5a{QPjdB6_L({!~>Va zt<~AbdyW{S1lCkPm;>Tds+#XRJ}lQ^CBiciuo%35?7oJuxKQhsbTbg3rp}dl$2%Qr zRQ7VC$e=vZWt!uaanf*VM#Ycr7BerUdK#12$($9fqrFs59$ex#@*$DoN9aes3_}~w z!%9p-5@I$A?Q@4fv5qo1^c4x%YD+ZH5pv%4kwHIc3Ryic!Ps)?dF~kr3|XWgp)h^= zwTs*mZ@rWLJXbIiioGhuSjtsXZdqhVAmCrW-#U~%nsZ6cp9~`d?f2-Y`_NG$ktpF# z6^M`Dpi+X$DrD{E%)a5?_Q7Rb;8AtWA?$1;0pL?GFW81kUq{LRybcPr!ET92$_sdI z!8)OJszd`9aqDS!xp{zN=cV4rEq zOmbv>!24Y?CnXIX`C)U1KGTwTDcv5KK>N_9p7_Xt^^RWIDgq|NL3k}Tkkbg;Y>Wj; zoIBnrTXh&dvF%_-x782l$A31Yw`Q}r2*Pbl5Kk)!#gH`RVml^IfTx>CAPcqn_={Bq zepfV(7mluWChle7^$(t*=x~uRCq|%gu4Jn$gfr=jB%|@Bm^?LgY+B+C097oFh|+83 zcDm3*C`n*NuInhu~n0#AgRtouO9k~FFqKp zh`yq$9S_Xtd%k^^EEuHSaY#36hlOLmYkABFul3?mj8ddDeEM)9k6B6S*wcz z&M?Vqh24piC6(90_&N;LB)D<&xE8-; z3cm7x(s4Bwzd8=x9hmAoi%dI!9VT~Xq{nxhNM|8RBj%v4Oy&R*sBs3=G>T1_1{u@xk3eg}mgb>QbLRek?U!$|S%_%$@Y*uT)~yM~hJ+^)){*!;ME ze6cqu0g8+WkZYo)9@{#|)Cu|)gacG>(VbZZQR@y*gevNn;9neccs`iNBn{H{(f^>* zyXsD;TIE0-eBih2?5k{GA%V!~JIe07_;@vFj?-GaTWTC|m`Hvj06>-Nd8S;DkKIZ~ zbn01yrc?jm#b$-||B`1SYJX-5M|HpY3%;Mn`Us`1%jFY657f|===g<{?kkmakjSav z8Vm%`UX>7#j#RXK1rt*b=bY(!)Q{_4Z16$3#S!M2k`lg%UiT~JE6r8k{KX{D(Q)T3 z^lXsC--qHhc@l2TUBHl7R%{PvkcX2&Fu45}#~(6GO+A(=EZh~B|0`b=s~vn_<~~UN zBD?OAgcN%XOTUSt&OTR+1flCLj(@R8IUSyIoT#2EKfsPxbW=Xax>Bv)D#u!ee`l3X z>oii%5}90W^}^}}@9zf(!A9o~@sLk40onX86D;Mr?z9d?F%0kz&!1yexMpfEMG`v& z8QD7zPB|_Z*|7%pO2H?4L*fKHSLi*g25*r2(1O{3a@@v3K4VAia~k%79?A#!mD{y$?(iaLNNjybC+T<{a$~taH*nX{zq&Qc z*Ua1fX;yNM&nGW{@SJ};xZ6)NEe}BYFm1c{rSascg}#m=Eb>DftsIMnQ6SOsOVCAr zv60q(@HCLTutS^ZV0O`68aB1C%e+*CkQPA3b;Fq5TU&!VTlib)E*tQP#?pe}tpK0+ zFXnOR$BX*%?#*GqYVE>>UMt&BCi-tQKdA1Ywb0}j@ZwHx&=D3xVcxF;;yR2M+=+T; zKa9cJVI)u%1fojpY(Ymm_81&*ye!RkK?NR;+j(JnDg>y*_fSATrx*gEJFnZme%YZ{{N&Z%b43PK_9x z;&Ge7J+{2>sXC2%q%D*uI}WO0E6M7$du2WZ41Jm$+Y3O|!DM-UbHRk=etDC0XV3-q zQ5V6(Y*66K0pFS_27&Pb_pL+uOT+q-(wMc&0A3%5dvAB5aZ zW7Y5}Lc3XJ7GyAg_y?)zO}&Z|+xxLpBys{eEZ>_}G&tM0C?p6VZ>*B~4&XSFNnU^Z zQfNN6OihLB^AWnQET% z{Sk{QQ)%Nu``t)O)#gxU8mxMhuRAo1ltlN!nSkeke9Gu$c%M9|kgjo{r9ZwP98yZO zes;#f9C=Y1KaFS?zH%5o%s2hIpVDaqbm>bTq0O^C8|v&3vboM}{uygAs5Eg5Ko-`M zQ+}hLv;0)B35XVe(9ctm+ZMAr;jj>uN6xvxM)gY6%&WeI70>d1$?SL+6{$%cKfJ_d zCPx0-_HW{3KG;}eQ3^gkb=p{NdIq%8K9a@;iAxg)U&%bySjf}q3?7Mx+APTHzoLyC zYT`vUzSe(&ee5C&zFYu@d~kgA%gcp5J@s|vgV}qbv=Q zXh0y>oHL)glzPyxT*Swh!8|W1=Qb|`-A;_)&eA4k`4#p)pKb+Ez8OcM#iWVFLFEYJ zdas2+j|S)X_cHW)(Wg!DIwV4m!PQlU`{#~3w0yQ%X22tF6&|(V{-}J9e0w~_e$S`= zl*YJm3dW2D)=RbWcA71^#WPfAE!bd~)?|?{h{2~AbDswjcfDH^!@)o->?>M@k~-k( z5)?LkC4C6C;s|BRaJV116^*&k{p23~faf(uqXF!|@#5LS-lbwB7K&}(LLHp0oo9Ip znSLkWwN+u?pmscKQ#%)Y%8oU?dU9luibZ!r8-&^vkRL}tn27W>XRJ%%VmAS8O5qg< zmnG{?6z9c}>PR<6kEDePoW(O?YnSl>rdW|h)5!h@;jfqEw;T&_?GdN&P*m#+O$R%5%F?80kbiVA!G(5%w*BPXBNzU4Imd+HIpkTb(272X4KWI16Gp85g(I1@hI68f=J3nDlwTb;L`WDe58lEyIu zE$y=b3p?g@`X;c0>E==&FlK%e%x{j2W2nA3%?MTv(rGRGl=&%b%hk6$U?_NdKb`SI z392)c(`)w<Jo` z6`QYt94;jscR#4B3sx;sl2$ta2?hE9vagcjh>BXA<*sWsC!!1eWk0pLBO;=9WRppQ zI^s&`jzzj6LopwRV%EX!6xJ)os$9IrHAZ_7(@t%aw{`1%h%~W*gnt374kIZatX=!^ zs3jNR`jmjt>A6{(g!1oww<%iJzVgEcGm8ir9bCRHm%lL#q+$7acHzukoF9ADEN$%c zl123Vo?ALg{%EaTpj`a#iNRFt73VIP=DRFZRyA{*uEysJnjFBYD&^_1}q@-Szqe1Ct%@z5co9B;7mZwg-wn#ye_fS@ENRNg}6_ILr1j;Ft85l?M<8)0%I< zuA~Dm`}S832jla-qLd|dsD_w(>syqM{xU$rwoathHe4M_5wylFr!!8U zF4J1mo$1J0I_%d_o)j2K=u#zwi9pIAZG+=Mc2;9+UO95W%|~165_xjI*!cQ4IG*_c ztJ_bLkaJO8U*Erv1PaEJzu1;^H%H1zw76<;FI<^*6~HGxJ&qH;Br;N!_&XFKSW8!^ zX!Ap0Myz3=2+^$I3$z7E0~B$FC}2l><9$oPGh z&gU1QS`hc24!x%Kax9k2#28UBZ|}NS!n`Lru%%bN{eBp!{d&;Jm%@0>X{y9+U>kLD z_OYDl2g96aO<$5gVze8DYPt9@BE0FAk1S8?jJtw60gj&H1&KfMGWq4uhse)gt3bC6 zxhx+^x{j~glJd^1QSB)KavQ!>Pi?#@zd$zpS-;>I11PsllOR&cHOeOYyf_4^2Hmh5 zboM1barUVSkc@MCfhuG&%@(oSbwXdJEo|p3&A={^;JIq}%DwLazA0Yw+wCfufQ3a3 zuruEx=zNVD+)p$&anXqejXnim5!I~CeWbGK{aK52F)f9~F1pC>eL^Bemq zxN}KqxVqq5)jtCFW>(bpp3}TC(ETTo?iL>U?k%Q5;TK<8#UKBV7Dmu{HdT$2u|HTm zFB^8*y!2Qp3hQ3ym@6A4#>8Z#zR+TktMe>GNyf{D`Q~g?!s|TdC1rPS2U>~5sWHay z7GdLbFz$9UIp5K8aZ=jOt=Uee@I(kXKhER*6!qI_E&Sy*-W8YZH^clc`E{urOP`Ve zE1jXZomh>BHLAy8A15BUvsA3exU2Fqo>K_Vc;xiX4*aH9$;pr5z0Z4{Tz&aIm(PM! zuf&CLelNuz^SFD%?s$jwkr&JNu;@Bg!k{-i6crE!J{(P}aY7{k?&hFQUi@y_dx%MIC7g-_QyZ!`T%aHK(u$fc6kk7_=H>N)j)6sCnhgDb&}u#L}I zOcUl#wFq%qYHB;wQ)F^;?G*osb&dK+4IjG10k5O1%_9Cyz4AN7 z2IXqC#>p<;Ci-t?UHHWX>hw&g8RBs%T2FxHs~=Q?6(L70SF++=ui>H!5Ni04;z0fL+7c3snbn;@ci_MRax$Tc8X_|SjUpZ*80TD(uR{Tnx&bv`I ziseJLA!qh?ueZMTb)D}fJ8mXNLUEzy15^HO`TpL9x-I9C!`<^fS z7~A$_smZGoNdc^mRuN_MWbcbY^OJMcvs_Q0MkV@Ly}4xGd=XDRh@`Ckm`G65=#(;| zOvnhi|JQ&V68C@S?Z87ipfRsK4KYh(G;>8vvknwYkW0v@&F{w`dR{==;f{XLOIX`} ztS)PfV@s}_^VmWi)85sUK;5D%Cx7cp#;h&yFu3)%rm5xkA)fA-?dm|momeOy>>O`5 zAIU0O1I=(Lv#sKMCA5mS^;}Evnep|mvyW_4)5?`1?FDOT5_hW%Pf*qdgMexsT7^W1 zO|t_2?Z(P}G^tUnbFhA0vb(flQYO04C?b<&V8{`r;im2-h{)?o+mPk1+-17(fwU~H z$PnD2Tx@k|o<9tV-a^MmB=e6_hG)-s?gWFGiiNk|Y^yRp3hY})QQEzp*4_(%YnLBg zTXbz-)S!Ou`jHCo>uYWrm?|nN+Tu?IJ*ZN_GM)Z!!pX+=^H`|;W$_C)X=j4M2a)p3&J zneK!u4}N#Dr_-^D$6>*6Qa8M}4t-9dGy(js!Bu@3puh)PNcV%E8(eHO!UK5Ox8cup zbb)$$zTnjhyJP+_9l3nKpAF=A_UrtbG}oOKPda>{f~)7jE>X+Gov~bTVfX1VdsfabaiTWG%YYl^iy4cY-mY17$|?W$%@Hugf183>a$3ly>QiHa&E0O3F8UVmhk?>U%*(oM`ShmOW2*; zx_f+7!u_|?r-y0F7}-<=!)TYAmO`W}DCaAIv3`x)jbpAR9+ei!lDw%b8XnSypnX@O z(Qh|criSp{(@o}$vuYSqgI|6i7Vx`M`y_4<3i zgEAT5_!?V;dN5dSh$GTU#GY0C+;!ou5`%ZkFMH=}5+*ny1*vci&fFyNh&~%uR&Eot z^JbPoI>xQE-8=sKm6Il5eetu^spee?YY|m}*4rlB5mh*h&luF0-Ku<>eiJsj4eil} ze>v@@;D6>?7@@pD3=EWZ=jKF~Rsv^5Xw80nIw(o5O#8_Sfe;NmtdN~%rv^G6*X=P> z{2O*aM~e9#{+sEj!AFsW8__Vgz16D6^1wq)pdfCP{onyP%l1dE4bm)OQX5K>%s76e z_zkAz%}<|@`ehLv(>tUr^GQOHUO&pUE@U?Y*($Yshrd4a%bo~#Mq4>rZV^~(X)Ul5 zU)8iJ>GibYoFGYPo+bEU z|C@`S-Md0yA9~Bj!vw)Sb_Bb(joVLEy8?I%SGsU!HHrX-I3RranMAQ9BASQBE(1LmvXgkf~8fmJ&ikeE1=}L$_KRsUKtgpO1%+*W~ z?!y}M=2a=O(hn9cOZzd0LC)HO+f%aty-<<;Ab|?b{%5$dp1|`7h*(+$gEiw54o_ANuEIl`Rk+_U-66jut`s=UgZcRU;~!(<;I)+Qy%%MzHA*541g3l#RA zTO{Y6_Wa3wbIXRVDg!#&n0K!CNLEbuir8IiAWwY$M3W)gRlb4boZA}&3$p`g4r*-5 z1?UX7Km@7{PZ(fvBAU+Fcy!BF z*SbdH+AfV%001|!W82M!c3J|yr}Qc!CsEnscfZ{L2R;nTn`}t6N6oEtut5VTc6Ij# zS_rPsV)iNpx7hB{(l^)_tMPC*!j z>9sLlf6K<2I6I=|CM~khXtn46czamfeL8Zp;mBNPAI%&SAx)G;93;Eyz>Bj9MR6r6 zUv<-3AXQ3MP)5pD%I+SRnl`?05oWyS{lNR@No7tyNZzANPN8f8&b-pTmB7KW zEYslbUJg9)>Hx^5WbHnV2`Az!(`j=ilzAo(&~FLLeoCsH0qtJSS+sG}con~vneB(Um>(JTby(V_gX;NhVm%m#h_Zhh{*=nbkuIBV?>NaPI7bf z%JO$9&DWRoZ5uQu*Q1NqQHGS;kiAU)PYuwsyg7GalXi(KVBK2x`T1zAZ@Ur9WJ+1- zxNftzs)%m=c*U{1;#|Je*o?AWkqNos)HQ&ab&kd@mrX@M6b60TlaQrMR_4L7YvSs>QM>qR z)QN9@aj7Ig3)&|8rftJhXVmUZEyq-|m_G3xSq4;KQnd42o$c|x>K}=r29m$kb=laW z{Y6ob4)x|fG&xF%0tr`>01@LP`odWU>v{y6Uxd{9_yVPZ%ZZVul2R%DA5Ox^O41uf zW1{f(D}zJKZque3-so{Zm=%U<+j4yJrFDI*S)ny>@vtEKFwxv}W;z1ppG>Lfs^or^ zrSSVLV%G>lNv;Jw+dcd-UY!oStZ`R~S7sNnXKKA8tTu-Ky0wyt%*sQ1s_AHV$SmdX z!MdS`-zewx`P+IyB^aW<2n&CK@r(n<{g7urz zTX*W42QNu~+*~hV&|qUuA@_m@{^VPEOn%tDwaS5DXWu3YZT)o}2+b8iECgy>eU4V5 z)9U!Lo=8ZL75Tw&5+_r64_JO1ZFnb5!MiD*Z&7}kz%2LT@z!W{tt>)mpDpJw?EK>3X*2$+ zd#5x&72gGB8kw1|uEeyS(V9Up^;F|VCWDs%GT`SFlnOL zAonLFkHhXKH~G?aF&opU7MxJ;_{aKBa$rNcThOFunSNi>#;qU8~QeTwF}81^%YFCz(^oRCRM^ zN5;iq{!gyWYYn}*@J|zf|CIDeh6~S(X%yi9@K!U;PVI-tIc^$-EYj6A3g{eTtKaWB z{V;L}+isv7Q+t4@qwkB_NzEacdRS@5bHBij;CcwA&Tw1CqMvo!t@I_jShmRdT=eqs z+!BBOhY#V5a`pI_%vk626cljjhV5X)IBwo9!Ubl=oC~_uwIhF%ug%vzDOTYr^CXd) zW(fg0CwALO9VbqZ`1b|RgyUJ&j`~%lUAcj?cf8A9M(dSN+3KfT%2b?20FxiTvtD86 zYrLI!kdZC?s@F^oH&yX^0+m=Wa}_QQu1a`!#RXqyN@Fq(6|Nat=d0ti@myo(;tJ{> zp87m1r%e*(c&y~jYoK43s6s*z#Et7(xJ6q5HpMXaHcnC&AbVM}!V?l_@Dpw=9`7$o z|FvM^Cfttjjt1%@4;WDeiFUuUWkw(*5EqR@8c{^Jk-MQv8L(!U0(3wrcu*ZM$hRfe zPNsa2PKcbV$rzr7xwMMe)XExOpa(FW2Cj{34N}nG#aXsg`4)XR9cGc~%+|e#1&bPW zdAL9Z#o_drL<4OK%~;6G_Cy#Nj_BWdNTZesYyS&P+^+Q{5`OKMcXeBZ_c^mxbvNp6 zm5UkSJl2Q;!hz^dZNoLZ?pkSLgc7BfPEaBjlf0RWyRiOQ2H;)8V<(m^~OvA z^Ud5rqkAQEs9zV+H@7 z_pXV3ZALoQs$kA`jFtx*|Lsh=m!#Uj7lzU0W6gKRL{Fi> z*-VcrF|W;z&-oW?u~+!Gl`netcfHzmOkm}y{n_p|9`lcGjF7;}#*mhIC74~K&V_jh zDPhpmSUx3=Xs2T5JvMjTdo;jbk?Hv{TiBZ}5$Ujw8XT`8r;lSFQ}(*|QkKZ*$=jlO z``*QEQye!Ke3=uUvB;EU&x$)oCuLI;=18&>@cHRkPD+l)T`v9(@8 zQE`^nO61`(AwMivNx-3yN|o`)cm;WI>&wJQ!c~f_z|cS@Zz<5?pSfWP9lNPa7B7>4 z8->J^df;#~$z%ZVclBxyj=&^*E@7uhFC@6GF!8CNi7EA&dj4{%?_uK`8J?9|+spKq zp$B2E!@+uY*zlxZ+%MIrlwt!gM*-|C&w9t*W{P^kLV$0T_QW`oW7Jr)#9_Ah=-h1e zl=NB6DadfYUQl*E#OzfTIiu4QQK!FF-G-a58m#_pAhJ>F#C{_Sw`IaWensX|sFtw& zmx39i$k1Rn!)PFCDNsX6$-#W7Cz_5tXc~9WPmiPJ~fM5O)F;<>oPeqj^sFX7dw6ZF=WOc$k?>SZEG7GpahB0*W0k8)y-{P zrnT4#SKcM4xN;g`eUfhlGraFM{M+~)x!Gu(0}(kp1Q8-z zv*+PPM{Fu#+7!(5!iKG%Y(j^TMuOq2_G=Y14*-4v+B=iYEp4L6=dcsj#}vII4&~zB4g8(k+Zu zJ&x7=xw_qXK(WR7Plz!#GrzcAxqK}&q)gTq4%&;V;C?F1d7ktqC7KX;XwsaJo$UDL zcXDcEb{(ZWFp^Mi{;@)tU*kkwJ5;sRby#!|?#fUsyK1u2Qe|+bvB1+{G~#f2q0H4U z*6Z~tO0hZm@n~Kfas*@`;t$zNrC1Ll-Bj6YF_f^ASdj%St{gf;VsS+i_4)Z%qaMM# z)YQ)%1@n@2``W7ui$#|01a%W z|FJ9>?MU?>NE%{KOsW5s5)~U=F=?Rm!zKuxu^a+&b5+w(p3>SPA8~Rs!J?+3Pi`%j zk3w1Ifh= zIy{_E1t5P}gWpBK&hCsn$TQ99<_kL9Gkp9oARan@yH~}CBe_dQ*CB@>-^+Lb{7(5K zuRpJ<)Qi(-cCyWF=~^YPK(DP>Tw|RPCAW0Q{!LP;=S#<1g#1Jm^f8Ge13@y zE#jn#an2UovsM$i7pM`DM_a5s33`J&Pf#hF=D|HT23fs$hpRlt3`mNnwC3{l4+V}@ zNQ7BFqv=XG$dH+45`Hh1*ca0}NFzLrgyn z3YcDQ=VZTo`_W}!Y(z4~qiMB7^e~vq+Ded$o&7papbJ-0pra-G$tdQ&bZtwd)kB1U zz20bo*th60>~+}(HTWcF`p6_pOroOajKeHh_N%86_;5uL^;b9TaZFdl&XFyPbHimv zq4h*TGtX&^*C-)IB<23?WHO+FOM%1t`|Z!uUeUBa{HgjaB!utRw<@k&FB;6PF;1KT z!sVLbLm;?rt2Nl}IL+TMmj{X@;z*kF7XM88T}WvU95m!#^_uZE&}HWi)eA|P)e^JW z_HUW7D?u=_Y_ATk!7R@=0+An7#<;?7vcFkaHD15e{4VBBtw@+n5QVFHalswwc6{cy z;q#2`%#wK`_xJ9(^)ohMiYUiN)hqFf(paw0XT@shfpzPu#OeMeIJJYshSqk?UQ=GVC@W znRhmkMO3zumKfosYm4|2X;$;Em_POsx*0>Fk4m`Jv?*7Y?_H;k?TXL_Ix&XlRP^Vh z48#{VEi=2e*}{p^!SB_*kPVGi^){*YxmWU3 zNy!X%R(&&NZmJX!N$4#}l11#^6$ZIk2GAQZ@Y1%NQ8xa@we&N}KJhQg3vrRl-nSS2 ze2p#oYIsW@`yi_cJm+m5XD`bs1n-%@zTVn2qYq1tgaJye)6;fJaDX?u1++N%57Lv}f5>b)Z4v%)u{gV8t0ejOSd{epd!4__p zTn6m!Rj?Bz{6XQ3=_M}2d|GIF%B*_@@qSsnQUjD=lZfQZsj-%V--`TnF@4AH2`)}aYgDvwFo1GmI0W!yModpjAjHonMQuV6x4|^?t zbh+egGYX8$NLor5TPFqZo~vp1kBr34kFPb(!Rn4!ZKiwe8_f%;L(Qo|dXlzY-!oA$ zTse^y$N3ZyT-r?HXQWG3?zqGmhxtar-m=nhH2Vp<&rb5^y$tWggOzAV3CJ)AwlT8n ze8RztZCr(mtPRgiBKvOyD}>9k{UtW^WM(z^?F<-lKhuDfws|!xM^cRLV|>jA6414A z##s61>rBGd5gjw;bj>IfMqK*ccQ+F_JgFRmWg(VJ=r^1|A?ep?Zg39CNs^_H$?E#@ zc<36qm3zPq6y358(&CkU0gwi`%3t*NzC(^nxcy$K)^uZAXbJASg?lD}{LG*FnkNnv ztFr5>(UK%ElKOLk%pmYbut&Fg4tF8NTO=y;+N(a$sLXUlS`MS;N_5HH!&xZcRkSbD zdHaD3o3DBQV6iHje%jh7EJi+lA|}UCWV_efUFsvOdJ;DO+N88)aZx=90V$J^MpC-FL8U>E?#`uaDFG!!x>;IM zy1S)2m+oFly7^|o`+1-D{pK$Zj{}&Qot^8v&icV#^z6nrcTOlB$_p*~Rwd5AEgCmZ zNVdZNeE>Sz5dA{>fY}s@X2Erog9|xv4)p3}+()2uM7;jd z?@VIcKA*!OZMw~VZwVRN==#|(*t#lL{nv*p0HCW;@y`Vz;iaPLbbfjv%H)9E~w^7HzyhF&*WkP&J@UdkdPqORK`-zB<+;!z6SlBu>f+hTeOwStY$uHd)ib~RUlB9NBF zaKKt6ot;=|(6agy_niS$G}mktd$l2@dTbN`o!3L--)Ug;4j&`1p0~%F*Zu7S+01{l z&CMGS(#AA6Rgx_Qu$`X*AScT{A1yO~6&?5%bi#}#ZdeR^$+k?JwO;0KBZPJ;&sOZ2 zF~7jj<@%OwU)^I9IF_6SF$s*eOmag2a~tcAl!dkAr5Hl8!zpd17K? zBl0IZx~aYcEPSt!5raNS?MW6Wvj)+@K6&n}a|v`RaDv|BJV%=h589 zOFwSKA4rD|`pe-SV2^VnEi)iNQ&muOfC}K{F+wU}kFEaBP#ge)5vA9;&w zJu)s?u$xMLl4+OQNXY-nMhdsN_|;&Q-sZ5px>%^MFMfycSQ332$OM1;Jx?tW4mrKI zu4Wl;13~?op+d;|P6hgAmOI_NL6th;e!Fe>?l*3J_Q7qd(gw~QuvyV;sf;!?ZE$H1 zK8Dd0G)RqK`|Lb0Ag4i9o}5T_yK^%FGLi!sgeS$^;5+XZFE>$0z#pJUM1dl1{7Y&;`sW?1NslTDR9>zu$9Jlgg|d3EcK ztjw+xr809Ogm7ngD>u^zU~x~f%pwC@p%Gt7@2`~s)YAYq{5JkBJj$>F+Brn6k%l3h zRh*Cf;$E?IU;1(<&l&WJ-#FLn&HNCMvd(xuYXg>lRmEBU!_{MaGsp46xuUj}zwp}ZBST_6qWT>97=xGyw&MOTQ@U$IJ1Bkvt5;lT)X^AO3 zYgK5k2@vy3q6b)A421n+|DPjQ0^wFv@?RiryUX=k!r`>L-R;~Bq{k=QxQ25{Bs-t- ztP-pjijPNGmvht!8U3ohGS?ejCqhP=gkykET8L{yj(Anj(U_wz5NmaP1?J}SN4|81oOc61~`C|vGW=6d_;8S81K$*by{~! zOz=L?t3^=Cz*P?>j{cQM|QFPSi#t(w9mjt1_hfyI~T&@XDXh^qm+s z<-V6iDMcSk)7N^Vq^Ty>mZIJKd-f~oA25K}SV~#~V48h;RJ?y!ROLg``rupWt?lc% z_a$)o(TqltWx~9hJ1H6eU2l*5)xt~E`u3NOYY+C&(q?0n82BR!at#|W=hD&!=(Wy3 z7Rs2%BiK9w|BFGvaB{%k{0GsHQxOv71|=fRKeS8a?Dc}#;XilO1YiYexr@Tc)hR7HUGfx^%)h%FLY|FDos@)ue1 zv&=k8{J84alq+R?>w6VD7_`IBKEuR_V#jHZu%_8)mouO}{cwN9#BT6O;)ol#sd(Tvh$Tf!-i)k@3>U?s(aG#HvrigKGE537Ck z?@Sfon~10bi26RV-r6YQI_{7`ABGC^;oLIS=#fvFieR*7zdOX0&1uP2m^m}ul0cdb zyS+d@9bd-c>8UxU#=i=_@CJKdtvwIH8YPi;$gXLsXW_3}B-EWOH3G`@#j99@((jX>A&c^y$K?+i z`oIo+#oiWY=BCP=t!&(;N09@*{`b1&V#$1y(Nl{{G47Qt0>5Np?`D0EkKQ*iy`FD% z-Wi++l@TtiuEabO)vsUhTY}ta`#DaQ;*_a%r_0K0jbYBPHbVyY&?>c@?ksEQ6y}QV zb9?Fphn1CS?S1qaCla^mYG+Wzi96TcvW7Pa71^VIE{=?(katf{V-AQT;Z-K)(KzyQ zW%f(-olT+R+t!=Q)m^8pi5!P&H(WbzhEOTDxd!C_S>fl8K8mqXm!y8=OB@S@P;h1{ zaHfO z6iC5(`E=oeGj_D@y)_ep5u==?lq8H^D#MDGuG|^p;+H*Tisb~G)BxWm@`-TMU)$&N zxx|Ra-EpKZ!(aI&v5DXxJPUzL#s>>|m`av`ebhs%>iPi_|vskHekUB0ZV z)n^{o(aVrH5-N*DAbpnMlQ!L5z|fG97^xj~SaMRbcV zGK0*Xk^Nci{v$F)NdtJ5Pfi_c<0prB62Rkz24DM|dHEJ|jvM7tekWbf+1OWWC35mV z9Wqz}%plJ=w#L1YKO?<7D40xbjQ$YXchqJP@yD;eu2LAUHe|I!6$deRLlE zd{Bm0$#EH=4cp*-~AD|B!P(XZYqw|i7g3Y&#*w+BbW)G{@QNz6ve7=?Bl&_UJDw!_e&bue`X(iV zI%i(OPh`elqyQ=YHkfK%PSLydc5)<i{0nUmX}~Ws;LwH{ zt8>_MDpQe{4#J4rnPEFnqB|lrn*%ER-6t0}?SSMQ))W@cEGobwBX4g0ZUBGxYR7 z22NRQq6}vzr`d{ml4=FOVrclzjA&r(y@>G<)JUphmGTj8ENw)Sr#K*xObL_P*nY0k zim6{EHa3!~BDKC%U^fNcrLSp0@6J{uZ=vuefTr%9jCC}QM+mlt2su(j*uWY=|<+s5!@Wnn0+5R z-}W*R^M#+7^rDKU`gJ<`0|b-6gF`T<>`;_ZoY@l~L_4gr;~OXs;q7;&BM1oGq1(Odxbf&BYy@6D0s z?MMvelJTjJkA6^!*BQiJ^(#9fXxdZ(S2Nw4g<5PaQou9jYB z@65a|IHf%0Fwz7km`|EWo>gl}^jK6>8Ept>Z80StZ5A&J)KC8th7PKb zs|oXFWke*hxPrFqSX07i3Pu;^oi^~VjY7!Kan*7&F){R7>Hz!vR^@b>m9L?f)@n8E z0sm}I49UuWM}}%65~8vEhlu% zkAmd_OQz=6#e}EIpwFA}BBd_tL;P<_&{X<3@>Q77P3~%PuNn)}pojx=fN9gb!e!RE zr&yR|Um%IA?q}$ikJ?yIypah=j}>*YJ$7up8jc(Ib>9AX*q{1JNxJ=Sx6XV!R8^-_H=w7)0#cdcg2(p){1$(yF~j8&LM z7x%%h3q3wjx~br3wycWGE)1o@vO@HVpLg_vOs{FhPQ8uYUt1VVnUM3C+gst!zDmH_ zhcs&WPs92*1Q#?eZ{3d6{}(U@?Duarhc@Oe+lucHT%?GST@mcM0?UVJ22Se@J@-5IMR%a-_~lPuU&71NYABz3CvsK zCwhlVE(;n764kD}vczTUup+#fu@(r(zX)5}nr++M2E z0USA#lo|747EwwmgSSwn_C`8Gsfr!PX=+BlCOX||g*ET(sb2WuQcCP;?{-L++l!5Z z9Gf4R;sm2hPSY#R5$z?A*$@7ouutkwFFjA{bOh@=LyU^Xv_k0w%ct%*SLtEZw@!hZ zraNABYjgrvn2DGIMg;+O*b{9Klr<~A#DXT-xG0Rde>aMbn1WcvJ*1o1!{ zAe~0$96X~8kM#IQ$~@EJ+YgTIb6>ifxWG-(;#7}a;!9g!Iv^EtSw3CxU7GII@#mrZ zrXNlIu?Tnk8TaDm*%XG*;!sd8vzjZO)?;EN5)4MT43b4{P$1ty~YB^J!&%as4&IxKTNGYAs!V_oJ*#7keR;JAMXl5Rl zfC6}P5_RG=e`qQ9#dvqi!Tr{KYDBoMfgk<4({NCttTbV*z0KM3v2bAr5jD!rZ#29D zi*6b2oZbn9Q;)gP!y7NOuBsf2l9LO!_ffx)t&TxQm2)vG(Cuo3jr^&rX_=aWTes?* zY!f#2uXS@E%vKG|459KZ`yP2KvrgW zsts-$iLfNzGx znK+NyzKcO`psm9$GR_hAECiXNvNV@QRtU)`6z*-}t!NWz^jR-6%KC}W|0&1IKoE#? zfxkT5f%!D#g6%&Rv4dXjyNBZIwjucbBjr3<%0@DqM{Y`?Eembwuj|nOs)qaYAJAg& zROLSHwAmeY7#7ye>3RL`6Km~#x4=s0BY`t8-CPXXfSKU+0^&4Z&XPnyk4P=Qi5MHf z@rqO{gocLKU}_tDp$QO_4_lta-A`Uh;Dv0t@_{xw5GJ6rUNR-H@^df@Y+NlU9 zY77~C2n_)(K($@&K(*uhB@QFNeMgFE{l?BeW)G6Qd!mN@Jn4t)%|Q?d2l-SD5a)hc z0c|UQ8B&Bh9*)3E9S@k;(1$t_D~DajwPni|aVK7qYRx#m(1~y?5O^+W$~rOkiU-q0 zx_t-+^w;n-hl$0GNme-3y!D~|f$cZMZGYFkKYU7zI@obb=qc69Ioo0Jh#rRt< zjk#RHnEnk6$uAxOC)sC@Ugk^}_5t@F-$9^AxpOQx|22QeH~r72$)xhbny7OevxSrA ziq!f1F{!ML1|<6yc}@5;r?UHHJ?u?5 zD(DeWc7Q&*W)nopcOmJqkgEl^q7TaAhjXUTso-5CL!ZZO-+UO`4V<(6_`qH zG`AKD2OX){m)gUu;`>){JESiqgl|xhjAj=*@|9DHRx9wzjFUp-BvWd3T3blB6O*PVEr0u~u_eFG)8`me?x$(7 zkn!G)r*P{0K@T4G{8ta2?k)w|LFvHW$j6Y&FUejm^L$ZPP=AE!koAZ1h&=K4m86)%r~l@7hcFC;Q&*_@`4+S8lE225|NI;oIJ}H>C=q>52%)D#61nS!P1rI69|FP!B4uNJ_uN8Y4+;H@J5lvULdr2Q3 z!ntIPg>1_EjmqI$$6}>Ls8d1zn{9EyEH5Id$5Ct{2hLCattqzJ#d8gBMJ0)qIC=+YO zlJBB{iV(nA90s%dnMOp#M*2xYHvU+ncD9eoP_p-ULNHn^9=X;m=q}Du%i-`?P4!U_ z#b_pHNtAx4fybG;d?Wv&kQSB7C zw4Zg;?-5GQyXaLv7A|@m<*L(L-V%c~pD?y8J()%^21vE6&)0w!g$8ESP5ZLF@xq2h zevanL9mgnM;~qfc0G&Y%s6;$^6HTbPMrApzw$|fJi-o+tbKa`!n{9)^FOLAONX5U+m7u2NkyST;XRZRkumFJfu_jtjT zzuNmxy-iB$3Vt3is)KIoSLaVMd|e9=+0Dz>QzMRdtC?}J={^b!iV~4$x$82@Hhqf5 zo@h1BqJ=ubr}b)B{0(od6N};;87@K;|~ojEdsmJ}>hqDTI>_}+E>292l{(HpDp(xM_kz|cfPz+r`yKND*U zAp9|0cR8*WL)q?l{5*Bzp4Jy!Q6^E{`LQfb%vAWz6PkVyY{4`g*S;$`DQzr*jRrcR z0y(=XoxFHbstcH`fVAeD^F?}l^yx)EmP@N%CcKJ=3gXB2F8ntcX+WQ&Ln46tfCRDt zKn}w_lH-Yl=nns;4iw;)$%j2MK-L2`A=7}Jtr!0d;DO?ox_l{;umY&Jc#rQ5MQQ|x zE6|)F1MJD$-sVv?yY0AT?)fPK9C_$`sow>`v*(Vzo)gh!)kK6sm+4tYtRVpb)AtUp zMFjR7telF~!ZCC9vaV8wwN6mTihYD5BfQ%}hA_S#$g7#jv=jiHcAO0*w&Bs!-@9D; z^07t~K*fObG~~&4r}j8SH3#%rhH0i+!~9Y81JrJ@O-2NgU0(-l0jSNp*vtj&JO$ty z=s%Zozhfmo&7eOp;i7qBA!ptvMicxmpHId7;8>1_uq4=ojMhZtTW*)sBA_JBFWX5g zuc*QVClSGK{&q?{{y-ZPU^@8cV6J*3q350qRBCH=S-;s=s*I+0Ip3R?@eN zcQ|TL;*FZ|=bG1}^nz7ne$7pU7A!vJuwlvGr( zAWK5`w=+GLjUUOPo=xd+8j+Wy*PmKc6fA%Puj@shg-GsS9iz^pK3ZJ2spGN+Q?E+8 z+1bikqj)q>^Na`McdA>pOXtL^HGhqR$POYqdxpx+Xta3Fw6FQizhuO36{);Yz1$KX zmd>;Pu|&Vrn$SqGF&lM@QA$UauE$n{Q?cn(V#EXlxVtQJdyZ z^V%~PS9}&?YULzNuG0-ft7~Z*jwXV{vmyrk5X^ACrVXbJwiK5H-Cn7ry`t%OyKs!`ZwtW*IkcQ+lJ2ESfp|`_~5zxs5S%Fb8+~`4EH){U?*CaEwEsCR=FHc?CwD z6;M&2^x7M3qXoO|Rg6=cu?E2mA6CPra5yFv1>OXH8@8bMbRh_hGd}nA&VCdOYUajD zX=1A_DP=q7RYc^#d}6(+f2m&X&+;@rzB1C;32|+az=HY2evxrdCw4A-{A&4|{SQ~6 z9j25Vh6g3Utu zdq2xyAqg;QZR%1&WjdEpA{|0cqc_a-^?10nqpr^ucHLge zL?W*Nv?|NieT!7?6-%buY#}+^KWLnT?!)O^Zd)ZPE1>uUk#G#5_87ZrIP>h_cgDjK z_tVsrin`s`oe=?Re->|pSeg8J?bI0`&fuB&e=4NnW<_7DSEN+U8$LezD%}mZ6h64F zF0gnHq7LCZ#vsZeU*@?NFi5D-5n}~!*^|&@V#S7ONVQK8vSmEDj zIR6L9;Zi>gAYi)$k_FznU$$z7{Lu`^&KPxuvm3HOJ>3Z-nGqgs$J5m{jf^;jBq%;# z0$;LBP1P8MV4#65jvv{^{)Im1%SBCzuDH?lpQH%iwE7GI$&IWTb9(=(hXp-2Jq_K7 zfMN(i?o^y%p(z{7WuqT);ih*3<{kQB(|lO}zd4GMSj}TFO?(Uutt4YW^ky!?!6C+uj=Df$WjQn;14pYhIq-CRk0?j(~;B@{#*8ORm zgOWpC6(|a(g=J>&h`8S9P@qp_Id$>KI%0QP8raJlks2YMKLrvo>i|xWgR%1U3l=K#jo{E&)pnWuV@)XV8> zlk-olyYw}uE^^=7i! zj`)C&^`cKxJDc5Ij!q1PwT=-ECMG(a*$;TF(S-t^u9po3B*IX^)J#JegjRN3h_) z{wIhC-AXL;MRQ&5D#PP&1v(e#-d9ni;~f93uT7cMqw)j`Qg8MBz%JLDc-|a0szHm_ z1jHoV1^pnRcQVaiM;(9HQv&!r!?P&3y7KeM8(d9Do=#cVdIQ7zPqjtAGRd+MWwh+J zq;I@&p$+j`*?T`GO5S{UN(8|#s6VYINAj@C;Pl_YhS#WIE> zajYAvkbynsI~?8iChSWihcKHQO!DUS;!WBsYvJ?MbGMUG{(gF3G-ASc>ctJ;yEh`Mn z6(}!)Wib~OKE!e`T{Ksj2r7467vcKQCDVqk_4()4B$lBYW0XsZ4)f;Vm z1eKC$$v!?hS@Vnx#Q5R()l|pOK!ZuvZMwiF?0p%%Sw|NE z`jw?hG9hRr7o8E`Q0U8&ChnS+JWr$bb& zgp#8>H`~bOf%HFjSN!)Z>NlR(axZ9ebr^dI`kM1TPs&ew>J*23D?p0EL@4=jZCVi^ zx0r)8i#F}AUvhppn|}QC$=1C;E~^0OM~tZZwY&Sw1yEGGRStntG?1jVP4cR_2&~>{ zoB!_F#^yyJAuD?}RKDSmV<5>J4TQ`28pwCH*FRLp;^??3`psbRw!Fc~W!=@@B|bHN(&;u14joe7hbk;aZMQ(6 zo;S(+z*Tn+JCX5t0x;}n$`|D11w~E(a`2MFv*fQIA+n6?$S-Czq+1mPRC?XjK))i>0 zLkK!6N|YwNW|z>ZD~eC6&9G4R#jXZfP_KoGAF&U* z?QoDi->-HaZ_+X^9=au;auLL@m-Lf>Z; zfa-cul1h9^puQH!#Aej=(<&>z7<0p`>z8dbn&R6`58Ab8`I7Og8pc&EvC~m+JV>Vt z3iZ|1=R6ME*7|CNZzK`>aV3!$z)$_aZT*vI{1nN#zY-ungAnXh^cF;nJJ9u-1*%V{ zYMpI&)rXL8Fy-GHzl6?}(|E};q5c|ONuN2Kj$ZPA*4jEN9&g`a6vwv12quvIfK@h8 z;pAwbQRnvbm|B>;^^~&Z(g|GGIKOjqC~Dfui>z9v_m*o6?lK|zfX`t|ghg!9w66oa zh(Ob_Vr^9S4%bGH|8cmgx!7>D$+;KtGK;c;$PGEXv~*JQMBehHE{q``1CzW?bbYi2 zcl&|d1!=sbK1$$EHBThOcU33tN+V;=_t}ZA7*J>B&RYG%oxGif0UYEVk{l)MC2$@Y zm_Cu<;e{<18$EeM90yF9ssJY&pUgOpLANWaf>A0znyXhC$>3>oY5k>Wk~FL#*Sp)l zc|ul#H&CZW4GxL+FK<AiCB#9e(Hw)R`}h4Fdl9oJ4Jki+Gy>ME!@k)u%KRx0GjnI{!%+o|>?yjvbc)?$ZO zE}1&G=bbiH7XhRP#_oN9W91R$ZoRv>p%iho+gEPdclYs(tO1bc^EIwT+`Sdt)8ty3 zPOMH(ZZ|DC$jj9~ZHupX!)dUs_i-$U@03EElb=6;vUF{Djw4nGS$9!#c{*RZ@kCg( z_))`4LyNf|CiPwy?)+h2E||sM5FZ>}uHN0FPr+-U&~DMAIKDBAtkhYt+pO}0w;9B7 z&Z{izgm{7rpWSYTI>tQ8|AeSDnPJ`@2*9X&llBq0_ZHmJKQBA$y_qtY*MY7aw;X3( z$(0xU8g-}n%XU#&!GpQ6LjKW-FOH51((+y_`fX*}iW1*uGq53vN?*Q}uH2IT6<9-U zc?*oC>@Y5h_kIUR=-ZKw`uxCzJjN?{+9U2~dUsg7Hi_vM9?N*A`5>oVtH<;bKPC%g%yQY71EERPuhPQt1x42{p)gF#O(43IotGWFX-&?={Z*0S>^1ITirm zxae&zKRAO`0oQgz0=K&m4hp z`zFoW$ffm);lf;T%MWAk=bAr9z`@gfT`i8BWm_PtBCQ%=u_w5fuB$zQ7^5>P@!$hF z#9p^y)rsj3^w5;UOJ%4x^HS9WcRPVoWc)x78*%unY{d8YJxu$JMX2ow{YM-9776)W zC9%8q5$!rVpb3WyZuUg7X^N)F-?|z90U6QE1rKF97dadp)l^C`#@JzN*Jy&LW&tH)nV zpXiuNFaXn*N)0(IO1ItnzbWMc!0~Dqm<8vMC4i2^9Ya+~@vX2X-8ErVH1%z@YQ*-e zdIP@oyBEWJaE@;5mv~@?c~%wxY@r*{ME$9Cu!Y=1sKL_b&%LOH{qgwX4R6`D`g@+5 ztKISduL(*A8iqkB^`d8|wFca_{z4wqJt8IMJ~-9$iwP$FnPY6eceOtKU09Qy_|z?q z?+T&0{n9N_8u=6C+NwkPzJ$FLfRThr36Qm@FTWw*0Opn=O}BSIp|o*0>~(kn6+jIe zJ;I2F*p(d~`e2k9oU2Xpd10SMO|uW9Z)D}+{T9)O$5>{M<0i3@XcI3OcdFDCkX{`- z4Ydla;A|wm9;Zv${meon1&qf^Hf!{m_^ypZjmR1MIeXZD`%mkcF(5D3D4>f~^<$XU zl>*<0>prF~=@E=$>o~UJHVHCTu#A#DPPnab4?Z%q)k(Qr7oXglBC1K{MfPNQDl2NC z;vbSiNWCn;Mp6ESL6@KmP`=cf(?`SYMQ;qOI~GS4tlP8XonCyEr8!GFX3WZH8_(hv8K$j5GBEO%M?1NnUpU zeY_Xu;OzZFn`G1bi$AJ~lCu%Mf@?h;!&s4Gy)tkT45BzYLZLqZ518Cg-tsMfc&-$v zM{m>h`BRE*QB6ZwDt?CZ%+bkL$o2uK_ZySgV_)evq?2T4$z6bC1h4nwD#46YCyt2F z5X99k+s{Q5)v>JgLg}m3WNNdkw;JCub{S~A9pp7ccCByIk+1XO#bDe(%ZtOivhW9g zL6wi1xnl`*ej#sCSiv5-2Yr`XOiaytr2FB83N0n|;)0W0p@k$-UA)y<@$S-V6V<-m?|XKm zmPaDRYv1>13~*LkG z*sf(yUhV_46YVfgN=2F|;!onZs9)1#z_{Z9o4X&xyqt6`P#!(bw=}Em_l1TYJC@o> zoFzqU1SVFVVDM)#k8<>D7gedvG|Y7WdC;l}k{ui3|C4ft4K$szfxf)C`Khza`xEhh z4-jzm$VfYEXkM_@Av{;!^|IA@K3t4Htz)poF@&%w6W-)5o^ncDL*wg zj!1~YG%Gh3t};pt;V`)1y7|SG#9Um#j-Vz9KS2Q*B8a5pB@zhRx<|>uwneZZ6XtTKgV(%zFdQ(eS zj4kV{_e}dAU&bM?VsgyY8LU74(=+(*lwoER14jVz-XCn{euq$1;0#oO(Y^Mz@X@_^ zS)6Sc*F3$CM|sKqXL2vf8|iqfz!`~`)Gd{?c8D~!Tn+Dvf$6(uIM{dO>2abft*@nV zeZqneix_ljhM1u5S*=YU({!8H6!j>UpV%2pVS~+9MWL(eAA9Y+l(E}%EFmJfW-=fG z@R%9zJ=ykrI0qhX-Tabd@bzUd5#h#z$_TI_ei*>NdFJ3yr9VELJy}9&%T)XQ!{9er z!8;sPF}8Z#9bEkYTXU!HbAekXe>f1m zP4=%z9uRH1y1@8F07xjSckI}1gzp$KC@MdVSJ<|Ug|)Ot7(TUaAOLNvi^blu(Gu^l z{~WD&l+tZ`BhA3@>dom{>F#T*q7-aKoJc&>_oE&Azw_u&PricQ*QO^Spk+7`ZkY9{Ud#+ z&BxOLF|~m;SJDiX)1umum)~Zzw1AWTlf=?zTWt20knuP@qzJ13~N}ZR{5?fCU?nH+! znv#$JvE$qsZGQ?)2m5+=Qv;zHY9l1W0Mn>@EJf)5qB=gDOaj~gAxMB$S(2bpXn)#%eic$;XfM7+1D+=azk)Zl?sbE+Z4YRt}0ImAWUjmPg-8k!{< z@5CH{rwVAs!Z`sq`B|%-5DoDr#90E`t}=x4^BTd z2M5bopUHgV)WN<0yBvIwJ?2vFGlpGN=0WQUGOQ{ZUMEERTBlm#t z)Q(Tr_k+#(Ccv!U*c*BiY!wN(7G}`676ubyf=k0fKvj<=q)2c%tx8-QfY~rI^EdS~ zC6fln#Ln55Y2(~g7o`;C1tmZ_@F!A=Gr~=MS&HK+>-gP;s=8P$rBjRNXy~BK6=pi$8liwCA~pWls!jf*l3-9&0{OyN;LTuczeFX zU1??B=Z0I30-!dO0DbCDjPFVwyp?U!7$WtPDsa^4j(H`^P%TDUd!PHj{{1c6e1v+obL*Ex z)xlzrzwvP@Fm3MVvHHQpw_g!pcjL`Y5rrbGgvFXlC!UU0&^Wq8^x{{wGZ6?g=i})g zEb=$~K~lv(13rMpdQ`TvAZ|#p=iy->;3NYKJKri&p%Fr z@Y{|FOTEfB8pv`x+Mur+=eEdN;6MNkC2{#1D;0#)Ma%B9Ph-bBcZfNgqXF)Mid3kC zTS4hU^$gKtg&XSj4RgML!SOa|wKmrvY~TdzGI2(8Q_^QV-*pT%*n4o=~nF^10f zYB2Zv4HlR41Y>{eNo`{L&C?tetl6ORswF;+hGZSLLd)U>e6FpmeB+Hq$W0<9#Q+YQ zuABQ}a<<0qK=}BcwQqnn1Kj5EHL1$rO08xo{Sx<#s*_0v**pgjOM;POjQMeFQgoZ> z%lH{XUV_BPYfYz(n%a4u&PHZ1Yi8C1U%;$Sfen#>SqOT7RCilwFGE9Z7& zkD*Q(F}7{XB7Q!h6$rQtn=wugiFGhB)jtWPe9jR>a`2;ISFPhYHuIc|S%bnnaSMIE1k8_&-Dy8;y4lEW8ch$s^iBTAf+dq zKt6IAMYb1Qm6NKzwF&j#l;-g-BJZm;I&yqdJ5u0ul3+ls3mGkV*`^m(7eDt7q-(4A ziVXo(SZEog+`OCIAfjDGFl#jLh_SYjCy6K#BD8TkmYX-uN9?Pw{=9!1W2%Ky$%zKLhRLeP?jAuIKc$)U5n^@ zU~CCpllH0T)gKDKi=g2q41DU6`Ud6e>7=)0Z#>}{RaE<_qV702MQpBTh_v{IBSF^O?ZJcRRyA=aLsAUS}lFFe?kMB?y_ z$(^DAXj^Zo3OfpK$m*Oc^t6PnH&BxC^bgr1wh`^H|3*h;ia(h0=Q&OzAFTLX)^fj})lgE=H`Tl$ z;Ax|P_MJR$Ab5r%%(K4PToe8Am*;#5eZckkNc*_eoUYsaBv0`sM70UJl}T5mecHy| zj6;kPv`(Q$-6 z*Ttdt30&BgRu>Wys>8B(iq~8)in(-xkB*CS$4l%%l6i=4< z2FNP8S7;KKKENplINg$N@NKxjTl~7QVbp^im>6*V3uxK{j^R`|bJY2iGfe}oRi)E_Qk?mhVGqmw1`FqcX9O=|DEKm_-W@*_6#C_c7Sx|?_Oz~zoDn-KaypG>_)+EvOp1<=&3P;O5Go@B0zx{p@vmyImukNN z(;DsPxI$n!z=oRczD2`_p~mV4>TK{0zfi<|Tus4+DRvWpT#(u^!*umg=|OVVm*Lx> zmhM$apyPujlDVivN1k}oqFbws7+bBQF|^+)FXnrk6{ME#<9h(CsS$@3RC9;u)Is`W zJEub7<78z*t$}f}fHRM&xnfw`-$v_cM;oE*f0bscW3qx<(;1!&Slc*_7r-jjsIa@gO_8mU<^-Uo{0f|3+dJEvzfWZF%+5LbZ|C4C@m;NN} zPKD&GN8)9etl%mfMnl7*^3^P^hvruY6^{cIl!(4K5(zOP3*q?I>F`I7Ht}A-BPB0@ z{uq#1Q-3Q^Yd$o|H}Anro}GUe^rZAtSUHl9ZU4kMhIZY`acpLMU;J-QyP&CjjobM& zr%Aq3jXLE{19-su>WsDCADF_h()7fk)^BpqbpM%*o7Nw%(<^8i`Np(1@X?vN01qRZ z*g?T(9solJiiYXSPKZ4W;W4MDXsO_~A2lZae>-x~Gdc0yqBpj;&0haoC@XyKdd#!Z z^##ll{ENH`Zj`9%g=KG&xLWn4ZNpu&^`U2XNcPRPiMRl~4`E&6{a14)Z;PCqpt=12 z^i})|JC|Hw{pqm!aZcE^dDB>5ux|!Wy5865m(OYsU;fxJ(s=i|f0ApHP5VUN0M7|g zUpYIwL$>Lq?4p_8ueV+-@6A$GJCEe{tJI6}ZLZ#mh$bKgyGJ_`M9$3nm!J4M(pfw%eOC9X%Db!6t0i0(f8Am0Z18941kbF(-MQN< z6MuM`>|OAEI=ijnhJ45GN4KYP+*z`?(fMlc|x2LvRoCjZE8EL)8N|ygr*ACm< z3#Zefi%-u3-lW;#*CM;<(rMEpei2efr?WKOYXFY9z5*o$Bj5?IYQ;fX_R}7f@%dkS zH|_8Tg?#}r(>}EoKTi8zyXJRQb<2<4fA{fZWUmDsK6~eaGHb2>o0QcNyMA66Ed_rDidNdqHs2`Ca%zC^}AXZNg>6`ne9 z{w=%vZu^dUZSYP6x1%R5%RgS&_rrW~D%+x$ZSB>?%n|SIO#MDbY{Ikx+lZ#WMwu*0 zpp(hdRL$0XpBZY*bM#$y`|Og_GE?7MRO_C;&9^?TADEi_+GNva97?$@^zv8ned~?p zO{!H7OV!A;`^P$G65RE1Jm5V2gzsHE#kkyEs;H^B$#i`<=n;x>t0S3xWf9` zzoK4D%-KflOMTgmwyBr?zS$uDCcDa1=cSP44E`meXM~$1KfK)so>tSazf?AR`dgV@p@uZr;@W`W{o0YHvJCLj27G`(9{Y;`my!3%Jel;s?m`vHe&se!qBE zKjY5c>hQSw&#T|vdQkH$cz!`Vs0jZ9KNzkJ*vG`ynMN&nL3)5zc|2rUTJr3RmE+6l z`+>zN^oT1zW;W{=XC&Le3y*=l_eGDDKK*Au`{wz3$$7DM3_#%N>gTe~DWM4fdM%&b literal 0 HcmV?d00001 diff --git a/vmr_streamer/img/vm4-inst.png b/vmr_streamer/img/vm4-inst.png new file mode 100644 index 0000000000000000000000000000000000000000..177a1ef97e9cc3bcc78d20e18c326d879873f5ea GIT binary patch literal 21711 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 literal 0 HcmV?d00001 diff --git a/vmr_streamer/img/vm5-inst.png b/vmr_streamer/img/vm5-inst.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d70e7af6c45ae40e2617cde4592691055f3b80 GIT binary patch literal 27799 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 W=a#`4Waf6!M){hCeD0rj9{e9fum-yT literal 0 HcmV?d00001 diff --git a/vmr_streamer/small.ico b/vmr_streamer/small.ico new file mode 100644 index 0000000000000000000000000000000000000000..b3ec03bd617f32e58128fa977fd6ac9605124f4b GIT binary patch literal 46227 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

BgK=6ART^ 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

qL*>{@J?sfr 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

j5 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 literal 0 HcmV?d00001 diff --git a/vmr_streamer/source/VoicemeeterRemote.h b/vmr_streamer/source/VoicemeeterRemote.h new file mode 100644 index 0000000..82224fb --- /dev/null +++ b/vmr_streamer/source/VoicemeeterRemote.h @@ -0,0 +1,974 @@ +/******************************************************************************/ +/* Voicemeeter Remote API. V.Burel©2015-2021 */ +/******************************************************************************/ +/* This Library allows communication with Voicemeeter applications */ +/* 4 Client Applications can be connected to remote Voicemeeter. */ +/* it also allows communication with MacroButtons application. */ +/******************************************************************************/ +/* */ +/* OFFICIAL LINK : WWW.VOICEMEETER.COM */ +/* */ +/******************************************************************************/ +/* COPYRIGHT: Vincent Burel(c)2015-2021 All Rights Reserved */ +/******************************************************************************/ +/* */ +/* LICENSING: VoicemeeterRemote.dll usage is driven by a license agreement */ +/* given in VoicemeeterRemoteAPI.pdf or readme.txt */ +/* */ +/******************************************************************************/ +/* long = 32 bit integer */ +/******************************************************************************/ + + +#ifndef __VOICEMEETER_REMOTE_H__ +#define __VOICEMEETER_REMOTE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#define VBVMR_RESULT_OK 0 + +/******************************************************************************/ +/* */ +/* Login */ +/* */ +/******************************************************************************/ + +/** @name Communication Login / logout +* @{ */ + + /** + @brief Open Communication Pipe With Voicemeeter (typically called on software startup). + @return : 0: OK (no error). + 1: OK but Voicemeeter Application not launched. + -1: cannot get client (unexpected) + -2: unexpected login (logout was expected before). + */ + +long __stdcall VBVMR_Login(void); + + /** + @brief Close Communication Pipe With Voicemeeter (typically called on software end). + @return : 0 if ok. + */ + +long __stdcall VBVMR_Logout(void); + + + /** + @brief Run Voicemeeter Application (get installation directory and run Voicemeeter Application). + @param vType : Voicemeeter type (1 = Voicemeeter, 2= Voicemeeter Banana, 3= Voicemeeter Potato, 6 = Potato x64 bits). + @return : 0: Ok. + -1: not installed (UninstallString not found in registry). + -2: unknown vType number + */ + +long __stdcall VBVMR_RunVoicemeeter(long vType); + + +/** @} */ + + + + + + + + + + + +/******************************************************************************/ +/* */ +/* General Information */ +/* */ +/******************************************************************************/ + +/** @name General Information +* @{ */ + + /** + @brief Get Voicemeeter Type + @param pType : Pointer on 32bit long receiving the type (1 = Voicemeeter, 2= Voicemeeter Banana, 3 Potato). + + VOICEMEETER STRIP/BUS INDEX ASSIGNMENT + + | Strip 1 | Strip 2 |Virtual Input| BUS A | BUS B | + +---------+---------+-------------+---------+---------+ + | 0 | 1 | 2 | 0 | 1 | + + VOICEMEETER BANANA STRIP/BUS INDEX ASSIGNMENT + + | Strip 1 | Strip 2 | Strip 2 |Virtual Input|Virtual AUX|BUS A1|BUS A2|BUS A3|BUS B1|BUS B2| + +---------+---------+---------+-------------+-----------+------+------+------+------+------+ + | 0 | 1 | 2 | 3 | 4 | 0 | 1 | 2 | 3 | 4 | + + VOICEMEETER POTATO STRIP/BUS INDEX ASSIGNMENT + + | Strip 1 | Strip 2 | Strip 2 | Strip 2 | Strip 2 |Virtual Input|Virtual AUX| VAIO3 |BUS A1|BUS A2|BUS A3|BUS A4|BUS A5|BUS B1|BUS B2|BUS B3| + +---------+---------+---------+---------+---------+-------------+-----------+-----------+------+------+------+------+------+------+------+------+ + | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | + + + @return : 0: OK (no error). + -1: cannot get client (unexpected) + -2: no server. + */ + +long __stdcall VBVMR_GetVoicemeeterType(long * pType); + + /** + @brief Get Voicemeeter Version + @param pType : Pointer on 32bit integer receiving the version (v1.v2.v3.v4) + v1 = (version & 0xFF000000)>>24; + v2 = (version & 0x00FF0000)>>16; + v3 = (version & 0x0000FF00)>>8; + v4 = version & 0x000000FF; + + @return : 0: OK (no error). + -1: cannot get client (unexpected) + -2: no server. + */ + +long __stdcall VBVMR_GetVoicemeeterVersion(long * pVersion); + + +/** @} */ + + + + + + + + + + + + + + + + + + +/******************************************************************************/ +/* */ +/* Get parameters */ +/* */ +/******************************************************************************/ + +/** @name Getting Parameters +* @{ */ + + /** + @brief Check if parameters have changed. + Call this function periodically (typically every 10 or 20ms). + (this function must be called from one thread only) + + @return: 0: no new paramters. + 1: New parameters -> update your display. + -1: error (unexpected) + -2: no server. + */ + +long __stdcall VBVMR_IsParametersDirty(void); + + /** + @brief get parameter value. + @param szParamName : Null Terminal ASCII String giving the name of the parameter (see parameters name table) + @param pValue : Pointer on float (32bit float by reference) receiving the wanted value. + @return : 0: OK (no error). + -1: error + -2: no server. + -3: unknown parameter + -5: structure mismatch + */ + +long __stdcall VBVMR_GetParameterFloat(char * szParamName, float * pValue); + + /** + @brief get parameter value. + @param szParamName : Null Terminal ASCII String giving the name of the parameter (see parameters name table) + @param pValue : Pointer on String (512 char or wchar) receiving the wanted value. + @return : 0: OK (no error). + -1: error + -2: no server. + -3: unknown parameter + -5: structure mismatch + */ + +long __stdcall VBVMR_GetParameterStringA(char * szParamName, char * szString); +long __stdcall VBVMR_GetParameterStringW(char * szParamName, unsigned short * wszString); + +/** @} */ + + + + + + + + + +/******************************************************************************/ +/* */ +/* Get levels */ +/* */ +/******************************************************************************/ + +/** @name Getting RT Data +* @{ */ + + /** + @brief Get Current levels. + (this function must be called from one thread only) + + @param nType: 0= pre fader input levels. + 1= post fader input levels. + 2= post Mute input levels. + 3= output levels. + + @param nuChannel: audio channel zero based index + for input 0 = in#1 left, 1= in#1 Right, etc... + for output 0 = busA ch1, 1 = busA ch2... + + VOICEMEETER CHANNEL ASSIGNMENT + + | Strip 1 | Strip 2 | Virtual Input | + +----+----+----+----+----+----+----+----+----+----+----+----+ + | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | + + | Output A1 / A2 | Virtual Output | + +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | + + VOICEMEETER BANANA CHANNEL ASSIGNMENT + + | Strip 1 | Strip 2 | Strip 3 | Virtual Input | Virtual Input AUX | + +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | + + | Output A1 | Output A2 | Output A3 | + +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | + + | Virtual Output B1 | Virtual Output B2 | + +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | + + VOICEMEETER POTATO CHANNEL ASSIGNMENT + + | Strip 1 | Strip 2 | Strip 3 | Strip 4 | Strip 5 | Virtual Input | Virtual Input AUX | VAIO3 | + +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 25 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | + + | Output A1 | Output A2 | Output A3 | Output A4 | Output A5 | + +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | + + | Virtual Output B1 | Virtual Output B2 | Virtual Output B3 | + +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | + + + @return : 0: OK (no error). + -1: error + -2: no server. + -3: no level available + -4: out of range + */ + +long __stdcall VBVMR_GetLevel(long nType, long nuChannel, float * pValue); + + + /** + @brief Get MIDI message from M.I.D.I. input device used by Voicemeeter M.I.D.I. mapping. + (this function must be called from one thread only) + + @param pMIDIBuffer: pointer on MIDI Buffer. Expected message size is below 4 bytes, + but it's recommended to use 1024 Bytes local buffer to receive + possible multiple M.I.D.I. event message in optimal way: + unsigned char pBuffer[1024]; + + + @return : >0: number of bytes placed in buffer (2 or 3 byte for usual M.I.D.I. message) + -1: error + -2: no server. + -5: no MIDI data + -6: no MIDI data + */ + + +long __stdcall VBVMR_GetMidiMessage(unsigned char *pMIDIBuffer, long nbByteMax); + + +/** @} */ + + + + + + + + + + +/******************************************************************************/ +/* */ +/* Set Parameters */ +/* */ +/******************************************************************************/ + +/** @name Setting Parameters +* @{ */ + + /** + @brief Set a single float 32 bits parameters . + @param szParamName : Null Terminal ASCII String giving the name of the parameter (see parameters name table) + example: + Strip[1].gain + Strip[0].mute + Bus[0].gain + Bus[0].eq.channel[0].cell[0].gain + + @param pValue : float 32bit containing the new value. + @return : 0: OK (no error). + -1: error + -2: no server. + -3: unknown parameter + */ + +long __stdcall VBVMR_SetParameterFloat(char * szParamName, float Value); + + + + /** + @brief Set a single string parameters . + @param szParamName : Null Terminal ASCII String giving the name of the parameter (see parameters name table) + example: + Strip[1].name + Strip[0].device.mme + Bus[0].device.asio + + @param szString : zero terminal string. + @return : 0: OK (no error). + -1: error + -2: no server. + -3: unknown parameter + + */ + + +long __stdcall VBVMR_SetParameterStringA(char * szParamName, char * szString); +long __stdcall VBVMR_SetParameterStringW(char * szParamName, unsigned short * wszString); + + + + + /** + @brief Set one or several parameters by a script ( < 48 kB ). + @param szParamName : Null Terminal ASCII String giving the script + (script allows to change several parameters in the same time - SYNCHRO). + Possible Instuction separators: ',' ';' or '\n'(CR) + EXAMPLE: + "Strip[0].gain = -6.0 + Strip[0].A1 = 0 + Strip[0].B1 = 1 + Strip[1].gain = -6.0 + Strip[2].gain = 0.0 + Strip[3].name = "Skype Caller" " + + @return : 0: OK (no error). + >0: number of line causing script error. + -1: error + -2: no server. + -3: unexpected error + -4: unexpected error + */ + +long __stdcall VBVMR_SetParameters(char * szParamScript); +long __stdcall VBVMR_SetParametersW(unsigned short * szParamScript); + + +/** @} */ + + + + + + + + + + + +/******************************************************************************/ +/* DEVICES ENUMERATOR */ +/******************************************************************************/ + + +/** @name Device Enumeration Functions +* @{ */ + +#define VBVMR_DEVTYPE_MME 1 +#define VBVMR_DEVTYPE_WDM 3 +#define VBVMR_DEVTYPE_KS 4 +#define VBVMR_DEVTYPE_ASIO 5 + + /** + @brief Get number of Audio Output Device available on the system + @return : return number of device found. + */ + +long __stdcall VBVMR_Output_GetDeviceNumber(void); + + /** + @brief Return pointer on Output Device Descriptor according index + @param zindex : zero based index + @param nType : Pointer on 32bit long receiving the type (pointer can be NULL). + @param szName : Pointer on string (256 char min) receiving the device name (pointer can be NULL). + @param szHardwareId : Pointer on string (256 char min) receiving the hardware ID (pointer can be NULL). + @return : 0: OK (no error). + */ + +long __stdcall VBVMR_Output_GetDeviceDescA(long zindex, long * nType, char * szDeviceName, char * szHardwareId); +long __stdcall VBVMR_Output_GetDeviceDescW(long zindex, long * nType, unsigned short * wszDeviceName, unsigned short * wszHardwareId); + + /** + @brief Get number of Audio Input Device available on the system + @return : return number of device found. + */ + +long __stdcall VBVMR_Input_GetDeviceNumber(void); + + /** + @brief Return pointer on Input Device Descriptor according index + @param zindex : zero based index + @param nType : Pointer on 32bit long receiving the type (pointer can be NULL). + @param szName : Pointer on string (256 char min) receiving the device name (pointer can be NULL). + @param szHardwareId : Pointer on string (256 char min) receiving the hardware ID (pointer can be NULL). + @return : 0: OK (no error). + */ + +long __stdcall VBVMR_Input_GetDeviceDescA(long zindex, long * nType, char * szDeviceName, char * szHardwareId); +long __stdcall VBVMR_Input_GetDeviceDescW(long zindex, long * nType, unsigned short * wszDeviceName, unsigned short * wszHardwareId); + + + +/** @} */ + + + + + + +/******************************************************************************/ +/* VB-AUDIO CALLBACK */ +/******************************************************************************/ +/* 4x Functions to process all voicemeeter audio input and output channels */ +/* */ +/* VBVMR_AudioCallbackRegister :to register your audio callback(s) */ +/* VBVMR_AudioCallbackStart :to start the audio stream */ +/* VBVMR_AudioCallbackStop :to stop the audio stream */ +/* VBVMR_AudioCallbackUnregister :to unregister / Release callback(s) */ +/******************************************************************************/ + +/** @name VB-Audio Callback Functions +* @{ */ + + +typedef struct tagVBVMR_AUDIOINFO +{ + long samplerate; + long nbSamplePerFrame; +} VBVMR_T_AUDIOINFO, *VBVMR_PT_AUDIOINFO, *VBVMR_LPT_AUDIOINFO; + + +typedef struct tagVBVMR_AUDIOBUFFER +{ + long audiobuffer_sr; //Sampling Rate + long audiobuffer_nbs; //number of sample per frame + long audiobuffer_nbi; //number of inputs + long audiobuffer_nbo; //number of outputs + float * audiobuffer_r[128]; //nbi input pointers containing frame of nbs sample (of 32bits float) + float * audiobuffer_w[128]; //nbo output pointers containing frame of nbs sample (of 32bits float) +} VBVMR_T_AUDIOBUFFER, *VBVMR_PT_AUDIOBUFFER, *VBVMR_LPT_AUDIOBUFFER; + + + /** + @brief VB-AUDIO Callback is called for different task to Initialize, perform and end your process. + VB-AUDIO Callback is part of single TIME CRITICAL Thread. + VB-AUDIO Callback is non re-entrant (cannot be called while in process) + VB-AUDIO Callback is supposed to be REAL TIME when called to process buffer. + (it means that the process has to be performed as fast as possible, waiting cycles are forbidden. + do not use O/S synchronization object, even Critical_Section can generate waiting cycle. Do not use + system functions that can generate waiting cycle like display, disk or communication functions for example). + + @param lpUser: User pointer given on callback registration. + @param ncommand: reason why the callback is called. + @param lpData: pointer on structure, pending on nCommand. + @param nnn: additional data, unused + + @return : 0: always 0 (unused). + */ + + +typedef long (__stdcall *T_VBVMR_VBAUDIOCALLBACK)(void * lpUser, long nCommand, void * lpData, long nnn); + + +#define VBVMR_CBCOMMAND_STARTING 1 //command to initialize data according SR and buffer size + //info = (VBVMR_LPT_AUDIOINFO)lpData + +#define VBVMR_CBCOMMAND_ENDING 2 //command to release data +#define VBVMR_CBCOMMAND_CHANGE 3 //If change in audio stream, you will have to restart audio + +#define VBVMR_CBCOMMAND_BUFFER_IN 10 //input insert +#define VBVMR_CBCOMMAND_BUFFER_OUT 11 //bus output insert +#define VBVMR_CBCOMMAND_BUFFER_MAIN 20 //all i/o + //audiobuffer = (VBVMR_LPT_AUDIOBUFFER)lpData + //nnn = synchro = 1 if synchro with Voicemeeter + +/* + ----------------------------------------------------- + AUDIO BUFFER for VBVMR_CBCOMMAND_BUFFER_IN + ----------------------------------------------------- + VOICEMEETER + + | Strip 1 | Strip 2 | Virtual Input | + +----+----+----+----+----+----+----+----+----+----+----+----+ + | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | + + VOICEMEETER BANANA + + | Strip 1 | Strip 2 | Strip 3 | Virtual Input | Virtual Input AUX | + +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | + + VOICEMEETER 8 + + | Strip 1 | Strip 2 | Strip 3 | Strip 4 | Strip 5 | Virtual Input | Virtual Input AUX | Virtual Input 8 | + +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | + + +----------------------------------------------------- + AUDIO BUFFER for VBVMR_CBCOMMAND_BUFFER_OUT +----------------------------------------------------- + VOICEMEETER + + | Output A1 / A2 | Virtual Output | + +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | + + VOICEMEETER BANANA + + | Output A1 | Output A2 | Output A3 | + +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | + + | Virtual Output B1 | Virtual Output B2 | + +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | + + + VOICEMEETER 8 + + | Output A1 | Output A2 | Output A3 | Output A4 | Output A5 | + +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | + + | Virtual Output B1 | Virtual Output B2 | Virtual Output B3 | + +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | + + +----------------------------------------------------- + AUDIO BUFFER for VBVMR_CBCOMMAND_BUFFER_MAIN +----------------------------------------------------- + VOICEMEETER + + | Strip 1 | Strip 2 | Virtual Input | + +----+----+----+----+----+----+----+----+----+----+----+----+ + | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | + + | Output A1 / A2 | Virtual Output | + +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | + Output buffer provides outputs only: + | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | + + VOICEMEETER BANANA + + | Strip 1 | Strip 2 | Strip 3 | Virtual Input | Virtual Input AUX | + +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | + + | Output A1 | Output A2 | Output A3 | + +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | + Output buffer provides outputs only: + | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | + + | Virtual Output B1 | Virtual Output B2 | + +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | + Output buffer provides outputs only: + | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | + + + VOICEMEETER 8 + + | Strip 1 | Strip 2 | Strip 3 | Strip 4 | Strip 5 | Virtual Input | Virtual Input AUX | Virtual Input 8 | + +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | + + | Output A1 | Output A2 | Output A3 | Output A4 | Output A5 | + +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | + Output buffer provides outputs only: + | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | + + | Virtual Output B1 | Virtual Output B2 | Virtual Output B3 | + +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | + Output buffer provides outputs only: + | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | + + +*/ + + /** + @brief register your audio callback function to receive real time audio buffer + it's possible to register up to 3x different Audio Callback in the same application or in + 3x different applications. In the same application, this is possible because Voicemeeter + provides 3 kind of audio Streams: + - AUDIO INPUT INSERT (to process all Voicemeeter inputs as insert) + - AUDIO OUTPUT INSERT (to process all Voicemeeter BUS outputs as insert) + - ALL AUDIO I/O (to process all Voicemeeter i/o). + Note: a single callback can be used to receive the 3 possible audio streams. + + @param mode : callback type (main, input or bus output) see define below + @param pCallback : Pointer on your callback function. + @param lpUser : user pointer (pointer that will be passed in callback first argument). + @param szClientName[64]: IN: Name of the application registering the Callback. + OUT: Name of the application already registered. + @return : 0: OK (no error). + -1: error + 1: callback already registered (by another application). + */ + +long __stdcall VBVMR_AudioCallbackRegister(long mode, T_VBVMR_VBAUDIOCALLBACK pCallback, void * lpUser, char szClientName[64]); + +#define VBVMR_AUDIOCALLBACK_IN 0x00000001 //to process input insert +#define VBVMR_AUDIOCALLBACK_OUT 0x00000002 //to process output bus insert +#define VBVMR_AUDIOCALLBACK_MAIN 0x00000004 //to receive all i/o + + /** + @brief Start / Stop Audio processing + + he Callback will be called with + @return : 0: OK (no error). + -1: error + -2: no callback registred. + */ + +long __stdcall VBVMR_AudioCallbackStart(void); +long __stdcall VBVMR_AudioCallbackStop(void); + + + /** + @brief unregister your callback to release voicemeeter virtual driver + (this function will automatically call VBVMR_AudioCallbackStop() function) + @param pCallback : Pointer on your callback function. + @return : 0: OK (no error). + -1: error + 1: callback already unregistered. + */ + +long __stdcall VBVMR_AudioCallbackUnregister(void); + + + +/** @} */ + + + + + + +/******************************************************************************/ +/* */ +/* Macro Buttons */ +/* */ +/******************************************************************************/ + +/** @name Macro Buttons functions +* @{ */ + + /** + @brief Check if Macro Buttons states changed. + Call this function periodically (typically every 50 or 500ms) to know if something happen on MacroButton states . + (this function must be called from one thread only) + + @return: 0: no new status. + >0: last nu logical button status changed. + -1: error (unexpected) + -2: no server. + */ + +long __stdcall VBVMR_MacroButton_IsDirty(void); + + /** + @brief get current status of a given button. + @param nuLogicalButton : button index: 0 to 79) + @param pValue : Pointer on float (32bit float by reference) receiving the wanted value (0.0 = OFF / 1.0 = ON). + @param bitmode: define what kind of value you want to read (see MACROBUTTON_MODE below) + @return : 0: OK (no error). + -1: error + -2: no server. + -3: unknown parameter + -5: structure mismatch + */ + +long __stdcall VBVMR_MacroButton_GetStatus(long nuLogicalButton, float * pValue, long bitmode); + + /** + @brief set current button value. + @param nuLogicalButton : button index: 0 to 79) + @param fValue : float 32 bit value giving the status (0.0 = OFF / 1.0 = ON). + @param bitmode: define what kind of value you want to write/modify (see MACROBUTTON_MODE below) + @return : 0: OK (no error). + -1: error + -2: no server. + -3: unknown parameter + -5: structure mismatch + */ + +long __stdcall VBVMR_MacroButton_SetStatus(long nuLogicalButton, float fValue, long bitmode); + +#define VBVMR_MACROBUTTON_MODE_DEFAULT 0x00000000 //PUSH or RELEASE button +#define VBVMR_MACROBUTTON_MODE_STATEONLY 0x00000002 //change Displayed State only +#define VBVMR_MACROBUTTON_MODE_TRIGGER 0x00000003 //change Trigger State + + + +/** @} */ + + + + + + + + + +/******************************************************************************/ +/* 'C' STRUCTURED INTERFACE */ +/******************************************************************************/ + +typedef long (__stdcall *T_VBVMR_Login)(void); +typedef long (__stdcall *T_VBVMR_Logout)(void); +typedef long (__stdcall *T_VBVMR_RunVoicemeeter)(long vType); + +typedef long (__stdcall *T_VBVMR_GetVoicemeeterType)(long * pType); +typedef long (__stdcall *T_VBVMR_GetVoicemeeterVersion)(long * pVersion); + +typedef long (__stdcall *T_VBVMR_IsParametersDirty)(void); +typedef long (__stdcall *T_VBVMR_GetParameterFloat)(char * szParamName, float * pValue); +typedef long (__stdcall *T_VBVMR_GetParameterStringA)(char * szParamName, char * szString); +typedef long (__stdcall *T_VBVMR_GetParameterStringW)(char * szParamName, unsigned short * wszString); + + +typedef long (__stdcall *T_VBVMR_GetLevel)(long nType, long nuChannel, float * pValue); +typedef long (__stdcall *T_VBVMR_GetMidiMessage)(unsigned char *pMIDIBuffer, long nbByteMax); + +typedef long (__stdcall *T_VBVMR_SetParameterFloat)(char * szParamName, float Value); +typedef long (__stdcall *T_VBVMR_SetParameters)(char * szParamScript); +typedef long (__stdcall *T_VBVMR_SetParametersW)(unsigned short * szParamScript); +typedef long (__stdcall *T_VBVMR_SetParameterStringA)(char * szParamName, char * szString); +typedef long (__stdcall *T_VBVMR_SetParameterStringW)(char * szParamName, unsigned short * wszString); + +typedef long (__stdcall *T_VBVMR_Output_GetDeviceNumber)(void); +typedef long (__stdcall *T_VBVMR_Output_GetDeviceDescA)(long zindex, long * nType, char * szDeviceName, char * szHardwareId); +typedef long (__stdcall *T_VBVMR_Output_GetDeviceDescW)(long zindex, long * nType, unsigned short * wszDeviceName, unsigned short * wszHardwareId); +typedef long (__stdcall *T_VBVMR_Input_GetDeviceNumber)(void); +typedef long (__stdcall *T_VBVMR_Input_GetDeviceDescA)(long zindex, long * nType, char * szDeviceName, char * szHardwareId); +typedef long (__stdcall *T_VBVMR_Input_GetDeviceDescW)(long zindex, long * nType, unsigned short * wszDeviceName, unsigned short * wszHardwareId); + +typedef long (__stdcall *T_VBVMR_AudioCallbackRegister)(long mode, T_VBVMR_VBAUDIOCALLBACK pCallback, void * lpUser, char szClientName[64]); +typedef long (__stdcall *T_VBVMR_AudioCallbackStart)(void); +typedef long (__stdcall *T_VBVMR_AudioCallbackStop)(void); +typedef long (__stdcall *T_VBVMR_AudioCallbackUnregister)(void); + +typedef long (__stdcall *T_VBVMR_MacroButton_IsDirty)(void); +typedef long (__stdcall *T_VBVMR_MacroButton_GetStatus)(long nuLogicalButton, float * pValue, long bitmode); +typedef long (__stdcall *T_VBVMR_MacroButton_SetStatus)(long nuLogicalButton, float fValue, long bitmode); + + + +typedef struct tagVBVMR_INTERFACE +{ + T_VBVMR_Login VBVMR_Login; + T_VBVMR_Logout VBVMR_Logout; + T_VBVMR_RunVoicemeeter VBVMR_RunVoicemeeter; + T_VBVMR_GetVoicemeeterType VBVMR_GetVoicemeeterType; + T_VBVMR_GetVoicemeeterVersion VBVMR_GetVoicemeeterVersion; + T_VBVMR_IsParametersDirty VBVMR_IsParametersDirty; + T_VBVMR_GetParameterFloat VBVMR_GetParameterFloat; + T_VBVMR_GetParameterStringA VBVMR_GetParameterStringA; + T_VBVMR_GetParameterStringW VBVMR_GetParameterStringW; + + T_VBVMR_GetLevel VBVMR_GetLevel; + T_VBVMR_GetMidiMessage VBVMR_GetMidiMessage; + + T_VBVMR_SetParameterFloat VBVMR_SetParameterFloat; + T_VBVMR_SetParameters VBVMR_SetParameters; + T_VBVMR_SetParametersW VBVMR_SetParametersW; + T_VBVMR_SetParameterStringA VBVMR_SetParameterStringA; + T_VBVMR_SetParameterStringW VBVMR_SetParameterStringW; + + T_VBVMR_Output_GetDeviceNumber VBVMR_Output_GetDeviceNumber; + T_VBVMR_Output_GetDeviceDescA VBVMR_Output_GetDeviceDescA; + T_VBVMR_Output_GetDeviceDescW VBVMR_Output_GetDeviceDescW; + T_VBVMR_Input_GetDeviceNumber VBVMR_Input_GetDeviceNumber; + T_VBVMR_Input_GetDeviceDescA VBVMR_Input_GetDeviceDescA; + T_VBVMR_Input_GetDeviceDescW VBVMR_Input_GetDeviceDescW; + + T_VBVMR_AudioCallbackRegister VBVMR_AudioCallbackRegister; + T_VBVMR_AudioCallbackStart VBVMR_AudioCallbackStart; + T_VBVMR_AudioCallbackStop VBVMR_AudioCallbackStop; + T_VBVMR_AudioCallbackUnregister VBVMR_AudioCallbackUnregister; + + T_VBVMR_MacroButton_IsDirty VBVMR_MacroButton_IsDirty; + T_VBVMR_MacroButton_GetStatus VBVMR_MacroButton_GetStatus; + T_VBVMR_MacroButton_SetStatus VBVMR_MacroButton_SetStatus; + +} T_VBVMR_INTERFACE, *PT_VBVMR_INTERFACE, *LPT_VBVMR_INTERFACE; + +#ifdef VBUSE_LOCALLIB + // internal used (not public) + void __stdcall VBVMR_SetHinstance(HINSTANCE hinst); +#endif + + + + +/******************************************************************************/ +/* VBAN RT PACKET */ +/******************************************************************************/ + +#pragma pack(1) + +// COMPATIBILITY: defined structure cannot be changed. +// some field could be added at the end of the structure to keep the compatibility in the time. + +typedef struct tagVBAN_VMRT_PACKET +{ + unsigned char voicemeeterType; // 1 = Voicemeeter, 2= Voicemeeter Banana, 3 Potato + unsigned char reserved; // unused + unsigned short buffersize; // main stream buffer size + unsigned long voicemeeterVersion; // version like for VBVMR_GetVoicemeeterVersion() functino + unsigned long optionBits; // unused + unsigned long samplerate; // main stream samplerate + short inputLeveldB100[34]; // pre fader input peak level in dB * 100 + short outputLeveldB100[64]; // bus output peak level in dB * 100 + unsigned long TransportBit; // Transport Status + unsigned long stripState[8]; // Strip Buttons Status (see MODE bits below) + unsigned long busState[8]; // Bus Buttons Status (see MODE bits below) + short stripGaindB100Layer1[8]; // Strip Gain in dB * 100 + short stripGaindB100Layer2[8]; + short stripGaindB100Layer3[8]; + short stripGaindB100Layer4[8]; + short stripGaindB100Layer5[8]; + short stripGaindB100Layer6[8]; + short stripGaindB100Layer7[8]; + short stripGaindB100Layer8[8]; + short busGaindB100[8]; // Bus Gain in dB * 100 + char stripLabelUTF8c60[8][60]; // Strip Label + char busLabelUTF8c60[8][60]; // Bus Label +} T_VBAN_VMRT_PACKET, *PT_VBAN_VMRT_PACKET, *LPT_VBAN_VMRT_PACKET; + +#define expected_size_T_VBAN_VMRT_PACKET 1384 //1436 max + +#pragma pack() + +#define VMRTSTATE_MODE_MUTE 0x00000001 +#define VMRTSTATE_MODE_SOLO 0x00000002 +#define VMRTSTATE_MODE_MONO 0x00000004 +#define VMRTSTATE_MODE_MUTEC 0x00000008 + +#define VMRTSTATE_MODE_MIXDOWN 0x00000010 +#define VMRTSTATE_MODE_REPEAT 0x00000020 +#define VMRTSTATE_MODE_MIXDOWNB 0x00000030 +#define VMRTSTATE_MODE_COMPOSITE 0x00000040 +#define VMRTSTATE_MODE_UPMIXTV 0x00000050 +#define VMRTSTATE_MODE_UPMIX2 0x00000060 +#define VMRTSTATE_MODE_UPMIX4 0x00000070 +#define VMRTSTATE_MODE_UPMIX6 0x00000080 +#define VMRTSTATE_MODE_CENTER 0x00000090 +#define VMRTSTATE_MODE_LFE 0x000000A0 +#define VMRTSTATE_MODE_REAR 0x000000B0 + +#define VMRTSTATE_MODE_MASK 0x000000F0 + +#define VMRTSTATE_MODE_EQ 0x00000100 +#define VMRTSTATE_MODE_CROSS 0x00000200 +#define VMRTSTATE_MODE_EQB 0x00000800 + +#define VMRTSTATE_MODE_BUSA 0x00001000 +#define VMRTSTATE_MODE_BUSA1 0x00001000 +#define VMRTSTATE_MODE_BUSA2 0x00002000 +#define VMRTSTATE_MODE_BUSA3 0x00004000 +#define VMRTSTATE_MODE_BUSA4 0x00008000 +#define VMRTSTATE_MODE_BUSA5 0x00080000 + +#define VMRTSTATE_MODE_BUSB 0x00010000 +#define VMRTSTATE_MODE_BUSB1 0x00010000 +#define VMRTSTATE_MODE_BUSB2 0x00020000 +#define VMRTSTATE_MODE_BUSB3 0x00040000 + +#define VMRTSTATE_MODE_PAN0 0x00000000 +#define VMRTSTATE_MODE_PANCOLOR 0x00100000 +#define VMRTSTATE_MODE_PANMOD 0x00200000 +#define VMRTSTATE_MODE_PANMASK 0x00F00000 + +#define VMRTSTATE_MODE_POSTFX_R 0x01000000 +#define VMRTSTATE_MODE_POSTFX_D 0x02000000 +#define VMRTSTATE_MODE_POSTFX1 0x04000000 +#define VMRTSTATE_MODE_POSTFX2 0x08000000 + +#define VMRTSTATE_MODE_SEL 0x10000000 +#define VMRTSTATE_MODE_MONITOR 0x20000000 + + + + + +/******************************************************************************/ +/* LOCAL FUNCTIONS */ +/******************************************************************************/ + +long VBVMR_LocalInit(void); +long VBVMR_LocalEnd(void); +void * VBVMR_GetRequestVB0STREAMPTR(void); + +long VBVMR_SetParametersWEx(unsigned short * szParamScript, long fCopyToClient); + +long VBVMR_LoginEx(long properties); + +long VBVMR_MB_PushSettings(void * lpParam); + + + + + +#ifdef __cplusplus +} +#endif + +#endif /*__VOICEMEETER_REMOTE_H__*/ + + diff --git a/vmr_streamer/source/streamer_ctrl.c b/vmr_streamer/source/streamer_ctrl.c new file mode 100644 index 0000000..3b5a48e --- /dev/null +++ b/vmr_streamer/source/streamer_ctrl.c @@ -0,0 +1,1924 @@ +/**********************************************************************************/ +/* VMSCTL V.Burel */ +/**********************************************************************************/ +/* Contains our custom windows control for vmr_streamer project */ +/*--------------------------------------------------------------------------------*/ +/* */ +/* COMPILATION DIRECTIVES: */ +/* */ +/* To compile With Microsoft VC2005 or higher, you need to create an */ +/* empty Win32 project with the following options: */ +/* - Configuration Properties / General : Char Set = NOT SET */ +/* - Configuration Properties / C/C++ / Preprocessor : _CRT_SECURE_NO_DEPRECATE */ +/* */ +/* This source code can be compiled for 32bit or 64 bits targets as well */ +/* WARNING: FOR 64x COMPILATION, ADD PREPROCESSOR DEFINE: VB_X64 */ +/* */ +/*--------------------------------------------------------------------------------*/ +/* */ +/* LICENSING: VoicemeeterRemote.dll usage is driven by a license agreement */ +/* given in VoicemeeterRemoteAPI.pdf or readme.txt */ +/* This Source Code can be used only in a program using Voicemeeter */ +/* Remote API. */ +/* */ +/*--------------------------------------------------------------------------------*/ + + +#ifndef __cplusplus + #ifndef STRICT + #define STRICT + #endif +#endif + +#include +#include +#include "streamer_ctrl.h" + +static HINSTANCE G_hinstance=NULL; + + +#define PEAKMETER_RELEASE_DECREMENT 1.0f + +/*---------------------------------------------------------------*/ +/* TOOL */ +/*---------------------------------------------------------------*/ + +void TOOL_StorePointerInWindow(HWND hw,LPVOID pp) +{ +#ifdef VB_X64 + SetWindowLongPtr(hw,0,(LONG_PTR)pp); +#else + SetWindowLong(hw,0,(ULONG)pp); +#endif +} + +LPVOID TOOL_RecallPointerFromWindow(HWND hw) +{ +#ifdef VB_X64 + return (LPVOID)GetWindowLongPtr(hw,0); +#else + return (LPVOID)GetWindowLong(hw,0); +#endif +} + + + + + + + + + + + + + + + + + +/*---------------------------------------------------------------*/ +/* STRIP CONTROL */ +/*---------------------------------------------------------------*/ + +#define VMSCTL_STRIPBUS_MARGIN 5 +#define VMSCTL_STRIP_DY_BUTTON 20 +#define VMSCTL_STRIP_DY_ASSIGN 30 + +#define VMSCTL_STRIP_DX_NICKNAME 40 +#define VMSCTL_STRIP_DX_ASSIGN 30 + +#define VMSCTL_STRIP_DXMIN_PEAKMETER 100 +#define VMSCTL_STRIP_DYMIN_SLIDER 100 + + +typedef struct tagVMSCTL_STRIPCTX +{ + HWND hw; + long Ident; + long x0,y0,dx,dy; + long isShown; + + RECT rect_nickname; + RECT rect_name; + RECT rect_meters; + RECT rect_slider[VMSCTL_MAX_NBBUS]; + RECT rect_assign[VMSCTL_MAX_NBBUS]; + + long dx_meter; + long dy_meter; + long dx_slider; + long dx_name; + long margin_slider; + long dy_slider; + HBITMAP tempbmp; +// long SliderLinkMode; + + float start_value; + HWND LastCapture; + long mouse_y0; + long last_y0; + BOOL mouseCapture; + long ctlRunning; + long iStripRunning; + + T_VMSCTL_STRIPPARAM param; + T_VMSCTL_STRIP_DATA data; + T_VMSCTL_RT_DATA rtdata; +} T_VMSCTL_STRIPCTX, *PT_VMSCTL_STRIPCTX, *LPT_VMSCTL_STRIPCTX; + + + + +static void DrawSTRIP_NickNameMute(LPT_VMSCTL_STRIPCTX lpobject, HDC dc) +{ + char sss[64]; + RECT rect; + HFONT oldfont; + HPEN oldpen; + HBRUSH oldbrush; + if (dc == NULL) return; + + rect.left=VMSCTL_STRIPBUS_MARGIN; + rect.top=VMSCTL_STRIPBUS_MARGIN; + rect.right=rect.left+VMSCTL_STRIP_DX_NICKNAME; + rect.bottom=rect.top+VMSCTL_STRIP_DY_BUTTON; + lpobject->rect_nickname=rect; + + oldpen = (HPEN)SelectObject(dc,lpobject->param.assignbus_pen); + oldbrush = (HBRUSH)SelectObject(dc,lpobject->param.bkg1_brush); + oldfont = (HFONT)SelectObject(dc,lpobject->param.font0); + SetBkMode(dc,TRANSPARENT); + SetTextColor(dc,lpobject->param.assignbus_color); + + if (lpobject->data.strip_mute != 0) + { + SetTextColor(dc,lpobject->param.mutered_color); + SelectObject(dc,lpobject->param.mutered_pen); + } + + RoundRect(dc,rect.left,rect.top,rect.right,rect.bottom, 5,5); + strcpy(sss,lpobject->data.strip_nickname); + DrawText(dc,sss,(long)strlen(sss),&rect,DT_SINGLELINE | DT_VCENTER | DT_CENTER); + + SelectObject(dc,oldpen); + SelectObject(dc,oldbrush); + SelectObject(dc,oldfont); + +} + +static void DrawSTRIP_Name(LPT_VMSCTL_STRIPCTX lpobject, HDC dc) +{ + RECT rect; + HFONT oldfont; + HPEN oldpen; + HBRUSH oldbrush; + if (dc == NULL) return; + + rect.left=VMSCTL_STRIPBUS_MARGIN+VMSCTL_STRIP_DX_NICKNAME+10; + rect.top=VMSCTL_STRIPBUS_MARGIN; + rect.right=rect.left+lpobject->dx_name; + rect.bottom=rect.top+VMSCTL_STRIP_DY_BUTTON; + lpobject->rect_name=rect; + + oldpen = (HPEN)SelectObject(dc,GetStockObject(NULL_PEN)); + oldbrush = (HBRUSH)SelectObject(dc,lpobject->param.bkg1_brush); + oldfont = (HFONT)SelectObject(dc,lpobject->param.font2); + SetBkMode(dc,TRANSPARENT); + SetTextColor(dc,lpobject->param.name_color); + + RoundRect(dc,rect.left,rect.top,rect.right,rect.bottom, 5,5); + DrawTextW(dc,lpobject->data.strip_namew,(long)wcslen(lpobject->data.strip_namew),&rect,DT_SINGLELINE | DT_VCENTER | DT_LEFT); + + SelectObject(dc,oldpen); + SelectObject(dc,oldbrush); + SelectObject(dc,oldfont); +} + + +static void DrawSTRIP_PeakMetersBkg(LPT_VMSCTL_STRIPCTX lpobject, HDC dc) +{ + long dx; + RECT rect; + HPEN oldpen; + HBRUSH oldbrush; + if (dc == NULL) return; + + dx = lpobject->dx_meter; + rect.left=VMSCTL_STRIPBUS_MARGIN; + rect.top=VMSCTL_STRIPBUS_MARGIN+VMSCTL_STRIP_DY_BUTTON+10; + rect.right=rect.left+dx; + rect.bottom=rect.top+lpobject->dy_meter; + lpobject->rect_meters=rect; + + oldpen = (HPEN)SelectObject(dc,GetStockObject(BLACK_PEN)); + oldbrush = (HBRUSH)SelectObject(dc,GetStockObject(BLACK_BRUSH)); + + Rectangle(dc,rect.left,rect.top,rect.right,rect.bottom); + + SelectObject(dc,oldpen); + SelectObject(dc,oldbrush); +} + +static void DrawSTRIP_PeakMeters(LPT_VMSCTL_STRIPCTX lpobject, HDC dc) +{ + LPT_VMSCTL_STRIPPARAM lpp; + float dBValue, dBmin=-80.0f, dBmax=+12.0f; + long nu,nbMeter=2; + long dx,dy,xx,x1,xgreen,xred; + RECT rect; + HPEN oldpen; + HBRUSH oldbrush; + if (dc == NULL) return; + + dx = lpobject->dx_meter-6; + rect.left=VMSCTL_STRIPBUS_MARGIN; + rect.top=VMSCTL_STRIPBUS_MARGIN+VMSCTL_STRIP_DY_BUTTON+10; + rect.bottom=rect.top+lpobject->dy_meter; + dy = (rect.bottom-rect.top-4) / nbMeter; + + rect.left+=3; + rect.top+=3; + rect.right=rect.left+dx; + rect.bottom = rect.top+dy; + + oldpen = (HPEN)SelectObject(dc,GetStockObject(NULL_PEN)); + oldbrush = (HBRUSH)SelectObject(dc,GetStockObject(BLACK_BRUSH)); + xgreen = (long)(((-24.0f - dBmin) * dx)/ (dBmax - dBmin)); + xred = (long)(((0.0f - dBmin) * dx)/ (dBmax - dBmin)); + lpp = &(lpobject->param); + + for (nu=0;nurtdata.dbLevel[nu]; + xx = (long)(((dBValue - dBmin) * dx)/ (dBmax - dBmin)); + if (xx < 0) xx=0; + if (xx > dx) xx=dx; + + // blue + if (xx > 0) + { + SelectObject(dc,lpp->meter_brush1); + x1=xx; + if (x1 > xgreen) x1=xgreen; + Rectangle(dc,rect.left,rect.top,rect.left+x1+1,rect.bottom); + } + //green + if (xx >= xgreen) + { + SelectObject(dc,lpp->meter_brush2); + x1=xx; + if (x1 > xred) x1=xred; + Rectangle(dc,rect.left+xgreen,rect.top,rect.left+x1+1,rect.bottom); + } + //red + if (xx >= xred) + { + SelectObject(dc,lpp->meter_brush3); + x1=xx; + Rectangle(dc,rect.left+xred,rect.top,rect.left+x1+1,rect.bottom); + } + //black + if (xx <= dx) + { + SelectObject(dc,GetStockObject(BLACK_BRUSH)); + Rectangle(dc,rect.left+xx,rect.top,rect.right+1,rect.bottom); + } + + rect.top +=dy; + rect.bottom +=dy; + } + SelectObject(dc,oldpen); + SelectObject(dc,oldbrush); +} + +static void DrawSTRIP_BUSAssignmentButton(LPT_VMSCTL_STRIPCTX lpobject, HDC dc, long nuVisibleSlider, long fAssigned, char * szBUSName) +{ + long x0,y0, dx,dy; + long cursor_height=20; + RECT rect; + HPEN oldpen; + HBRUSH oldbrush; + HFONT oldfont; + if (dc == NULL) return; + //compute local coordintate + dx = lpobject->dx_slider; + dy = VMSCTL_STRIP_DY_ASSIGN; + x0=VMSCTL_STRIPBUS_MARGIN + lpobject->margin_slider+ (lpobject->dx_slider*nuVisibleSlider); + //y0=lpobject->dy - VMSCTL_STRIPBUS_MARGIN- VMSCTL_STRIP_DY_ASSIGN; + + y0=VMSCTL_STRIPBUS_MARGIN+ VMSCTL_STRIP_DY_BUTTON +10 +lpobject->dy_meter+10+lpobject->dy_slider+10; + + dx = dx -4; + dy = dy -6; + + rect.left=x0+2; + rect.top=y0+3; + rect.right=rect.left+dx; + rect.bottom=rect.top+dy; + lpobject->rect_assign[nuVisibleSlider]=rect; + + + oldpen = (HPEN)SelectObject(dc,lpobject->param.assignbus_pen); + oldbrush = (HBRUSH)SelectObject(dc,lpobject->param.bkg1_brush); + oldfont = (HFONT)SelectObject(dc,lpobject->param.font1); + SetBkMode(dc,TRANSPARENT); + SetTextColor(dc,lpobject->param.assignbus_color); + + if (fAssigned != 0) + { + SetTextColor(dc,lpobject->param.assigned_color); + SelectObject(dc,lpobject->param.assigned_pen); + if (dx >= 40) SelectObject(dc,lpobject->param.font2); + } + + RoundRect(dc,rect.left,rect.top,rect.right,rect.bottom, 7,7); + DrawText(dc,szBUSName,(long)strlen(szBUSName),&rect,DT_SINGLELINE | DT_VCENTER | DT_CENTER); + + SelectObject(dc,oldpen); + SelectObject(dc,oldbrush); + SelectObject(dc,oldfont); + + +} + +static void DrawSTRIP_BUSAssignment(LPT_VMSCTL_STRIPCTX lpobject, HDC dc) +{ + LPT_VMSCTL_STRIP_DATA lpdata; + long vi, nuVisibleSlider; + nuVisibleSlider=0; + lpdata = &(lpobject->data); + if (lpdata->strip_pBUSNameList == NULL) return; + for (vi=0; vi < VMSCTL_MAX_NBBUS; vi++) + { + if ((lpdata->strip_assignmentbit[vi] & 0x10) != 0) + { + DrawSTRIP_BUSAssignmentButton(lpobject, dc, nuVisibleSlider, (long)(lpdata->strip_assignmentbit[vi] & 0x0F), lpdata->strip_pBUSNameList[vi]); + nuVisibleSlider++; + } + } +} + +static void DrawSTRIP_Slider(LPT_VMSCTL_STRIPCTX lpobject, HDC dc, long nuVisibleSlider, float dBValue) +{ + LPT_VMSCTL_STRIPPARAM lpp; + HDC dcmem; + char sss[64]; + long x0,y0, yy, dx,dy,x_middle; + long cursor_height=20; + RECT rect,rect2; + HPEN oldpen, sliderpen; + HBRUSH oldbrush, sliderbrush; + HFONT oldfont; + HBITMAP oldbmp; + if (dc == NULL) return; + + //compute local coordintate + dx = lpobject->dx_slider; + dy = lpobject->dy_slider; + x0=VMSCTL_STRIPBUS_MARGIN + lpobject->margin_slider+ (lpobject->dx_slider*nuVisibleSlider); + y0=VMSCTL_STRIPBUS_MARGIN + VMSCTL_STRIP_DY_BUTTON +10 +lpobject->dy_meter+10; + + dx = dx -4; + + rect.left=x0; + rect.top=y0; + rect.right=rect.left+dx; + rect.bottom=rect.top+dy; + lpobject->rect_slider[nuVisibleSlider]=rect; + + rect.left=0; + rect.top=0; + rect.right=rect.left+dx; + rect.bottom=rect.top+dy; + + x_middle = (rect.left+rect.right)>>1; + lpp = &(lpobject->param); + //define slider color according level + if (dBValue > 0.0f) + { + sliderpen = lpp->slider_pen_red; + sliderbrush = lpp->slider_brush_red; + } + else + { + sliderpen = lpp->slider_pen_green; + sliderbrush = lpp->slider_brush_green; + } + //compute slider horizontal position + if (dBValue > lpp->vmax) dBValue=lpp->vmax; + if (dBValue < lpp->vmin) dBValue=lpp->vmin; + yy = (long)(((dBValue - lpp->vmin) * (dy - cursor_height))/ (lpp->vmax - lpp->vmin)); + if (yy < 0) yy=0; + if (yy > dy) yy=dy; + + //we don't draw directly in screen. + //to avoid flickering we first build a bitmap in memory + dcmem=CreateCompatibleDC(dc); + if (lpobject->tempbmp ==NULL) lpobject->tempbmp=CreateCompatibleBitmap(dc,dx,dy); + oldbmp=(HBITMAP)SelectObject(dcmem,lpobject->tempbmp); + //Draw background + oldpen = (HPEN)SelectObject(dcmem,GetStockObject(NULL_PEN)); + oldbrush = (HBRUSH)SelectObject(dcmem,lpp->bkg1_brush); + oldfont = (HFONT)SelectObject(dcmem,lpobject->param.font0); + SetBkMode(dcmem,TRANSPARENT); + SetTextColor(dcmem,RGB(0,0,0)); + + //draw background + Rectangle(dcmem,rect.left,rect.top,rect.right+1,rect.bottom+1); + SelectObject(dcmem,sliderpen); + MoveToEx(dcmem,x_middle, rect.top, NULL); + LineTo(dcmem,x_middle, rect.bottom); + + //draw cursor + SelectObject(dcmem,sliderpen); + SelectObject(dcmem,sliderbrush); + RoundRect(dcmem,rect.left, rect.bottom-yy-cursor_height,rect.right, rect.bottom-yy-1,7,7); + rect2=rect; + rect2.top =rect2.bottom-yy-cursor_height; + rect2.bottom = rect2.top+cursor_height; + sprintf(sss,"%0.1f", dBValue); + DrawText(dcmem,sss,(long)strlen(sss),&rect2,DT_SINGLELINE | DT_VCENTER | DT_CENTER); + + SelectObject(dcmem,oldpen); + SelectObject(dcmem,oldbrush); + SelectObject(dcmem,oldfont); + //display bitmap on screen at the end. + BitBlt(dc,x0,y0,dx,dy,dcmem,0,0,SRCCOPY); + SelectObject(dcmem,oldbmp); + DeleteDC(dcmem); + +} + +static void DrawSTRIP_AllSliders(LPT_VMSCTL_STRIPCTX lpobject, HDC dc) +{ + LPT_VMSCTL_STRIP_DATA lpdata; + long vi, nuVisibleSlider; + nuVisibleSlider=0; + lpdata = &(lpobject->data); + for (vi=0; vi < VMSCTL_MAX_NBBUS; vi++) + { + if ((lpdata->strip_assignmentbit[vi] & 0x10) != 0) + { + DrawSTRIP_Slider(lpobject, dc, nuVisibleSlider, lpdata->strip_gain[vi]); + nuVisibleSlider++; + } + } +} + +static void ComputeStripDisplayData(LPT_VMSCTL_STRIPCTX lpobject) +{ + long ddx, dx, dy, nbBus; + dx= lpobject->dx - VMSCTL_STRIPBUS_MARGIN -VMSCTL_STRIPBUS_MARGIN; + dy= lpobject->dy - VMSCTL_STRIPBUS_MARGIN -VMSCTL_STRIPBUS_MARGIN; + if (dx < 80) dx =80; + if (dy < 150) dy =150; + lpobject->dx_meter = dx; + lpobject->dy_meter = 20; + lpobject->dy_slider = dy - VMSCTL_STRIP_DY_BUTTON -10 -lpobject->dy_meter - 10 - VMSCTL_STRIP_DY_ASSIGN-10; + + lpobject->dx_name = dx-VMSCTL_STRIP_DX_NICKNAME-10; + + // Bus number gives the slider number + nbBus=1; + if (lpobject->data.strip_nbBusDisplayed > nbBus) nbBus=lpobject->data.strip_nbBusDisplayed; + + // compute slider size according slider number. + ddx = dx / (nbBus+1); // we add a margin + if (ddx < 35) + { + ddx = (dx - (35 * nbBus)) >> 1; + if (ddx < 0) ddx =0; + } + ddx=ddx>>1; + dx=dx-ddx-ddx; + lpobject->margin_slider = ddx; + lpobject->dx_slider = dx / nbBus; +} + +static void DrawSTRIP(LPT_VMSCTL_STRIPCTX lpobject, HDC dc) +{ + ComputeStripDisplayData(lpobject); + DrawSTRIP_NickNameMute(lpobject, dc); + DrawSTRIP_Name(lpobject, dc); + DrawSTRIP_PeakMetersBkg(lpobject, dc); + DrawSTRIP_AllSliders(lpobject, dc); + DrawSTRIP_BUSAssignment(lpobject, dc); +} + + +/*---------------------------------------------------------------*/ +/* BUS CALLBACK */ +/*---------------------------------------------------------------*/ + +static long VMSCTL_Strip_GetStripIndex(LPT_VMSCTL_STRIPCTX lpobject,long nuVisibleSlider) +{ + LPT_VMSCTL_STRIP_DATA lpdata; + long vi, nu=0; + lpdata = &(lpobject->data); + for (vi=0; vi < VMSCTL_MAX_NBBUS; vi++) + { + if ((lpdata->strip_assignmentbit[vi] & 0x10) != 0) + { + if (nuVisibleSlider == nu) return vi; + nu++; + } + } + return 0; +} + +static long VMSCTL_Strip_WhereAmI(LPT_VMSCTL_STRIPCTX lpobject,long x0, long y0) +{ + long nuVisibleSlider; + RECT rect; + rect=lpobject->rect_nickname; + if ((x0 >= rect.left) && (x0 <= rect.right) && (y0>= rect.top) && (y0<=rect.bottom)) return VMSCTL_STRIP_ID_MUTE; + rect=lpobject->rect_name; + if ((x0 >= rect.left) && (x0 <= rect.right) && (y0>= rect.top) && (y0<=rect.bottom)) return VMSCTL_STRIP_ID_NAME; + rect=lpobject->rect_meters; + if ((x0 >= rect.left) && (x0 <= rect.right) && (y0>= rect.top) && (y0<=rect.bottom)) return VMSCTL_STRIP_ID_METER; + + for (nuVisibleSlider=0; nuVisibleSlider < lpobject->data.strip_nbBusDisplayed; nuVisibleSlider++) + { + rect=lpobject->rect_slider[nuVisibleSlider]; + if ((x0 >= rect.left) && (x0 <= rect.right) && (y0>= rect.top) && (y0<=rect.bottom)) return VMSCTL_STRIP_ID_GAIN+nuVisibleSlider; + rect=lpobject->rect_assign[nuVisibleSlider]; + if ((x0 >= rect.left) && (x0 <= rect.right) && (y0>= rect.top) && (y0<=rect.bottom)) return VMSCTL_STRIP_ID_ASSIGN+nuVisibleSlider; + } + return 0; +} + +static long VMSCTL_Strip_ManageLButtonDown(LPT_VMSCTL_STRIPCTX lpobject, HWND hw, long x0, long y0) +{ + LPT_VMSCTL_STRIP_DATA lpdata; + HDC dc; + float fValue; + long nuCtl, iStrip, nuVisibleSlider; + nuCtl=VMSCTL_Strip_WhereAmI(lpobject,x0, y0); + if (nuCtl == 0) return 0; + + lpdata = &(lpobject->data); + + // if the control is in the 8 possible displayed Sliders + if ((nuCtl >= VMSCTL_STRIP_ID_GAIN) && (nuCtl < (VMSCTL_STRIP_ID_GAIN + VMSCTL_MAX_NBBUS))) + { + nuVisibleSlider = nuCtl - VMSCTL_STRIP_ID_GAIN; + iStrip = VMSCTL_Strip_GetStripIndex(lpobject,nuVisibleSlider); + lpobject->start_value = lpdata->strip_gain[iStrip]; + if (lpobject->start_value > lpobject->param.vmax) lpobject->start_value = lpobject->param.vmax; + if (lpobject->start_value < lpobject->param.vmin) lpobject->start_value = lpobject->param.vmin; + lpobject->LastCapture = SetCapture(hw); + lpobject->mouse_y0=y0; + lpobject->last_y0=y0; + lpobject->mouseCapture=TRUE; + lpobject->ctlRunning=nuCtl; + lpobject->iStripRunning=iStrip; + return 0; + } + // if the control is in the 8 possible assignation buttton. + if ((nuCtl >= VMSCTL_STRIP_ID_ASSIGN) && (nuCtl < (VMSCTL_STRIP_ID_ASSIGN + VMSCTL_MAX_NBBUS))) + { + nuVisibleSlider = nuCtl - VMSCTL_STRIP_ID_ASSIGN; + iStrip = VMSCTL_Strip_GetStripIndex(lpobject,nuVisibleSlider); + + if ((lpdata->strip_assignmentbit[iStrip] & 0x0F) == 0) + { + lpdata->strip_assignmentbit[iStrip] |= 0x01; + fValue=1.0f; + } + else + { + lpdata->strip_assignmentbit[iStrip] &= 0xF0; + fValue=0.0f; + } + lpobject->param.lpCallback(lpobject->param.lpuser, lpobject->Ident, nuCtl, fValue); + dc=GetDC(hw); + DrawSTRIP_BUSAssignmentButton(lpobject, dc, nuVisibleSlider, (long)(fValue), lpdata->strip_pBUSNameList[iStrip]); + ReleaseDC(hw,dc); + return 0; + } + + // test other control if required + switch(nuCtl) + { + case VMSCTL_STRIP_ID_MUTE: + if (lpdata->strip_mute == 0) + { + lpdata->strip_mute =1; + fValue=1.0f; + } + else + { + lpdata->strip_mute =0; + fValue=0.0f; + } + lpobject->param.lpCallback(lpobject->param.lpuser, lpobject->Ident, nuCtl, fValue); + dc=GetDC(hw); + DrawSTRIP_NickNameMute(lpobject, dc); + ReleaseDC(hw,dc); + break; + case VMSCTL_BUS_ID_NAME: + break; + case VMSCTL_BUS_ID_METER: + break; + } + + return 0; +} + +static long VMSCTL_Strip_ManageLButtonDbclick(LPT_VMSCTL_STRIPCTX lpobject, HWND hw, long x0, long y0) +{ + HDC dc; + float fValue; + long nuCtl, iStrip, nuVisibleSlider; + nuCtl=VMSCTL_Strip_WhereAmI(lpobject,x0, y0); + if (nuCtl == 0) return 0; + + // if the control is in the 8 possible displayed Sliders + if ((nuCtl >= VMSCTL_STRIP_ID_GAIN) && (nuCtl < (VMSCTL_STRIP_ID_GAIN + VMSCTL_MAX_NBBUS))) + { + nuVisibleSlider = nuCtl - VMSCTL_STRIP_ID_GAIN; + iStrip = VMSCTL_Strip_GetStripIndex(lpobject,nuVisibleSlider); + + fValue=0.0f; + lpobject->data.strip_gain[iStrip]=fValue; + lpobject->param.lpCallback(lpobject->param.lpuser, lpobject->Ident, nuCtl, fValue); + + dc=GetDC(hw); + DrawSTRIP_Slider(lpobject, dc, nuVisibleSlider, fValue); + ReleaseDC(hw,dc); + return 0; + } + VMSCTL_Strip_ManageLButtonDown(lpobject, hw, x0, y0); + return 0; +} + + +static long VMSCTL_Strip_ManageMouseMove(LPT_VMSCTL_STRIPCTX lpobject, HWND hw, long x0, long y0) +{ + HDC dc; + LPT_VMSCTL_STRIPPARAM lpp; + long dy,ddy, nuCtl, iStrip, nuVisibleSlider; + float fValue; + if (lpobject->mouseCapture == FALSE) return -1; + lpp = &(lpobject->param); + nuCtl=lpobject->ctlRunning; + if ((nuCtl >= VMSCTL_STRIP_ID_GAIN) && (nuCtl < (VMSCTL_STRIP_ID_GAIN + VMSCTL_MAX_NBBUS))) + { + iStrip = lpobject->iStripRunning; + if (y0 != lpobject->last_y0) + { + dy=y0-lpobject->mouse_y0; + ddy=lpobject->dy_slider; + + fValue=lpobject->start_value - (((lpp->vmax - lpp->vmin) * dy) / ddy); + if (fValue < lpp->vmin) fValue=lpp->vmin; + if (fValue > lpp->vmax) fValue=lpp->vmax; + if (fValue != lpobject->data.strip_gain[iStrip]) + { + lpobject->data.strip_gain[iStrip]=fValue; + lpobject->param.lpCallback(lpobject->param.lpuser, lpobject->Ident, nuCtl, fValue); + + nuVisibleSlider = nuCtl - VMSCTL_STRIP_ID_GAIN; + dc=GetDC(hw); + DrawSTRIP_Slider(lpobject, dc, nuVisibleSlider, fValue); + ReleaseDC(hw,dc); + } + lpobject->last_y0 = y0; + } + + } + return 0; +} + +static long VMSCTL_Strip_ManageLButtonUp(LPT_VMSCTL_STRIPCTX lpobject, HWND hw, long x0, long y0) +{ + if (lpobject->mouseCapture == FALSE) return -1; + ReleaseCapture(); + if (lpobject->LastCapture != NULL) SetCapture(lpobject->LastCapture); + lpobject->mouseCapture=FALSE; + return 0; +} + + +static LRESULT CALLBACK VMSCTL_StripCallback(HWND hw, //handle of the window. + UINT msg, //Message Ident. + WPARAM p1, //parameter 1. + LPARAM p2) //parameter 2 +{ + HPEN oldpen; + HBRUSH oldbrush; + RECT rect; + LPCREATESTRUCT lpcs; + LPT_VMSCTL_STRIPCTX lpobject; + HDC dc; + PAINTSTRUCT ps; + switch (msg) + { + //here we create our structure + case WM_CREATE: + lpcs=(LPCREATESTRUCT)p2; + lpobject=(LPT_VMSCTL_STRIPCTX)lpcs->lpCreateParams; + lpobject->hw=hw; + TOOL_StorePointerInWindow(hw,lpobject); + break; + //on mouse click we get the focus. + case WM_MOUSEACTIVATE: + if (GetFocus()!=hw) SetFocus(hw); + return MA_ACTIVATE; + //on Focus change we redraw the control + case WM_SETFOCUS: + case WM_KILLFOCUS: + InvalidateRect(hw,NULL,FALSE); + return 0; + //here we draw all the control + case WM_PAINT: + dc=BeginPaint(hw,&ps); + lpobject=(LPT_VMSCTL_STRIPCTX)TOOL_RecallPointerFromWindow(hw); + if (lpobject != NULL) DrawSTRIP(lpobject, dc); + EndPaint(hw,&ps); + return 0; + case WM_ERASEBKGND: + lpobject=(LPT_VMSCTL_STRIPCTX)TOOL_RecallPointerFromWindow(hw); + if (lpobject == NULL) return 0; + + dc=(HDC)p1; + GetClientRect(hw,&rect); + oldbrush = (HBRUSH)SelectObject(dc,lpobject->param.bkg0_brush); + oldpen = (HPEN)SelectObject(dc,GetStockObject(NULL_PEN)); + Rectangle(dc,rect.left-1,rect.top-1,rect.right+1,rect.bottom+1); + oldbrush = (HBRUSH)SelectObject(dc,lpobject->param.bkg1_brush); + RoundRect(dc,rect.left,rect.top,rect.right,rect.bottom, 7,7); + SelectObject(dc,oldpen); + SelectObject(dc,oldbrush); + return 0; + //mouse behavior + case WM_LBUTTONDOWN: + lpobject=(LPT_VMSCTL_STRIPCTX)TOOL_RecallPointerFromWindow(hw); + if (lpobject == NULL) break; + VMSCTL_Strip_ManageLButtonDown(lpobject, hw, (short int)LOWORD(p2), (short int)HIWORD(p2)); + break; + case WM_LBUTTONDBLCLK: + lpobject=(LPT_VMSCTL_STRIPCTX)TOOL_RecallPointerFromWindow(hw); + if (lpobject == NULL) break; + VMSCTL_Strip_ManageLButtonDbclick(lpobject, hw, (short int)LOWORD(p2), (short int)HIWORD(p2)); + break; + case WM_MOUSEMOVE: + lpobject=(LPT_VMSCTL_STRIPCTX)TOOL_RecallPointerFromWindow(hw); + if (lpobject == NULL) break; + VMSCTL_Strip_ManageMouseMove(lpobject, hw, (short int)LOWORD(p2), (short int)HIWORD(p2)); + break; + case WM_LBUTTONUP: + lpobject=(LPT_VMSCTL_STRIPCTX)TOOL_RecallPointerFromWindow(hw); + if (lpobject == NULL) break; + VMSCTL_Strip_ManageLButtonUp(lpobject, hw, (short int)LOWORD(p2), (short int)HIWORD(p2)); + break; + // control ending + case WM_CLOSE: + DestroyWindow(hw); + return 0; + case WM_DESTROY: + lpobject=TOOL_RecallPointerFromWindow(hw); + if (lpobject != NULL) + { + //if (lpobject->tempbmp !=NULL) DeleteObject(lpobject->tempbmp); + free(lpobject); + TOOL_StorePointerInWindow(hw,NULL); + } + break; + + } + return DefWindowProc(hw,msg,p1,p2); +} + + +HWND VMSCTL_CreateSTRIP(HWND hParent, long Ident, long x0,long y0, LPT_VMSCTL_STRIPPARAM lpparam) +{ + HWND hw; + char szName[64]; + long wstyle, vi; + LPT_VMSCTL_STRIPCTX lpobject; + //we allocate memory for our structure + lpobject=(LPT_VMSCTL_STRIPCTX)malloc(sizeof(T_VMSCTL_STRIPCTX)); + if (lpobject == NULL) return NULL; + memset(lpobject,0, sizeof(T_VMSCTL_STRIPCTX)); + if (lpparam == NULL) return NULL; + lpobject->param = *lpparam; + //define control size according bitmap. + lpobject->dx=100; + lpobject->dy=100; + //init rtdata; + for (vi=0;vi<8;vi++) + { + lpobject->rtdata.dbLevel[vi]=-100.0f; + } + //set control ident + lpobject->Ident=Ident; + //we create window with window-creation data + wstyle=WS_CHILD | WS_TABSTOP; // | WS_VISIBLE + sprintf(szName,"Strip #%i", Ident); + hw=CreateWindow(VMSCTL_CLASSNAME_STRIP, szName, + wstyle,x0,y0, + lpobject->dx, // window width + lpobject->dy, // window height + hParent, // parent Windows Handle. + (HMENU)Ident, // child-window identifier. + G_hinstance, // handle of application instance + lpobject); // we communicate our pointer (see WM_CREATE) + + return hw; +} + +long VMSCTL_PositionSTRIP(HWND hw, long x0,long y0, long dx, long dy, long fShow) +{ + LPT_VMSCTL_STRIPCTX lpobject; + BOOL fUpdate=FALSE; + lpobject=(LPT_VMSCTL_STRIPCTX)TOOL_RecallPointerFromWindow(hw); + if (lpobject == NULL) return -1; + if (fShow == 0) + { + lpobject->x0 = x0; + lpobject->y0 = y0; + lpobject->dx = dx; + lpobject->dy = dy; + if (lpobject->isShown != 0) + { + ShowWindow(hw, SW_HIDE); + } + lpobject->isShown = fShow; + } + else + { + if (lpobject->x0 != x0) fUpdate=TRUE; + if (lpobject->y0 != y0) fUpdate=TRUE; + if (lpobject->dx != dx) fUpdate=TRUE; + if (lpobject->dy != dy) fUpdate=TRUE; + if (lpobject->isShown == 0) fUpdate=TRUE; + + if (fUpdate == TRUE) + { + //internal bitmap size can be changed + if (lpobject->tempbmp !=NULL) DeleteObject(lpobject->tempbmp); + lpobject->tempbmp=NULL; + + lpobject->x0 = x0; + lpobject->y0 = y0; + lpobject->dx = dx; + lpobject->dy = dy; + + ComputeStripDisplayData(lpobject); + SetWindowPos(hw,HWND_TOP,lpobject->x0,lpobject->y0,lpobject->dx,lpobject->dy,SWP_SHOWWINDOW); + lpobject->isShown = fShow; + } + } + //if (fUpdate == TRUE) InvalidateRect(hw, NULL, TRUE); + return 0; +} + +long VMSCTL_SetDataSTRIP(HWND hw, LPT_VMSCTL_STRIP_DATA pData, long fUpdateAll) +{ + BOOL fUpdateMuteDisplay; + long vi,nuVisibleSlider; + BOOL fBusChanged, fAssignChanged, fGainChanged; + HDC dc=NULL; + LPT_VMSCTL_STRIP_DATA pCurrent; + LPT_VMSCTL_STRIPCTX lpobject; + lpobject=(LPT_VMSCTL_STRIPCTX)TOOL_RecallPointerFromWindow(hw); + if (lpobject == NULL) return -1; + + pCurrent = &(lpobject->data); + if (lpobject->isShown != 0) + { + dc=GetDC(hw); + } + + // NickName Button + fUpdateMuteDisplay=FALSE; + if ((fUpdateAll != 0) || (pCurrent->strip_nickname[0] == 0)) + { + strcpy(pCurrent->strip_nickname, pData->strip_nickname); + fUpdateMuteDisplay=TRUE; + } + // Strip Name + if ((wcscmp(pCurrent->strip_namew, pData->strip_namew) != 0) || (fUpdateAll != 0)) + { + wcscpy(pCurrent->strip_namew, pData->strip_namew); + DrawSTRIP_Name(lpobject, dc); + } + + // check bus number change + fBusChanged = fUpdateAll; + fAssignChanged = fUpdateAll; + fGainChanged =fUpdateAll; + if (pCurrent->strip_nbBusDisplayed != pData->strip_nbBusDisplayed) + { + fBusChanged = TRUE; + fAssignChanged = TRUE; + pCurrent->strip_nbBusDisplayed = pData->strip_nbBusDisplayed; + //internal bitmap size can be changed + if (lpobject->tempbmp !=NULL) DeleteObject(lpobject->tempbmp); + lpobject->tempbmp=NULL; + } + // check slide bus assignement change + pCurrent->strip_pBUSNameList = pData->strip_pBUSNameList; + for (vi=0; vi < VMSCTL_MAX_NBBUS; vi++) + { + if ((pCurrent->strip_assignmentbit[vi] & 0x10) != (pData->strip_assignmentbit[vi] & 0x10)) fBusChanged=TRUE; + if ((pCurrent->strip_assignmentbit[vi] & 0x01) != (pData->strip_assignmentbit[vi] & 0x01)) fAssignChanged=TRUE; + pCurrent->strip_assignmentbit[vi] = pData->strip_assignmentbit[vi]; + } + if (fBusChanged == TRUE) ComputeStripDisplayData(lpobject); + if ((fBusChanged == TRUE) || (fAssignChanged == TRUE)) DrawSTRIP_BUSAssignment(lpobject, dc); + + // check slider gain + nuVisibleSlider=0; + for (vi=0; vi < VMSCTL_MAX_NBBUS; vi++) + { + fGainChanged=fUpdateAll; + if ((pCurrent->strip_assignmentbit[vi] & 0x10) != 0) + { + if (pCurrent->strip_gain[vi] != pData->strip_gain[vi]) fGainChanged=TRUE; + // if the slider is used by the mouse we do not update display. + if ((lpobject->mouseCapture == TRUE) && (lpobject->iStripRunning == vi)) fGainChanged=FALSE; + if ((fBusChanged == TRUE) || (fGainChanged == TRUE)) + { + pCurrent->strip_gain[vi] = pData->strip_gain[vi]; + DrawSTRIP_Slider(lpobject, dc, nuVisibleSlider, pCurrent->strip_gain[vi]); + } + nuVisibleSlider++; + } + } + // Mute Button + if ((pCurrent->strip_mute != pData->strip_mute) || (fUpdateMuteDisplay == TRUE) || (fUpdateAll == TRUE)) + { + pCurrent->strip_mute = pData->strip_mute; + DrawSTRIP_NickNameMute(lpobject, dc); + } + + if (dc != NULL) ReleaseDC(hw,dc); + + return 0; +} + +long VMSCTL_ResetDataSTRIP(HWND hw) +{ + long vi; + LPT_VMSCTL_STRIPCTX lpobject; + lpobject=(LPT_VMSCTL_STRIPCTX)TOOL_RecallPointerFromWindow(hw); + if (lpobject == NULL) return -1; + memset(&(lpobject->data), 0, sizeof(T_VMSCTL_STRIPPARAM)); + for (vi=0;vi<8;vi++) lpobject->rtdata.dbLevel[vi]=-100.0f; + return 0; +} + + +long VMSCTL_SetRTDataSTRIP(HWND hw, LPT_VMSCTL_RT_DATA pRTData) +{ + HDC dc; + long nu; + LPT_VMSCTL_STRIPCTX lpobject; + lpobject=(LPT_VMSCTL_STRIPCTX)TOOL_RecallPointerFromWindow(hw); + if (lpobject == NULL) return -1; + + if (pRTData == NULL) return -2; + + //compute value to display, with a release factor + for (nu=0;nu<2;nu++) //display 2 channels only + { + if (pRTData->dbLevel[nu] > lpobject->rtdata.dbLevel[nu]) lpobject->rtdata.dbLevel[nu]=pRTData->dbLevel[nu]; + else + { + lpobject->rtdata.dbLevel[nu] = lpobject->rtdata.dbLevel[nu] - PEAKMETER_RELEASE_DECREMENT; + if (lpobject->rtdata.dbLevel[nu] < -100.0f) lpobject->rtdata.dbLevel[nu]=-100.0f; + } + } + //display peak meter. + if (lpobject->isShown != 0) + { + dc=GetDC(hw); + DrawSTRIP_PeakMeters(lpobject, dc); + ReleaseDC(hw,dc); + } + + return 0; +} + +long VMSCTL_GetIndexSTRIP(HWND hw,long nuVisibleSlider) +{ + LPT_VMSCTL_STRIPCTX lpobject; + lpobject=(LPT_VMSCTL_STRIPCTX)TOOL_RecallPointerFromWindow(hw); + if (lpobject == NULL) return 0; + return VMSCTL_Strip_GetStripIndex(lpobject,nuVisibleSlider); +} + + + + + + + + + + + + + + + + + + + + + + + +/*---------------------------------------------------------------*/ +/* BUS CONTROL */ +/*---------------------------------------------------------------*/ + +#define VMSCTL_BUS_DX_NICKNAME 30 +#define VMSCTL_BUS_DX_MON 40 + +#define VMSCTL_BUS_DXMIN_NAME 100 +#define VMSCTL_BUS_DXMIN_PEAKMETER 100 +#define VMSCTL_BUS_DXMIN_SLIDER 100 + +typedef struct tagVMSCTL_BUSCTX +{ + HWND hw; + long Ident; + long x0,y0,dx,dy; + long isShown; + + RECT rect_nickname; + RECT rect_name; + RECT rect_meters; + RECT rect_slider; + RECT rect_monitor; + + long dx_meter; + long dx_slider; + HBITMAP tempbmp; + + float start_value; + HWND LastCapture; + long mouse_x0; + long last_x0; + BOOL mouseCapture; + long ctlrunning; + + float fMaxLevelToDisplay; + float fMaxLevelDisplayed; + long nMaxLevelToDisplay; + T_VMSCTL_BUSPARAM param; + T_VMSCTL_BUS_DATA data; + T_VMSCTL_RT_DATA rtdata; +} T_VMSCTL_BUSCTX, *PT_VMSCTL_vCTX, *LPT_VMSCTL_BUSCTX; + + +static void DrawBUS_NickNameMute(LPT_VMSCTL_BUSCTX lpobject, HDC dc) +{ + char sss[64]; + RECT rect; + HFONT oldfont; + HPEN oldpen; + HBRUSH oldbrush; + if (dc == NULL) return; + + rect.left=VMSCTL_STRIPBUS_MARGIN; + rect.top=VMSCTL_STRIPBUS_MARGIN; + rect.right=rect.left+VMSCTL_BUS_DX_NICKNAME; + rect.bottom=lpobject->dy-5; + lpobject->rect_nickname=rect; + + oldpen = (HPEN)SelectObject(dc,lpobject->param.assignbus_pen); + oldbrush = (HBRUSH)SelectObject(dc,lpobject->param.bkg1_brush); + oldfont = (HFONT)SelectObject(dc,lpobject->param.font1); + SetBkMode(dc,TRANSPARENT); + SetTextColor(dc,lpobject->param.assignbus_color); + + if (lpobject->data.bus_mute != 0) + { + SetTextColor(dc,lpobject->param.mutered_color); + SelectObject(dc,lpobject->param.mutered_pen); + } + + RoundRect(dc,rect.left,rect.top,rect.right,rect.bottom, 5,5); + strcpy(sss,lpobject->data.bus_nickname); + DrawText(dc,sss,(long)strlen(sss),&rect,DT_SINGLELINE | DT_VCENTER | DT_CENTER); + + SelectObject(dc,oldpen); + SelectObject(dc,oldbrush); + SelectObject(dc,oldfont); + +} + +static void DrawBUS_Name(LPT_VMSCTL_BUSCTX lpobject, HDC dc) +{ + RECT rect; + HFONT oldfont; + HPEN oldpen; + HBRUSH oldbrush; + if (dc == NULL) return; + + rect.left=VMSCTL_STRIPBUS_MARGIN+VMSCTL_BUS_DX_NICKNAME+10; + rect.top=2; + rect.right=rect.left+VMSCTL_BUS_DXMIN_NAME; + rect.bottom=lpobject->dy-2; + lpobject->rect_name=rect; + + oldpen = (HPEN)SelectObject(dc,GetStockObject(NULL_PEN)); + oldbrush = (HBRUSH)SelectObject(dc,lpobject->param.bkg1_brush); + oldfont = (HFONT)SelectObject(dc,lpobject->param.font2); + SetBkMode(dc,TRANSPARENT); + SetTextColor(dc,lpobject->param.name_color); + + RoundRect(dc,rect.left,rect.top,rect.right,rect.bottom, 5,5); + DrawTextW(dc,lpobject->data.bus_namew,(long)wcslen(lpobject->data.bus_namew),&rect,DT_SINGLELINE | DT_VCENTER | DT_LEFT); + + SelectObject(dc,oldpen); + SelectObject(dc,oldbrush); + SelectObject(dc,oldfont); +} + + +static void DrawBUS_PeakMetersBkg(LPT_VMSCTL_BUSCTX lpobject, HDC dc) +{ + long dx; + RECT rect; + HPEN oldpen; + HBRUSH oldbrush; + if (dc == NULL) return; + + dx = lpobject->dx_meter; + rect.left=VMSCTL_STRIPBUS_MARGIN+VMSCTL_BUS_DX_NICKNAME+10+VMSCTL_BUS_DXMIN_NAME+10; + rect.top=VMSCTL_STRIPBUS_MARGIN; + rect.right=rect.left+dx; + rect.bottom=lpobject->dy-VMSCTL_STRIPBUS_MARGIN; + lpobject->rect_meters=rect; + + oldpen = (HPEN)SelectObject(dc,GetStockObject(BLACK_PEN)); + oldbrush = (HBRUSH)SelectObject(dc,GetStockObject(BLACK_BRUSH)); + Rectangle(dc,rect.left,rect.top,rect.right,rect.bottom); + + SelectObject(dc,oldpen); + SelectObject(dc,oldbrush); +} + +static void DrawBUS_PeakMeters(LPT_VMSCTL_BUSCTX lpobject, HDC dc) +{ + char sss[64]; + LPT_VMSCTL_BUSPARAM lpp; + float dBValue, dBmin=-80.0f, dBmax=+12.0f; + long nu,nbMeter=2; + long dx,dy,xx,x1,xgreen,xred; + RECT rect, rectmax; + HPEN oldpen; + HBRUSH oldbrush; + HFONT oldfont; + if (dc == NULL) return; + + dx = lpobject->dx_meter-6; + rect.left=VMSCTL_STRIPBUS_MARGIN+VMSCTL_BUS_DX_NICKNAME+10+VMSCTL_BUS_DXMIN_NAME+10; + rect.top=VMSCTL_STRIPBUS_MARGIN; + rect.bottom=lpobject->dy-VMSCTL_STRIPBUS_MARGIN; + dy = (rect.bottom-rect.top-4) / nbMeter; + + // compute peak meter zone + rect.left+=3; + rect.top+=3; + rect.right=rect.left+dx; + rect.bottom = rect.top+dy; + + // compute dB max zone and reduce peak meter zone + rectmax = rect; + rect.right -=25; + dx -=25; + rectmax.left=rect.right; + rectmax.bottom +=dy; + + // prepare display and compute different level + oldfont = (HFONT)SelectObject(dc,lpobject->param.font0); + oldpen = (HPEN)SelectObject(dc,GetStockObject(NULL_PEN)); + oldbrush = (HBRUSH)SelectObject(dc,GetStockObject(BLACK_BRUSH)); + xgreen = (long)(((-24.0f - dBmin) * dx)/ (dBmax - dBmin)); + xred = (long)(((0.0f - dBmin) * dx)/ (dBmax - dBmin)); + lpp = &(lpobject->param); + + for (nu=0;nurtdata.dbLevel[nu]; + xx = (long)(((dBValue - dBmin) * dx)/ (dBmax - dBmin)); + if (xx < 0) xx=0; + if (xx > dx) xx=dx; + + // blue + if (xx > 0) + { + SelectObject(dc,lpp->meter_brush1); + x1=xx; + if (x1 > xgreen) x1=xgreen; + Rectangle(dc,rect.left,rect.top,rect.left+x1+1,rect.bottom); + } + //green + if (xx >= xgreen) + { + SelectObject(dc,lpp->meter_brush2); + x1=xx; + if (x1 > xred) x1=xred; + Rectangle(dc,rect.left+xgreen,rect.top,rect.left+x1+1,rect.bottom); + } + //red + if (xx >= xred) + { + SelectObject(dc,lpp->meter_brush3); + x1=xx; + Rectangle(dc,rect.left+xred,rect.top,rect.left+x1+1,rect.bottom); + } + //black + if (xx <= dx) + { + SelectObject(dc,GetStockObject(BLACK_BRUSH)); + Rectangle(dc,rect.left+xx,rect.top,rect.right+1,rect.bottom); + } + + rect.top +=dy; + rect.bottom +=dy; + } + // display max level + if (lpobject->fMaxLevelDisplayed != lpobject->fMaxLevelToDisplay) + { + SetBkMode(dc,TRANSPARENT); + SetTextColor(dc,lpobject->param.name_color); + if (lpobject->fMaxLevelToDisplay < -99.0f) strcpy(sss,"-"); + else sprintf(sss,"%0.1f", lpobject->fMaxLevelToDisplay); + SelectObject(dc,GetStockObject(BLACK_BRUSH)); + Rectangle(dc,rectmax.left,rectmax.top,rectmax.right+1,rectmax.bottom+1); + DrawText(dc,sss,(long)strlen(sss),&rectmax,DT_SINGLELINE | DT_VCENTER | DT_CENTER); + lpobject->fMaxLevelDisplayed=lpobject->fMaxLevelToDisplay; + } + SelectObject(dc,oldpen); + SelectObject(dc,oldbrush); + SelectObject(dc,oldfont); +} + + +static void DrawBUS_Slider(LPT_VMSCTL_BUSCTX lpobject, HDC dc) +{ + HDC dcmem; + char sss[64]; + float dBValue; + LPT_VMSCTL_BUSPARAM lpp; + long x0,y0, xx,dx,dy,y_middle; + long cursor_width=35; + RECT rect,rect2; + HPEN oldpen, sliderpen; + HBRUSH oldbrush, sliderbrush; + HFONT oldfont; + HBITMAP oldbmp; + if (dc == NULL) return; + + //compute local coordintate + dx = lpobject->dx_slider; + dy = lpobject->dy-VMSCTL_STRIPBUS_MARGIN-VMSCTL_STRIPBUS_MARGIN; + x0=VMSCTL_STRIPBUS_MARGIN+VMSCTL_BUS_DX_NICKNAME+10+VMSCTL_BUS_DXMIN_NAME+10+lpobject->dx_meter+10; + y0=VMSCTL_STRIPBUS_MARGIN; + + rect.left=x0; + rect.top=y0; + rect.right=rect.left+dx; + rect.bottom=rect.top+dy; + lpobject->rect_slider=rect; + + rect.left=0; + rect.top=0; + rect.right=rect.left+dx; + rect.bottom=rect.top+dy; + + y_middle = (rect.bottom+rect.top)>>1; + lpp = &(lpobject->param); + dBValue = lpobject->data.bus_gain; + //define slider color according level + if (dBValue > 0.0f) + { + sliderpen = lpp->slider_pen_red; + sliderbrush = lpp->slider_brush_red; + } + else + { + sliderpen = lpp->slider_pen_green; + sliderbrush = lpp->slider_brush_green; + } + //compute slider horizontal position + xx = (long)(((dBValue - lpp->vmin) * (dx - cursor_width))/ (lpp->vmax - lpp->vmin)); + if (xx < 0) xx=0; + if (xx > dx) xx=dx; + + //we don't draw directly in screen. + //to avoid flickering we first build a bitmap in memory + dcmem=CreateCompatibleDC(dc); + if (lpobject->tempbmp ==NULL) lpobject->tempbmp=CreateCompatibleBitmap(dc,dx,dy); + oldbmp=(HBITMAP)SelectObject(dcmem,lpobject->tempbmp); + //Draw background + oldpen = (HPEN)SelectObject(dcmem,GetStockObject(NULL_PEN)); + oldbrush = (HBRUSH)SelectObject(dcmem,lpp->bkg1_brush); + oldfont = (HFONT)SelectObject(dcmem,lpobject->param.font0); + SetBkMode(dcmem,TRANSPARENT); + SetTextColor(dcmem,RGB(0,0,0)); + + //draw background + Rectangle(dcmem,rect.left,rect.top,rect.right+1,rect.bottom+1); + SelectObject(dcmem,sliderpen); + MoveToEx(dcmem,rect.left,y_middle, NULL); + LineTo(dcmem,rect.right, y_middle); + + //draw cursor + SelectObject(dcmem,sliderpen); + SelectObject(dcmem,sliderbrush); + RoundRect(dcmem,rect.left+xx, rect.top,rect.left+xx+cursor_width-1,rect.bottom,7,7); + rect2=rect; + rect2.left +=xx; + rect2.right = rect2.left+cursor_width; + sprintf(sss,"%0.1f", dBValue); + DrawText(dcmem,sss,(long)strlen(sss),&rect2,DT_SINGLELINE | DT_VCENTER | DT_CENTER); + + SelectObject(dcmem,oldpen); + SelectObject(dcmem,oldbrush); + SelectObject(dcmem,oldfont); + //display bitmap on screen at the end. + BitBlt(dc,x0,y0,dx,dy,dcmem,0,0,SRCCOPY); + SelectObject(dcmem,oldbmp); + DeleteDC(dcmem); + +} + +static void DrawBUS_Monitor(LPT_VMSCTL_BUSCTX lpobject, HDC dc) +{ + char sss[64]; + RECT rect; + HFONT oldfont; + HPEN oldpen; + HBRUSH oldbrush; + if (dc == NULL) return; + + if (lpobject->data.bus_fMonitorSupport == 0) return; + + rect.right = lpobject->dx-VMSCTL_STRIPBUS_MARGIN; + rect.left=rect.right-VMSCTL_BUS_DX_MON; + //check if there is enough place to display it. + if (rect.left < (lpobject->rect_slider.right+10)) rect.left = lpobject->rect_slider.right+10; + rect.right = rect.left + VMSCTL_BUS_DX_MON; + + rect.top=VMSCTL_STRIPBUS_MARGIN; + rect.bottom=lpobject->dy-VMSCTL_STRIPBUS_MARGIN; + lpobject->rect_monitor=rect; + + oldpen = (HPEN)SelectObject(dc,lpobject->param.assignbus_pen); + oldbrush = (HBRUSH)SelectObject(dc,lpobject->param.bkg1_brush); + oldfont = (HFONT)SelectObject(dc,lpobject->param.font1); + SetBkMode(dc,TRANSPARENT); + SetTextColor(dc,lpobject->param.assignbus_color); + + if (lpobject->data.bus_monitor != 0) + { + SetTextColor(dc,RGB(0,0,0)); + SelectObject(dc,lpobject->param.monitor_brush); + SelectObject(dc,lpobject->param.monitor_pen); + } + + RoundRect(dc,rect.left,rect.top,rect.right,rect.bottom, 5,5); + strcpy(sss,"Mon"); + DrawText(dc,sss,(long)strlen(sss),&rect,DT_SINGLELINE | DT_VCENTER | DT_CENTER); + + SelectObject(dc,oldpen); + SelectObject(dc,oldbrush); + SelectObject(dc,oldfont); + +} + +static void ComputeBusDisplayData(LPT_VMSCTL_BUSCTX lpobject) +{ + long dx; + dx= lpobject->dx - VMSCTL_STRIPBUS_MARGIN- VMSCTL_BUS_DX_NICKNAME-10-VMSCTL_BUS_DXMIN_NAME-VMSCTL_STRIPBUS_MARGIN; + if (lpobject->data.bus_fMonitorSupport != 0) dx = dx -10 -VMSCTL_BUS_DX_MON; + dx= (dx-20) >> 1; + if (dx < 100) dx =100; + lpobject->dx_meter = dx; + lpobject->dx_slider = dx; + lpobject->fMaxLevelDisplayed=-500.0f; //to force display refresh +} + + +static void DrawBUS(LPT_VMSCTL_BUSCTX lpobject, HDC dc) +{ + ComputeBusDisplayData(lpobject); + DrawBUS_NickNameMute(lpobject, dc); + DrawBUS_Name(lpobject, dc); + DrawBUS_PeakMetersBkg(lpobject, dc); + DrawBUS_Slider(lpobject, dc); + DrawBUS_Monitor(lpobject, dc); +} + + +/*---------------------------------------------------------------*/ +/* BUS CALLBACK */ +/*---------------------------------------------------------------*/ + + +static long VMSCTL_Bus_WhereAmI(LPT_VMSCTL_BUSCTX lpobject,long x0, long y0) +{ + RECT rect; + rect=lpobject->rect_nickname; + if ((x0 >= rect.left) && (x0 <= rect.right) && (y0>= rect.top) && (y0<=rect.bottom)) return VMSCTL_BUS_ID_MUTE; + rect=lpobject->rect_name; + if ((x0 >= rect.left) && (x0 <= rect.right) && (y0>= rect.top) && (y0<=rect.bottom)) return VMSCTL_BUS_ID_NAME; + rect=lpobject->rect_meters; + if ((x0 >= rect.left) && (x0 <= rect.right) && (y0>= rect.top) && (y0<=rect.bottom)) return VMSCTL_BUS_ID_METER; + rect=lpobject->rect_slider; + if ((x0 >= rect.left) && (x0 <= rect.right) && (y0>= rect.top) && (y0<=rect.bottom)) return VMSCTL_BUS_ID_GAIN; + rect=lpobject->rect_monitor; + if ((x0 >= rect.left) && (x0 <= rect.right) && (y0>= rect.top) && (y0<=rect.bottom)) return VMSCTL_BUS_ID_MONITOR; + return 0; +} + +static long VMSCTL_Bus_ManageLButtonDown(LPT_VMSCTL_BUSCTX lpobject, HWND hw, long x0, long y0) +{ + HDC dc; + float fValue; + long nuCtl; + nuCtl=VMSCTL_Bus_WhereAmI(lpobject,x0, y0); + if (nuCtl == 0) return 0; + + switch(nuCtl) + { + case VMSCTL_BUS_ID_MUTE: + if (lpobject->data.bus_mute == 0) + { + lpobject->data.bus_mute =1; + fValue=1.0f; + } + else + { + lpobject->data.bus_mute =0; + fValue=0.0f; + } + lpobject->param.lpCallback(lpobject->param.lpuser, lpobject->Ident, nuCtl, fValue); + dc=GetDC(hw); + DrawBUS_NickNameMute(lpobject, dc); + ReleaseDC(hw,dc); + break; + case VMSCTL_BUS_ID_NAME: + break; + case VMSCTL_BUS_ID_METER: + break; + case VMSCTL_BUS_ID_GAIN: + lpobject->start_value = lpobject->data.bus_gain; + if (lpobject->start_value > lpobject->param.vmax) lpobject->start_value = lpobject->param.vmax; + if (lpobject->start_value < lpobject->param.vmin) lpobject->start_value = lpobject->param.vmin; + lpobject->LastCapture = SetCapture(hw); + lpobject->mouse_x0=x0; + lpobject->last_x0=x0; + lpobject->mouseCapture=TRUE; + lpobject->ctlrunning=nuCtl; + break; + case VMSCTL_BUS_ID_MONITOR: + if (lpobject->data.bus_monitor == 0) + { + lpobject->data.bus_monitor =1; + fValue=1.0f; + } + else + { + lpobject->data.bus_monitor =0; + fValue=0.0f; + } + lpobject->param.lpCallback(lpobject->param.lpuser, lpobject->Ident, nuCtl, fValue); + dc=GetDC(hw); + DrawBUS_Monitor(lpobject, dc); + ReleaseDC(hw,dc); + break; + } + return 0; +} + +static long VMSCTL_Bus_ManageLButtonDbclick(LPT_VMSCTL_BUSCTX lpobject, HWND hw, long x0, long y0) +{ + HDC dc; + float fValue; + long nuCtl; + nuCtl=VMSCTL_Bus_WhereAmI(lpobject,x0, y0); + if (nuCtl == 0) return 0; + + switch(nuCtl) + { + //double click to reset slider to 0.0 dB + case VMSCTL_BUS_ID_GAIN: + fValue=0.0f; + lpobject->data.bus_gain=fValue; + lpobject->param.lpCallback(lpobject->param.lpuser, lpobject->Ident, nuCtl, fValue); + + dc=GetDC(hw); + DrawBUS_Slider(lpobject, dc); + ReleaseDC(hw,dc); + break; + //otherwise we consider it as a simple click + default: + VMSCTL_Bus_ManageLButtonDown(lpobject, hw, x0, y0); + break; + } + return 0; +} + + +static long VMSCTL_Bus_ManageMouseMove(LPT_VMSCTL_BUSCTX lpobject, HWND hw, long x0, long y0) +{ + HDC dc; + LPT_VMSCTL_BUSPARAM lpp; + long dx,ddx, nuCtl; + float fValue; + if (lpobject->mouseCapture == FALSE) return -1; + lpp = &(lpobject->param); + nuCtl=lpobject->ctlrunning; + switch(nuCtl) + { + case VMSCTL_BUS_ID_GAIN: + if (x0 != lpobject->last_x0) + { + dx=x0-lpobject->mouse_x0; + ddx=lpobject->dx_slider; + + fValue=lpobject->start_value + (((lpp->vmax - lpp->vmin) * dx) / ddx); + if (fValue < lpp->vmin) fValue=lpp->vmin; + if (fValue > lpp->vmax) fValue=lpp->vmax; + if (fValue != lpobject->data.bus_gain) + { + lpobject->data.bus_gain=fValue; + lpobject->param.lpCallback(lpobject->param.lpuser, lpobject->Ident, nuCtl, fValue); + + dc=GetDC(hw); + DrawBUS_Slider(lpobject, dc); + ReleaseDC(hw,dc); + } + lpobject->last_x0 = x0; + } + break; + } + return 0; +} + +static long VMSCTL_Bus_ManageLButtonUp(LPT_VMSCTL_BUSCTX lpobject, HWND hw, long x0, long y0) +{ + if (lpobject->mouseCapture == FALSE) return -1; + ReleaseCapture(); + if (lpobject->LastCapture != NULL) SetCapture(lpobject->LastCapture); + lpobject->mouseCapture=FALSE; + return 0; +} + + +static LRESULT CALLBACK VMSCTL_BusCallback(HWND hw, //handle of the window. + UINT msg, //Message Ident. + WPARAM p1, //parameter 1. + LPARAM p2) //parameter 2 +{ + HPEN oldpen; + HBRUSH oldbrush; + RECT rect; + LPCREATESTRUCT lpcs; + LPT_VMSCTL_BUSCTX lpobject; + HDC dc; + PAINTSTRUCT ps; + switch (msg) + { + //here we create our structure + case WM_CREATE: + lpcs=(LPCREATESTRUCT)p2; + lpobject=(LPT_VMSCTL_BUSCTX)lpcs->lpCreateParams; + lpobject->hw=hw; + TOOL_StorePointerInWindow(hw,lpobject); + break; + //on mouse click we get the focus. + case WM_MOUSEACTIVATE: + if (GetFocus()!=hw) SetFocus(hw); + return MA_ACTIVATE; + //on Focus change we redraw the control + case WM_SETFOCUS: + case WM_KILLFOCUS: + InvalidateRect(hw,NULL,FALSE); + return 0; + //here we draw all the control + case WM_PAINT: + dc=BeginPaint(hw,&ps); + lpobject=(LPT_VMSCTL_BUSCTX)TOOL_RecallPointerFromWindow(hw); + if (lpobject != NULL) DrawBUS(lpobject, dc); + EndPaint(hw,&ps); + return 0; + case WM_ERASEBKGND: + lpobject=(LPT_VMSCTL_BUSCTX)TOOL_RecallPointerFromWindow(hw); + if (lpobject == NULL) return 0; + dc=(HDC)p1; + GetClientRect(hw,&rect); + oldbrush = (HBRUSH)SelectObject(dc,lpobject->param.bkg0_brush); + oldpen = (HPEN)SelectObject(dc,GetStockObject(NULL_PEN)); + Rectangle(dc,rect.left-1,rect.top-1,rect.right+1,rect.bottom+1); + oldbrush = (HBRUSH)SelectObject(dc,lpobject->param.bkg1_brush); + RoundRect(dc,rect.left,rect.top,rect.right,rect.bottom, 7,7); + SelectObject(dc,oldpen); + SelectObject(dc,oldbrush); + return 0; + //mouse behavior + case WM_LBUTTONDOWN: + lpobject=(LPT_VMSCTL_BUSCTX)TOOL_RecallPointerFromWindow(hw); + if (lpobject == NULL) break; + VMSCTL_Bus_ManageLButtonDown(lpobject, hw, (short int)LOWORD(p2), (short int)HIWORD(p2)); + break; + case WM_LBUTTONDBLCLK: + lpobject=(LPT_VMSCTL_BUSCTX)TOOL_RecallPointerFromWindow(hw); + if (lpobject == NULL) break; + VMSCTL_Bus_ManageLButtonDbclick(lpobject, hw, (short int)LOWORD(p2), (short int)HIWORD(p2)); + break; + case WM_MOUSEMOVE: + lpobject=(LPT_VMSCTL_BUSCTX)TOOL_RecallPointerFromWindow(hw); + if (lpobject == NULL) break; + VMSCTL_Bus_ManageMouseMove(lpobject, hw, (short int)LOWORD(p2), (short int)HIWORD(p2)); + break; + case WM_LBUTTONUP: + lpobject=(LPT_VMSCTL_BUSCTX)TOOL_RecallPointerFromWindow(hw); + if (lpobject == NULL) break; + VMSCTL_Bus_ManageLButtonUp(lpobject, hw, (short int)LOWORD(p2), (short int)HIWORD(p2)); + break; + + //ending + case WM_CLOSE: + DestroyWindow(hw); + return 0; + case WM_DESTROY: + lpobject=TOOL_RecallPointerFromWindow(hw); + if (lpobject != NULL) + { + if (lpobject->tempbmp !=NULL) DeleteObject(lpobject->tempbmp); + free(lpobject); + TOOL_StorePointerInWindow(hw,NULL); + } + break; + + } + return DefWindowProc(hw,msg,p1,p2); +} + + +HWND VMSCTL_CreateBUS(HWND hParent, long Ident, long x0,long y0, LPT_VMSCTL_BUSPARAM lpparam) +{ + HWND hw; + char szName[64]; + long wstyle,vi; + LPT_VMSCTL_BUSCTX lpobject; + //we allocate memory for our structure + lpobject=(LPT_VMSCTL_BUSCTX)malloc(sizeof(T_VMSCTL_BUSCTX)); + if (lpobject == NULL) return NULL; + memset(lpobject,0, sizeof(T_VMSCTL_BUSCTX)); + if (lpparam == NULL) return NULL; + lpobject->param = *lpparam; + //define control size according bitmap. + lpobject->dx=100; + lpobject->dy=100; + //init rtdata; + for (vi=0;vi<8;vi++) + { + lpobject->rtdata.dbLevel[vi]=-100.0f; + } + //set control ident + lpobject->Ident=Ident; + + //we create window with window-creation data + wstyle=WS_CHILD | WS_TABSTOP; // | WS_VISIBLE + sprintf(szName,"Bus #%i", Ident); + hw=CreateWindow(VMSCTL_CLASSNAME_BUS, szName, + wstyle,x0,y0, + lpobject->dx, // window width + lpobject->dy, // window height + hParent, // parent Windows Handle. + (HMENU)Ident, // child-window identifier. + G_hinstance, // handle of application instance + lpobject); // we communicate our pointer (see WM_CREATE) + + return hw; +} + + +long VMSCTL_PositionBUS(HWND hw, long x0,long y0, long dx, long dy, long fShow) +{ + LPT_VMSCTL_BUSCTX lpobject; + BOOL fUpdate=FALSE; + lpobject=(LPT_VMSCTL_BUSCTX)TOOL_RecallPointerFromWindow(hw); + if (lpobject == NULL) return -1; + if (fShow == 0) + { + lpobject->x0 = x0; + lpobject->y0 = y0; + lpobject->dx = dx; + lpobject->dy = dy; + if (lpobject->isShown != 0) + { + ShowWindow(hw, SW_HIDE); + } + lpobject->isShown = fShow; + } + else + { + if (lpobject->x0 != x0) fUpdate=TRUE; + if (lpobject->y0 != y0) fUpdate=TRUE; + if (lpobject->dx != dx) fUpdate=TRUE; + if (lpobject->dy != dy) fUpdate=TRUE; + if (lpobject->isShown == 0) fUpdate=TRUE; + + if (fUpdate == TRUE) + { + if (lpobject->tempbmp !=NULL) DeleteObject(lpobject->tempbmp); + lpobject->tempbmp=NULL; + + lpobject->x0 = x0; + lpobject->y0 = y0; + lpobject->dx = dx; + lpobject->dy = dy; + + ComputeBusDisplayData(lpobject); + SetWindowPos(hw,HWND_TOP,lpobject->x0,lpobject->y0,lpobject->dx,lpobject->dy,SWP_SHOWWINDOW); + lpobject->isShown = fShow; + } + } + //if (fUpdate == TRUE) InvalidateRect(hw, NULL, TRUE); + return 0; +} + +long VMSCTL_SetDataBUS(HWND hw, LPT_VMSCTL_BUS_DATA pData, long fUpdateAll) +{ + BOOL fUpdateMuteDisplay; + HDC dc=NULL; + LPT_VMSCTL_BUS_DATA pCurrent; + LPT_VMSCTL_BUSCTX lpobject; + lpobject=(LPT_VMSCTL_BUSCTX)TOOL_RecallPointerFromWindow(hw); + if (lpobject == NULL) return -1; + if (pData == NULL) return -2; + pCurrent = &(lpobject->data); + + if (pCurrent->bus_fMonitorSupport != pData->bus_fMonitorSupport) + { + *pCurrent = *pData; + InvalidateRect(hw,NULL,TRUE); + return 0; + } + if (lpobject->isShown != 0) + { + dc=GetDC(hw); + } + + fUpdateMuteDisplay=FALSE; + if ((fUpdateAll != 0) || (pCurrent->bus_nickname[0] == 0)) + { + strcpy(pCurrent->bus_nickname, pData->bus_nickname); + fUpdateMuteDisplay = TRUE; + } + if ((wcscmp(pCurrent->bus_namew, pData->bus_namew) != 0) || (fUpdateAll != 0)) + { + wcscpy(pCurrent->bus_namew, pData->bus_namew); + DrawBUS_Name(lpobject, dc); + } + if ((pCurrent->bus_gain != pData->bus_gain) || (fUpdateAll != 0)) + { + if ((lpobject->mouseCapture == FALSE) || (fUpdateAll != 0)) + { + pCurrent->bus_gain = pData->bus_gain; + DrawBUS_Slider(lpobject, dc); + } + } + if ((pCurrent->bus_mute != pData->bus_mute) || (fUpdateMuteDisplay == TRUE) || (fUpdateAll != 0)) + { + pCurrent->bus_mute = pData->bus_mute; + DrawBUS_NickNameMute(lpobject, dc); + } + if ((pCurrent->bus_monitor != pData->bus_monitor) || (fUpdateAll != 0)) + { + pCurrent->bus_monitor = pData->bus_monitor; + DrawBUS_Monitor(lpobject, dc); + } + + if (dc != NULL) ReleaseDC(hw,dc); + + return 0; +} + +long VMSCTL_ResetDataBUS(HWND hw) +{ + long vi; + LPT_VMSCTL_BUSCTX lpobject; + lpobject=(LPT_VMSCTL_BUSCTX)TOOL_RecallPointerFromWindow(hw); + if (lpobject == NULL) return -1; + memset(&(lpobject->data), 0, sizeof(T_VMSCTL_BUSPARAM)); + for (vi=0;vi<8;vi++) lpobject->rtdata.dbLevel[vi]=-100.0f; + return 0; +} + +long VMSCTL_SetRTDataBUS(HWND hw, LPT_VMSCTL_RT_DATA pRTData) +{ + float fMax; + HDC dc; + long nu; + LPT_VMSCTL_BUSCTX lpobject; + lpobject=(LPT_VMSCTL_BUSCTX)TOOL_RecallPointerFromWindow(hw); + if (lpobject == NULL) return -1; + if (pRTData == NULL) return -2; + + fMax = -100.0f; + lpobject->nMaxLevelToDisplay--; + if (lpobject->nMaxLevelToDisplay < 1) lpobject->fMaxLevelToDisplay=fMax; + //compute value to display, with a release factor + for (nu=0;nu<2;nu++) //display 2 channels only + { + if (pRTData->dbLevel[nu] > fMax) fMax=pRTData->dbLevel[nu]; + if (pRTData->dbLevel[nu] > lpobject->rtdata.dbLevel[nu]) lpobject->rtdata.dbLevel[nu]=pRTData->dbLevel[nu]; + else + { + lpobject->rtdata.dbLevel[nu] = lpobject->rtdata.dbLevel[nu] - PEAKMETER_RELEASE_DECREMENT; + if (lpobject->rtdata.dbLevel[nu] < -100.0f) lpobject->rtdata.dbLevel[nu]=-100.0f; + } + } + // Compute max level to display + if (fMax > lpobject->fMaxLevelToDisplay) + { + lpobject->fMaxLevelToDisplay = fMax; + lpobject->nMaxLevelToDisplay = 200; + } + //display peak meter. + if (lpobject->isShown != 0) + { + dc=GetDC(hw); + DrawBUS_PeakMeters(lpobject, dc); + ReleaseDC(hw,dc); + } + + return 0; +} + + + + + + + + + + + + + + + +/*---------------------------------------------------------------*/ +/* INIT / END */ +/*---------------------------------------------------------------*/ +long VMSCTL_InitLib(HINSTANCE hinst) +{ + long rep; + WNDCLASS wc; + + G_hinstance=hinst; + + //register class for our custom Strip + wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; //allows double click + wc.lpfnWndProc =(WNDPROC)VMSCTL_StripCallback; //Adresse of the related callback + wc.cbClsExtra =0; //0 per default. + wc.cbWndExtra =sizeof(void*); //alloc some byte to store pointer inside window. + wc.hInstance =hinst; //application hinstance. + wc.hIcon =NULL; //no Icon + wc.hCursor =LoadCursor(NULL,IDC_ARROW); //handle on cursor mouse. + wc.hbrBackground=NULL; //no background + wc.lpszMenuName =NULL; //no menu. + wc.lpszClassName=VMSCTL_CLASSNAME_STRIP; + rep=RegisterClass(&wc); + if (rep==0) return -1; + + //register class for our custom BUS + wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; //allows double click + wc.lpfnWndProc =(WNDPROC)VMSCTL_BusCallback; //Adresse of the related callback + wc.cbClsExtra =0; //0 per default. + wc.cbWndExtra =sizeof(void*); //alloc some byte to store pointer inside window. + wc.hInstance =hinst; //application hinstance. + wc.hIcon =NULL; //no Icon + wc.hCursor =LoadCursor(NULL,IDC_ARROW); //handle on cursor mouse. + wc.hbrBackground=NULL; //no background + wc.lpszMenuName =NULL; //no menu. + wc.lpszClassName=VMSCTL_CLASSNAME_BUS; + rep=RegisterClass(&wc); + if (rep==0) return -1; + + return 0; +} + +void VMSCTL_EndLib(void) +{ + UnregisterClass(VMSCTL_CLASSNAME_STRIP,G_hinstance); + UnregisterClass(VMSCTL_CLASSNAME_BUS,G_hinstance); +} + diff --git a/vmr_streamer/source/streamer_ctrl.h b/vmr_streamer/source/streamer_ctrl.h new file mode 100644 index 0000000..6fcf2f7 --- /dev/null +++ b/vmr_streamer/source/streamer_ctrl.h @@ -0,0 +1,199 @@ +/**********************************************************************************/ +/* VMSCTL V.Burel */ +/**********************************************************************************/ +/* Contains our custom windows control for vmr_streamer project */ +/*--------------------------------------------------------------------------------*/ +/* */ +/* COMPILATION DIRECTIVES: */ +/* */ +/* To compile With Microsoft VC2005 or higher, you need to create an */ +/* empty Win32 project with the following options: */ +/* - Configuration Properties / General : Char Set = NOT SET */ +/* - Configuration Properties / C/C++ / Preprocessor : _CRT_SECURE_NO_DEPRECATE */ +/* */ +/* This source code can be compiled for 32bit or 64 bits targets as well */ +/* WARNING: FOR 64x COMPILATION, ADD PREPROCESSOR DEFINE: VB_X64 */ +/* */ +/*--------------------------------------------------------------------------------*/ +/* */ +/* LICENSING: VoicemeeterRemote.dll usage is driven by a license agreement */ +/* given in VoicemeeterRemoteAPI.pdf or readme.txt */ +/* This Source Code can be used only in a program using Voicemeeter */ +/* Remote API anyway */ +/* */ +/*--------------------------------------------------------------------------------*/ + + + +#ifndef __VMSCTL_H__ +#define __VMSCTL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +// if compiling for x64 target define this +//#define VB_X64 + + +#define VMSCTL_MAX_NBSTRIP 8 +#define VMSCTL_MAX_NBBUS 8 + + +#define VMSCTL_CLASSNAME_STRIP "VMStreamerCtrl_Strip" +#define VMSCTL_CLASSNAME_BUS "VMStreamerCtrl_BUS" + + +//Initialize library +long VMSCTL_InitLib(HINSTANCE hinst); +void VMSCTL_EndLib(void); + + +typedef struct tagVMSCTL_RT_DATA +{ + float dbLevel[8]; +} T_VMSCTL_RT_DATA, *PT_VMSCTL_RT_DATA, *LPT_VMSCTL_RT_DATA; + +/*---------------------------------------------------------------*/ +/* STRIP CTL */ +/*---------------------------------------------------------------*/ +typedef void (__stdcall *VMSCTL_LPT_SBCALLBACK)(void * lpuser,long Ident, long ICtl, float value); + + +#define VMSCTL_STRIP_ID_MUTE 100 +#define VMSCTL_STRIP_ID_NAME 101 +#define VMSCTL_STRIP_ID_METER 102 +#define VMSCTL_STRIP_ID_GAIN 132 +#define VMSCTL_STRIP_ID_ASSIGN 148 + +typedef struct tagVMSCTL_STRIPPARAM +{ + HFONT font0; + HFONT font1; + HFONT font2; + float vmin,vmax; + HBRUSH bkg0_brush; + HBRUSH bkg1_brush; + + HPEN assignbus_pen; + COLORREF assignbus_color; + COLORREF name_color; + + HPEN slider_pen_green; + HPEN slider_pen_red; + HBRUSH slider_brush_green; + HBRUSH slider_brush_red; + + HBRUSH meter_brush1; + HBRUSH meter_brush2; + HBRUSH meter_brush3; + + COLORREF mutered_color; + HPEN mutered_pen; + COLORREF assigned_color; + HPEN assigned_pen; + + VMSCTL_LPT_SBCALLBACK lpCallback; + void * lpuser; +} T_VMSCTL_STRIPPARAM, *PT_VMSCTL_STRIPPARAM, *LPT_VMSCTL_STRIPPARAM; + +HWND VMSCTL_CreateSTRIP(HWND hParent, long Ident, long x0,long y0, LPT_VMSCTL_STRIPPARAM lpparam); + +long VMSCTL_PositionSTRIP(HWND hw, long x0,long y0, long dx, long dy, long fShow); + + +typedef struct tagVMSCTL_STRIP_DATA +{ + WCHAR strip_namew[64]; + char strip_nickname[8]; + float strip_gain[VMSCTL_MAX_NBBUS]; + long strip_mute; + char strip_assignmentbit[VMSCTL_MAX_NBBUS]; //0x10 bus activated / 0x01 bus assigned + long strip_nbBusDisplayed; + long strip_fMultiLayer; + char ** strip_pBUSNameList; +} T_VMSCTL_STRIP_DATA, *PT_VMSCTL_STRIP_DATA, *LPT_VMSCTL_STRIP_DATA; + +long VMSCTL_SetDataSTRIP(HWND hw, LPT_VMSCTL_STRIP_DATA pData, long fUpdateAll); +long VMSCTL_ResetDataSTRIP(HWND hw); + +long VMSCTL_SetRTDataSTRIP(HWND hw, LPT_VMSCTL_RT_DATA pRTData); + +long VMSCTL_GetIndexSTRIP(HWND hw,long nuVisibleSlider); + + + + +/*---------------------------------------------------------------*/ +/* BUS CTL */ +/*---------------------------------------------------------------*/ + +#define VMSCTL_BUS_ID_MUTE 200 +#define VMSCTL_BUS_ID_NAME 201 +#define VMSCTL_BUS_ID_METER 202 +#define VMSCTL_BUS_ID_GAIN 203 +#define VMSCTL_BUS_ID_MONITOR 204 + +typedef struct tagVMSCTL_BUSPARAM +{ + HFONT font0; + HFONT font1; + HFONT font2; + float vmin,vmax; + + HBRUSH bkg0_brush; + HBRUSH bkg1_brush; + HPEN assignbus_pen; + COLORREF assignbus_color; + COLORREF name_color; + + HPEN slider_pen_green; + HPEN slider_pen_red; + HBRUSH slider_brush_green; + HBRUSH slider_brush_red; + + HBRUSH meter_brush1; + HBRUSH meter_brush2; + HBRUSH meter_brush3; + + COLORREF mutered_color; + HPEN mutered_pen; + + HBRUSH monitor_brush; + HPEN monitor_pen; + + VMSCTL_LPT_SBCALLBACK lpCallback; + void * lpuser; +} T_VMSCTL_BUSPARAM, *PT_VMSCTL_BUSPARAM, *LPT_VMSCTL_BUSPARAM; + +HWND VMSCTL_CreateBUS(HWND hParent, long Ident, long x0,long y0, LPT_VMSCTL_BUSPARAM lpparam); + +long VMSCTL_PositionBUS(HWND hw, long x0,long y0, long dx, long dy, long fShow); + + +typedef struct tagVMSCTL_BUS_DATA +{ + WCHAR bus_namew[64]; + char bus_nickname[8]; + float bus_gain; + long bus_mute; + long bus_monitor; + long bus_fMonitorSupport; +} T_VMSCTL_BUS_DATA, *PT_VMSCTL_BUS_DATA, *LPT_VMSCTL_BUS_DATA; + +long VMSCTL_SetDataBUS(HWND hw, LPT_VMSCTL_BUS_DATA pData, long fUpdateAll); +long VMSCTL_ResetDataBUS(HWND hw); + +long VMSCTL_SetRTDataBUS(HWND hw, LPT_VMSCTL_RT_DATA pRTData); + + +//End Of Header. + +#ifdef __cplusplus +} +#endif + + +#endif /*__VMSCTL_H__*/ + + diff --git a/vmr_streamer/source/vban_cmd.c b/vmr_streamer/source/vban_cmd.c new file mode 100644 index 0000000..96adc6e --- /dev/null +++ b/vmr_streamer/source/vban_cmd.c @@ -0,0 +1,600 @@ +/**********************************************************************************/ +/* VBAN COMMAND V.Burel(c)2015-2021 */ +/**********************************************************************************/ +/* */ +/* THIS PROGRAM PROVIDES A MINIMAL VBAN-SERVICE */ +/* PROVIDES A FUNCTION TO SEND VBAN-TEXT REQUEST */ +/* PROVIDES A METHOD TO MANAGE VBAN RT-PACKET */ +/* */ +/* This program example shows */ +/* - How to use Windows Socket */ +/* - How to send and recieve VBAN request */ +/* */ +/*--------------------------------------------------------------------------------*/ +/* */ +/* COMPILATION DIRECTIVES: */ +/* */ +/* To compile With Microsoft VC2005 or higher, you need to create an */ +/* empty Win32 project with the following options: */ +/* - Configuration Properties / General : Char Set = NOT SET */ +/* - Configuration Properties / C/C++ / Preprocessor : _CRT_SECURE_NO_DEPRECATE */ +/* */ +/* LINKER: Ws2_32.lib */ +/* */ +/* This source code can be compiled for 32bit or 64 bits targets as well */ +/* */ +/*--------------------------------------------------------------------------------*/ +/* */ +/* LICENSING: VoicemeeterRemote.dll usage is driven by a license agreement */ +/* given in VoicemeeterRemoteAPI.pdf or readme.txt */ +/* THIS SOURCE CODE CAN BE USED ONLY IN A PROGRAM USING VOICEMEETER */ +/* REMOTE API */ +/* */ +/*--------------------------------------------------------------------------------*/ + + +#ifndef __cplusplus +#ifndef STRICT +#define STRICT +#endif +#endif + +#include +//#include +#include +//#include +#include + +#include "vban_cmd.h" +#include "VoicemeeterRemote.h" + + + +typedef struct tagVBANCMD_CONTEXT +{ + long mode; + BOOL ThreadStarted, finitlib; + HANDLE Thread_handle; + DWORD Thread_ident; + BOOL Thread_flagOK; + long WSAStartupReply; + WSADATA WSAData; + SOCKET vban_socket; + unsigned long IPv4Address; + unsigned short UDPport; + long fPortUsedByOtherApplication; + CRITICAL_SECTION ctc_section; + T_VBAN_VMRT_PACKET CurrentRTPPacket; + long CurrentRTPPacket_dirtyflag; + DWORD CurrentRTPPacket_counter; + T_VBAN_VMRT_PACKET PublicRTPPacket; + unsigned char last_voicemeeterType; + + T_VBAN_HEADER VBANHeader; + +} T_VBANCMD_CONTEXT, * PT_VBANCMD_CONTEXT, * LPT_VBANCMD_CONTEXT; + + +static T_VBANCMD_CONTEXT G_vban_ctx = { 0, 0, 0, NULL }; + + +long VBANCMD_GetIncomingRequestCounter(void) +{ + return G_vban_ctx.CurrentRTPPacket_counter; +} + +/******************************************************************************/ +/* SOCKET TOOL */ +/******************************************************************************/ + + +static long VBAN_CloseSocket(SOCKET* psocket) +{ + long rep; + if (*psocket != INVALID_SOCKET) + { + shutdown(*psocket, 2); + rep = closesocket(*psocket); + *psocket = INVALID_SOCKET; + } + return 0; +} + + +static long VBAN_SetSocketNonblocking(SOCKET socket) +{ + u_long flags; + flags = 1; + return ioctlsocket(socket, FIONBIO, &flags); +} + +static long VBAN_InitSocket(LPT_VBANCMD_CONTEXT lpctx, SOCKET* psocket, unsigned short nuPort, long SocketBufferSize) +{ + SOCKADDR_IN local_sin; + long rep, nnn; + long nsize, nbByte; + long nError; + + *psocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (*psocket == INVALID_SOCKET) return -1; + //set non blocking socket + rep = VBAN_SetSocketNonblocking(*psocket); + if (rep != 0) + { + closesocket(*psocket); + *psocket = INVALID_SOCKET; + return -2; + } + //disable debug mode + nsize = sizeof(rep); + nnn = getsockopt(*psocket, SOL_SOCKET, SO_DEBUG, (char*)&(rep), &nsize); + if (nnn == 0) + { + if (rep != 0) + { + rep = 0; + nsize = sizeof(rep); + setsockopt(*psocket, SOL_SOCKET, SO_DEBUG, (char*)&rep, nsize); + } + } + //set Time Out = ZERO. + rep = 0; + nsize = sizeof(rep); + setsockopt(*psocket, SOL_SOCKET, SO_SNDTIMEO, (char*)&rep, nsize); + setsockopt(*psocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&rep, nsize); + + //set Socket buffer size + nsize = sizeof(SocketBufferSize); + setsockopt(*psocket, SOL_SOCKET, SO_RCVBUF, (char*)&SocketBufferSize, nsize); + + //128 kB buffer is senough to send VBAN-TEXT request + nbByte = 1024 * 128; + nsize = sizeof(nbByte); + setsockopt(*psocket, SOL_SOCKET, SO_SNDBUF, (char*)&nbByte, nsize); + + //define socket port and ipaddress to + memset(&local_sin, 0, sizeof(SOCKADDR_IN)); + local_sin.sin_family = AF_INET; + local_sin.sin_port = htons((unsigned short)nuPort); + local_sin.sin_addr.s_addr = htonl(INADDR_ANY); + + lpctx->fPortUsedByOtherApplication = 0; + if (bind(*psocket, (struct sockaddr*)&(local_sin), sizeof(local_sin)) == SOCKET_ERROR) + { + nError = WSAGetLastError(); + if (nError == WSAEADDRINUSE) + { + lpctx->fPortUsedByOtherApplication = 1; + } + closesocket(*psocket); + *psocket = INVALID_SOCKET; + return -5; + } + return 0; +} + + +/******************************************************************************/ +/* FUNCTIONS REQUEST */ +/******************************************************************************/ + +long VBANCMD_SendRequest_String(char* pString) +{ + SOCKADDR_IN dest; + LPT_VBAN_HEADER lpHeader; + char Buffer[2048]; + long rep, nbByte; + LPT_VBANCMD_CONTEXT lpctx; + lpctx = &G_vban_ctx; + if (lpctx->ThreadStarted == 0) return -9; + if (pString == NULL) return -10; + + lpHeader = (LPT_VBAN_HEADER)Buffer; + // build VBAN Header from our current VBAN Header + *lpHeader = lpctx->VBANHeader; + lpctx->VBANHeader.nuFrame++; + strcpy((char*)(lpHeader + 1), pString); + //send request + memset(&dest, 0, sizeof(SOCKADDR_IN)); + dest.sin_family = AF_INET; + dest.sin_port = htons(lpctx->UDPport); + dest.sin_addr.s_addr = lpctx->IPv4Address; + + nbByte = sizeof(T_VBAN_HEADER) + (long)strlen(pString); + rep = sendto(lpctx->vban_socket, Buffer, nbByte, 0, (struct sockaddr*)&dest, sizeof(dest)); + if (rep == SOCKET_ERROR) return -20; + return 0; +} + +long VBANCMD_SendRequest_Float(char* szParam, float value) +{ + char String[512]; + LPT_VBANCMD_CONTEXT lpctx; + lpctx = &G_vban_ctx; + + if (szParam == NULL) return -1; + if (szParam[0] == 0) return -2; + + sprintf(String, "%s = %f;", szParam, value); + return VBANCMD_SendRequest_String(String); +} + + + +long VBANCMD_SendRequest_RegisterRTPacket(unsigned char sTimeOut, char* szVBANStreamName) +{ + SOCKADDR_IN dest; + T_VBAN_HEADER Header; + long rep, nbByte; + LPT_VBANCMD_CONTEXT lpctx; + lpctx = &G_vban_ctx; + if (lpctx->ThreadStarted == 0) return -9; + + Header.vban = 'NABV'; + Header.format_SR = 0x60; + Header.format_nbs = 0; + Header.format_nbc = VBAN_SERVICE_RTPACKETREGISTER; + Header.format_bit = sTimeOut & 0x000000FF; + if (szVBANStreamName != NULL) strcpy(Header.streamname, "Register RTP"); + else strncpy(Header.streamname, szVBANStreamName, 16); + Header.nuFrame = 0; + + + //send request + memset(&dest, 0, sizeof(SOCKADDR_IN)); + dest.sin_family = AF_INET; + dest.sin_port = htons(lpctx->UDPport); + dest.sin_addr.s_addr = lpctx->IPv4Address; + + nbByte = sizeof(T_VBAN_HEADER); + rep = sendto(lpctx->vban_socket, (char*)&Header, nbByte, 0, (struct sockaddr*)&dest, sizeof(dest)); + if (rep == SOCKET_ERROR) return -20; + return 0; +} + + + + + + +/******************************************************************************/ +/* CURRENT PARAMETERS FUNCTIONS */ +/******************************************************************************/ + +long VBANCMD_IsParameterDirty(void) +{ + unsigned char vmType; + long reply; + LPT_VBANCMD_CONTEXT lpctx; + lpctx = &G_vban_ctx; + reply = lpctx->CurrentRTPPacket_dirtyflag; + if (reply != 0) + { + // if dirty we copy our buffer in public structure + EnterCriticalSection(&(lpctx->ctc_section)); + lpctx->PublicRTPPacket = lpctx->CurrentRTPPacket; + LeaveCriticalSection(&(lpctx->ctc_section)); + } + // to fit the same behavior than the remote API function + vmType = lpctx->PublicRTPPacket.voicemeeterType; + if (vmType == 0) reply = -1; + if (lpctx->last_voicemeeterType != vmType) reply = -2; + lpctx->last_voicemeeterType = vmType; + return reply; +} + +// then all information will come directly from our public RTPacket structure + +long VBANCMD_GetVoicemeeterType(unsigned long* pType) +{ + LPT_VBANCMD_CONTEXT lpctx; + lpctx = &G_vban_ctx; + *pType = (unsigned long)(lpctx->PublicRTPPacket.voicemeeterType); + return 0; +} + +long VBANCMD_GetVoicemeeterVersion(unsigned long* pVersion) +{ + LPT_VBANCMD_CONTEXT lpctx; + lpctx = &G_vban_ctx; + *pVersion = lpctx->PublicRTPPacket.voicemeeterVersion; + return 0; +} + + +void TOOL_ConvertUTF8ToWCHAR(char* UTF8_String, WCHAR* wString, long nbCharMax) +{ + if (UTF8_String[0] == 0) + { + wString[0] = 0; + return; + } + memset(wString, 0, nbCharMax * sizeof(WCHAR)); + MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)UTF8_String, (int)strlen(UTF8_String), wString, nbCharMax); + wString[nbCharMax - 1] = 0; +} + + +long VBANCMD_GetBusLabel(long index, WCHAR* pwsz) +{ + LPT_VBANCMD_CONTEXT lpctx; + lpctx = &G_vban_ctx; + TOOL_ConvertUTF8ToWCHAR(lpctx->PublicRTPPacket.busLabelUTF8c60[index], pwsz, 64); + return 0; +} + +long VBANCMD_GetBusGain(long index, float* pValue) +{ + LPT_VBANCMD_CONTEXT lpctx; + lpctx = &G_vban_ctx; + *pValue = ((float)lpctx->PublicRTPPacket.busGaindB100[index]) * 0.01f; + return 0; +} + +long VBANCMD_GetBusSel(long index, float* pValue) +{ + LPT_VBANCMD_CONTEXT lpctx; + lpctx = &G_vban_ctx; + if ((lpctx->PublicRTPPacket.busState[index] & VMRTSTATE_MODE_SEL) != 0) *pValue = 1.0f; + else *pValue = 0.0f; + return 0; +} + +long VBANCMD_GetBusMute(long index, float* pValue) +{ + LPT_VBANCMD_CONTEXT lpctx; + lpctx = &G_vban_ctx; + if ((lpctx->PublicRTPPacket.busState[index] & VMRTSTATE_MODE_MUTE) != 0) *pValue = 1.0f; + else *pValue = 0.0f; + return 0; +} + +long VBANCMD_GetBusMonitor(long index, float* pValue) +{ + LPT_VBANCMD_CONTEXT lpctx; + lpctx = &G_vban_ctx; + if ((lpctx->PublicRTPPacket.busState[index] & VMRTSTATE_MODE_MONITOR) != 0) *pValue = 1.0f; + else *pValue = 0.0f; + return 0; +} + + + +long VBANCMD_GetStripLabel(long index, WCHAR* pwsz) +{ + LPT_VBANCMD_CONTEXT lpctx; + lpctx = &G_vban_ctx; + TOOL_ConvertUTF8ToWCHAR(lpctx->PublicRTPPacket.stripLabelUTF8c60[index], pwsz, 64); + return 0; +} + +long VBANCMD_GetStripGain(long index, float* pValue) +{ + LPT_VBANCMD_CONTEXT lpctx; + lpctx = &G_vban_ctx; + *pValue = ((float)lpctx->PublicRTPPacket.stripGaindB100Layer1[index]) * 0.01f; + return 0; +} + +long VBANCMD_GetStripGainLayer(long index, long layer, float* pValue) +{ + short* pGain; + LPT_VBANCMD_CONTEXT lpctx; + lpctx = &G_vban_ctx; + + pGain = lpctx->PublicRTPPacket.stripGaindB100Layer1; + pGain = pGain + (layer * 8); + *pValue = ((float)pGain[index]) * 0.01f; + return 0; +} + +long VBANCMD_GetStripMute(long index, float* pValue) +{ + LPT_VBANCMD_CONTEXT lpctx; + lpctx = &G_vban_ctx; + if ((lpctx->PublicRTPPacket.stripState[index] & VMRTSTATE_MODE_MUTE) != 0) *pValue = 1.0f; + else *pValue = 0.0f; + return 0; +} + + +static long G_MaskBusAssign_v1[8] = { VMRTSTATE_MODE_BUSA1, VMRTSTATE_MODE_BUSB1, 0, 0, 0, 0, 0, 0 }; +static long G_MaskBusAssign_v2[8] = { VMRTSTATE_MODE_BUSA1, VMRTSTATE_MODE_BUSA2, VMRTSTATE_MODE_BUSA3, VMRTSTATE_MODE_BUSB1, VMRTSTATE_MODE_BUSB2, 0, 0, 0 }; +static long G_MaskBusAssign_v3[8] = { VMRTSTATE_MODE_BUSA1, VMRTSTATE_MODE_BUSA2, VMRTSTATE_MODE_BUSA3, VMRTSTATE_MODE_BUSA4, VMRTSTATE_MODE_BUSA5, VMRTSTATE_MODE_BUSB1, VMRTSTATE_MODE_BUSB2, VMRTSTATE_MODE_BUSB3 }; + +long VBANCMD_GetStripAssignation(long index, long nBus, float* pValue) +{ + long* pMask; + LPT_VBANCMD_CONTEXT lpctx; + lpctx = &G_vban_ctx; + pMask = NULL; + if (lpctx->PublicRTPPacket.voicemeeterType == 1) pMask = G_MaskBusAssign_v1; + if (lpctx->PublicRTPPacket.voicemeeterType == 2) pMask = G_MaskBusAssign_v2; + if (lpctx->PublicRTPPacket.voicemeeterType == 3) pMask = G_MaskBusAssign_v3; + + if ((lpctx->PublicRTPPacket.stripState[index] & pMask[nBus]) != 0) *pValue = 1.0f; + else *pValue = 0.0f; + return 0; +} + + +long VBANCMD_GetLevel(long index, long nuChannel, float* pLevelDB) +{ + LPT_VBANCMD_CONTEXT lpctx; + lpctx = &G_vban_ctx; + switch (index) + { + case 0: + *pLevelDB = ((float)lpctx->PublicRTPPacket.inputLeveldB100[nuChannel]) * 0.01f; + return 0; + case 3: + *pLevelDB = ((float)lpctx->PublicRTPPacket.outputLeveldB100[nuChannel]) * 0.01f; + return 0; + default: + *pLevelDB = -100.0f; + break; + } + return -1; +} + + +/******************************************************************************/ +/* START / STOP VBAN CLIENT */ +/******************************************************************************/ + + +static DWORD WINAPI VBANCMD_Thread(LPT_VBANCMD_CONTEXT lpctx) +{ + SOCKADDR_IN from; + LPT_VBAN_HEADER lpHeader; + long rep, datasize, nbByte, mstemp, fromlen; + char Buffer[2048]; + unsigned char protocol; + DWORD current_ipv4; + HANDLE h_t; + h_t = GetCurrentThread(); + SetThreadPriority(h_t, THREAD_PRIORITY_HIGHEST); + CloseHandle(h_t); + lpHeader = (LPT_VBAN_HEADER)Buffer; + current_ipv4 = lpctx->IPv4Address; + while (lpctx->Thread_flagOK == TRUE) + { + mstemp = 1; + fromlen = sizeof(SOCKADDR_IN); + rep = recvfrom(lpctx->vban_socket, Buffer, 2048, 0, (struct sockaddr*)&from, &fromlen); + if (rep != SOCKET_ERROR) + { + mstemp = 0; + // if we recieve something + datasize = rep; + if ((datasize > sizeof(T_VBAN_HEADER)) && (from.sin_addr.S_un.S_addr == current_ipv4)) + { + // if it's a VBAN packet + if (lpHeader->vban == 'NABV') + { + protocol = lpHeader->format_SR & VBAN_PROTOCOL_MASK; + // if it's a VBAN-SERVICE packet + if (protocol == VBAN_PROTOCOL_SERVICE) + { + if (lpHeader->format_nbc == VBAN_SERVICE_RTPACKET) + { + // if it's a RTPacket + nbByte = datasize - sizeof(T_VBAN_HEADER); + if (nbByte >= sizeof(T_VBAN_VMRT_PACKET)) + { + // just copy it into our context structure and set dirty flag + EnterCriticalSection(&(lpctx->ctc_section)); + memcpy(&(lpctx->CurrentRTPPacket), lpHeader + 1, sizeof(T_VBAN_VMRT_PACKET)); + lpctx->CurrentRTPPacket_dirtyflag = 1; + lpctx->CurrentRTPPacket_counter++; + LeaveCriticalSection(&(lpctx->ctc_section)); + } + } + } + } + } + } + // if we did nothing we wait for 1 ms, otherwise we wait for next O/S scheduler cycle + Sleep(mstemp); + } + return 0; +} + + +long VBANCMD_StopThread(void) +{ + LPT_VBANCMD_CONTEXT lpctx; + lpctx = &G_vban_ctx; + if (lpctx->finitlib == 0) return -1; + + lpctx->ThreadStarted = 0; + // Stop Thread + lpctx->Thread_flagOK = FALSE; + if (lpctx->Thread_handle != NULL) + { + WaitForSingleObject(lpctx->Thread_handle, INFINITE); + CloseHandle(lpctx->Thread_handle); + lpctx->Thread_handle = NULL; + } + // Close Soccket + VBAN_CloseSocket(&(lpctx->vban_socket)); + + memset(&(lpctx->CurrentRTPPacket), 0, sizeof(T_VBAN_VMRT_PACKET)); + memset(&(lpctx->PublicRTPPacket), 0, sizeof(T_VBAN_VMRT_PACKET)); + lpctx->CurrentRTPPacket_dirtyflag = 1; + return 0; +} + + +long VBANCMD_StartThread(char* szVBANStreamName, char* szIPAddressTo, unsigned short UDPport) +{ + long rep, reply = 0; + LPT_VBANCMD_CONTEXT lpctx; + lpctx = &G_vban_ctx; + if (lpctx->finitlib == 0) return -1; + VBANCMD_StopThread(); + + // build our header to send VBAN-TEXT request + lpctx->VBANHeader.vban = 'NABV'; + lpctx->VBANHeader.format_SR = 0x52; + lpctx->VBANHeader.format_nbs = 0; + lpctx->VBANHeader.format_nbc = 0; + lpctx->VBANHeader.format_bit = 0x10; + if (szVBANStreamName == NULL) strcpy(lpctx->VBANHeader.streamname, "Command1"); + else strncpy(lpctx->VBANHeader.streamname, szVBANStreamName, 16); + lpctx->VBANHeader.nuFrame = 0; + + // Init Socket with 2 MB on RCV buffer + lpctx->IPv4Address = inet_addr(szIPAddressTo); + lpctx->UDPport = UDPport; + rep = VBAN_InitSocket(lpctx, &(lpctx->vban_socket), UDPport, 1024 * 1024 * 2); + if (rep != 0) return -2; + + // Start Thread + lpctx->Thread_flagOK = TRUE; + lpctx->Thread_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)VBANCMD_Thread, (void*)lpctx, 0, &(lpctx->Thread_ident)); + if (lpctx->Thread_handle == NULL) + { + reply = -100; + } + // we set STARTED flag only if all is good. + lpctx->ThreadStarted = 1; + return reply; +} + + + + + + + +/******************************************************************************/ +/* INIT / END LIB */ +/******************************************************************************/ + +long VBANCMD_EndLib(void) +{ + LPT_VBANCMD_CONTEXT lpctx; + lpctx = &G_vban_ctx; + + if (lpctx->finitlib == 0) return 0; + VBANCMD_StopThread(); + + DeleteCriticalSection(&(lpctx->ctc_section)); + memset(lpctx, 0, sizeof(T_VBANCMD_CONTEXT)); + return 0; +} + +long VBANCMD_InitLib(long mode) +{ + LPT_VBANCMD_CONTEXT lpctx; + lpctx = &G_vban_ctx; + memset(lpctx, 0, sizeof(T_VBANCMD_CONTEXT)); + lpctx->mode = mode; + lpctx->finitlib = 1; + lpctx->WSAStartupReply = WSAStartup(MAKEWORD(1, 1), &(lpctx->WSAData)); + InitializeCriticalSection(&(lpctx->ctc_section)); + lpctx->vban_socket = INVALID_SOCKET; + return 0; +} + diff --git a/vmr_streamer/source/vban_cmd.h b/vmr_streamer/source/vban_cmd.h new file mode 100644 index 0000000..e97818a --- /dev/null +++ b/vmr_streamer/source/vban_cmd.h @@ -0,0 +1,121 @@ +/**********************************************************************************/ +/* VBAN COMMAND V.Burel(c)2015-2021 */ +/**********************************************************************************/ +/* */ +/* THIS PROGRAM PROVIDES A MINIMAL VBAN-SERVICE */ +/* PROVIDES A FUNCTION TO SEND VBAN-TEXT REQUEST */ +/* PROVIDES A METHOD TO MANAGE VBAN RT-PACKET */ +/* */ +/* This program example shows */ +/* - How to use Windows Socket */ +/* - How to send and recieve VBAN request */ +/* */ +/*--------------------------------------------------------------------------------*/ +/* */ +/* COMPILATION DIRECTIVES: */ +/* */ +/* To compile With Microsoft VC2005 or higher, you need to create an */ +/* empty Win32 project with the following options: */ +/* - Configuration Properties / General : Char Set = NOT SET */ +/* - Configuration Properties / C/C++ / Preprocessor : _CRT_SECURE_NO_DEPRECATE */ +/* */ +/* LINKER: Ws2_32.lib */ +/* */ +/* This source code can be compiled for 32bit or 64 bits targets as well */ +/* */ +/*--------------------------------------------------------------------------------*/ +/* */ +/* LICENSING: VoicemeeterRemote.dll usage is driven by a license agreement */ +/* given in VoicemeeterRemoteAPI.pdf or readme.txt */ +/* THIS SOURCE CODE CAN BE USED ONLY IN A PROGRAM USING VOICEMEETER */ +/* REMOTE API */ +/* */ +/*--------------------------------------------------------------------------------*/ + +#ifndef __VBAN_CMD_H__ +#define __VBAN_CMD_H__ + + +#pragma pack(1) + +struct tagVBAN_HEADER +{ + unsigned long vban; // contains 'V' 'B', 'A', 'N' + unsigned char format_SR; // SR index (see SRList above) + unsigned char format_nbs; // nb sample per frame (1 to 256) + unsigned char format_nbc; // nb channel (1 to 256) + unsigned char format_bit; // mask = 0x07 (see DATATYPE table below) + char streamname[16]; // stream name + unsigned long nuFrame; // growing frame number +}; + +#pragma pack() + +typedef struct tagVBAN_HEADER T_VBAN_HEADER; +typedef struct tagVBAN_HEADER* PT_VBAN_HEADER; +typedef struct tagVBAN_HEADER* LPT_VBAN_HEADER; + + +#define VBAN_PROTOCOL_MASK 0xE0 +#define VBAN_PROTOCOL_SERVICE 0x60 + +#define VBAN_SERVICE_RTPACKETREGISTER 32 +#define VBAN_SERVICE_RTPACKET 33 + + +/******************************************************************************/ +/* FUNCTIONS */ +/******************************************************************************/ + +long VBANCMD_SendRequest_String(char* pString); +long VBANCMD_SendRequest_Float(char* szParam, float value); + +long VBANCMD_SendRequest_RegisterRTPacket(unsigned char sTimeOut, char* szVBANStreamName); + +// to check the VBAN connection works +long VBANCMD_GetIncomingRequestCounter(void); + + +/******************************************************************************/ +/* CURRENT PARAMETERS FUNCTIONS */ +/******************************************************************************/ +// we provide same function than Voicemeeter Remote API to simplify the process + +long VBANCMD_IsParameterDirty(void); + +long VBANCMD_GetVoicemeeterType(unsigned long* pType); +long VBANCMD_GetVoicemeeterVersion(unsigned long* pVersion); + +long VBANCMD_GetBusLabel(long index, WCHAR* pwsz); +long VBANCMD_GetBusGain(long index, float* pValue); +long VBANCMD_GetBusSel(long index, float* pValue); +long VBANCMD_GetBusMute(long index, float* pValue); +long VBANCMD_GetBusMonitor(long index, float* pValue); + + +long VBANCMD_GetStripLabel(long index, WCHAR* pwsz); +long VBANCMD_GetStripGain(long index, float* pValue); +long VBANCMD_GetStripGainLayer(long index, long layer, float* pValue); +long VBANCMD_GetStripMute(long index, float* pValue); +long VBANCMD_GetStripAssignation(long index, long nBus, float* pValue); + +long VBANCMD_GetLevel(long index, long nuChannel, float* pLevelDB); + + + +/******************************************************************************/ +/* START / STOP THREAD */ +/******************************************************************************/ + +long VBANCMD_StartThread(char* szVBANStreamName, char* szIPAddressTo, unsigned short UDPport); +long VBANCMD_StopThread(void); + +/******************************************************************************/ +/* INIT / END LIB */ +/******************************************************************************/ + +long VBANCMD_EndLib(void); +long VBANCMD_InitLib(long mode); + + +#endif /* __VBAN_CMD_H__*/ \ No newline at end of file diff --git a/vmr_streamer/source/vmr_streamer.c b/vmr_streamer/source/vmr_streamer.c new file mode 100644 index 0000000..1fd7dab --- /dev/null +++ b/vmr_streamer/source/vmr_streamer.c @@ -0,0 +1,2768 @@ +/*--------------------------------------------------------------------------------*/ +/* VMR example: Voicemeeter Custom GUI for Streamers */ +/*--------------------------------------------------------------------------------*/ +/* 'C' Sample Code to make a Voicemeeter Custom GUI V.Burel (c)2016-2021 */ +/* */ +/* THIS PROGRAM PROVIDES A GUI TO CONTROL VOICEMEETER */ +/* PROVIDES A SIMPLIFIED GUI WITH ONLY USED STRIP/BUS */ +/* PROVIDES A RESIZABLE GRAPHIC USER INTERFACE */ +/* */ +/* This program example shows */ +/* - How to link VoicemeeterRemote.dll */ +/* - How to Login / logout */ +/* - How to Manage regular parameters to make a custom controller. */ +/* - How to make a VBAN layer to also manage distant Voicemeeter. */ +/* */ +/*--------------------------------------------------------------------------------*/ +/* */ +/* COMPILATION DIRECTIVES: */ +/* */ +/* To compile With Microsoft VC2005 or higher, you need to create an */ +/* empty Win32 project with the following options: */ +/* - Configuration Properties / General : Char Set = NOT SET */ +/* - Configuration Properties / C/C++ / Preprocessor : _CRT_SECURE_NO_DEPRECATE */ +/* */ +/* This source code can be compiled for 32bit or 64 bits targets as well */ +/* WARNING: FOR 64x COMPILATION, ADD PREPROCESSOR DEFINE: VB_X64 */ +/* */ +/*--------------------------------------------------------------------------------*/ +/* */ +/* LICENSING: VoicemeeterRemote.dll usage is driven by a license agreement */ +/* given in VoicemeeterRemoteAPI.pdf or readme.txt */ +/* This Source Code can be used only in a program using Voicemeeter */ +/* Remote API. */ +/* */ +/*--------------------------------------------------------------------------------*/ + + +#ifndef __cplusplus + #ifndef STRICT + #define STRICT + #endif +#endif + +#include +#include +#include + +#include "VoicemeeterRemote.h" +#include "vmr_streamer.h" +#include "streamer_ctrl.h" +#include "vban_cmd.h" + +/*******************************************************************************/ +/** GET VOICEMEETER DIRECTORY **/ +/*******************************************************************************/ + +static char uninstDirKey[]="SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; + +#define INSTALLER_UNINST_KEY "VB:Voicemeeter {17359A74-1236-5467}" + + +void RemoveNameInPath(char * szPath) +{ + long ll; + ll=(long)strlen(szPath); + while ((ll>0) && (szPath[ll]!='\\')) ll--; + if (szPath[ll] == '\\') szPath[ll]=0; +} + +#ifndef KEY_WOW64_32KEY + #define KEY_WOW64_32KEY 0x0200 +#endif + +BOOL __cdecl RegistryGetVoicemeeterFolder(char * szDir) +{ + char szKey[256]; + char sss[1024]; + DWORD nnsize=1024; + HKEY hkResult; + LONG rep; + DWORD pptype=REG_SZ; + sss[0]=0; + + // build Voicemeeter uninstallation key + strcpy(szKey,uninstDirKey); + strcat(szKey,"\\"); + strcat(szKey,INSTALLER_UNINST_KEY); + + // open key + rep=RegOpenKeyEx(HKEY_LOCAL_MACHINE,szKey,0, KEY_READ, &hkResult); + if (rep != ERROR_SUCCESS) + { + // if not present we consider running in 64bit mode and force to read 32bit registry + rep=RegOpenKeyEx(HKEY_LOCAL_MACHINE,szKey,0, KEY_READ | KEY_WOW64_32KEY, &hkResult); + } + if (rep != ERROR_SUCCESS) return FALSE; + // read uninstall profram path + rep=RegQueryValueEx(hkResult,"UninstallString",0,&pptype,(unsigned char *)sss,&nnsize); + RegCloseKey(hkResult); + + if (pptype != REG_SZ) return FALSE; + if (rep != ERROR_SUCCESS) return FALSE; + // remove name to get the path only + RemoveNameInPath(sss); + if (nnsize>512) nnsize=512; + strncpy(szDir,sss,nnsize); + + return TRUE; +} + + + + + + +/*******************************************************************************/ +/** GET DLL INTERFACE **/ +/*******************************************************************************/ + +static HMODULE G_H_Module=NULL; +static T_VBVMR_INTERFACE iVMR; + +//if we directly link source code (for vb-audio development only) +#ifdef VBUSE_LOCALLIB + + long InitializeDLLInterfaces(void) + { + iVMR.VBVMR_Login =VBVMR_Login; + iVMR.VBVMR_Logout =VBVMR_Logout; + iVMR.VBVMR_RunVoicemeeter =VBVMR_RunVoicemeeter; + iVMR.VBVMR_GetVoicemeeterType =VBVMR_GetVoicemeeterType; + iVMR.VBVMR_GetVoicemeeterVersion =VBVMR_GetVoicemeeterVersion; + iVMR.VBVMR_IsParametersDirty =VBVMR_IsParametersDirty; + iVMR.VBVMR_GetParameterFloat =VBVMR_GetParameterFloat; + iVMR.VBVMR_GetParameterStringA =VBVMR_GetParameterStringA; + iVMR.VBVMR_GetParameterStringW =VBVMR_GetParameterStringW; + + iVMR.VBVMR_GetLevel =VBVMR_GetLevel; + iVMR.VBVMR_GetMidiMessage =VBVMR_GetMidiMessage; + iVMR.VBVMR_SetParameterFloat =VBVMR_SetParameterFloat; + iVMR.VBVMR_SetParameters =VBVMR_SetParameters; + iVMR.VBVMR_SetParametersW =VBVMR_SetParametersW; + iVMR.VBVMR_SetParameterStringA =VBVMR_SetParameterStringA; + iVMR.VBVMR_SetParameterStringW =VBVMR_SetParameterStringW; + + iVMR.VBVMR_Output_GetDeviceNumber =VBVMR_Output_GetDeviceNumber; + iVMR.VBVMR_Output_GetDeviceDescA =VBVMR_Output_GetDeviceDescA; + iVMR.VBVMR_Output_GetDeviceDescW =VBVMR_Output_GetDeviceDescW; + iVMR.VBVMR_Input_GetDeviceNumber =VBVMR_Input_GetDeviceNumber; + iVMR.VBVMR_Input_GetDeviceDescA =VBVMR_Input_GetDeviceDescA; + iVMR.VBVMR_Input_GetDeviceDescW =VBVMR_Input_GetDeviceDescW; + + iVMR.VBVMR_AudioCallbackRegister =VBVMR_AudioCallbackRegister; + iVMR.VBVMR_AudioCallbackStart =VBVMR_AudioCallbackStart; + iVMR.VBVMR_AudioCallbackStop =VBVMR_AudioCallbackStop; + iVMR.VBVMR_AudioCallbackUnregister =VBVMR_AudioCallbackUnregister; + return 0; + } + +//Dynamic link to DLL in 'C' (regular use) +#else + + long InitializeDLLInterfaces(void) + { + char szDllName[1024]; + memset(&iVMR,0,sizeof(T_VBVMR_INTERFACE)); + + //get folder where is installed Voicemeeter + if (RegistryGetVoicemeeterFolder(szDllName) == FALSE) + { + // voicemeeter not installed + return -100; + } + //use right dll according O/S type + if (sizeof(void*) == 8) strcat(szDllName,"\\VoicemeeterRemote64.dll"); + else strcat(szDllName,"\\VoicemeeterRemote.dll"); + + // Load Dll + G_H_Module=LoadLibrary(szDllName); + if (G_H_Module == NULL) return -101; + + // Get function pointers + iVMR.VBVMR_Login =(T_VBVMR_Login)GetProcAddress(G_H_Module,"VBVMR_Login"); + iVMR.VBVMR_Logout =(T_VBVMR_Logout)GetProcAddress(G_H_Module,"VBVMR_Logout"); + iVMR.VBVMR_RunVoicemeeter =(T_VBVMR_RunVoicemeeter)GetProcAddress(G_H_Module,"VBVMR_RunVoicemeeter"); + iVMR.VBVMR_GetVoicemeeterType =(T_VBVMR_GetVoicemeeterType)GetProcAddress(G_H_Module,"VBVMR_GetVoicemeeterType"); + iVMR.VBVMR_GetVoicemeeterVersion =(T_VBVMR_GetVoicemeeterVersion)GetProcAddress(G_H_Module,"VBVMR_GetVoicemeeterVersion"); + + iVMR.VBVMR_IsParametersDirty =(T_VBVMR_IsParametersDirty)GetProcAddress(G_H_Module,"VBVMR_IsParametersDirty"); + iVMR.VBVMR_GetParameterFloat =(T_VBVMR_GetParameterFloat)GetProcAddress(G_H_Module,"VBVMR_GetParameterFloat"); + iVMR.VBVMR_GetParameterStringA =(T_VBVMR_GetParameterStringA)GetProcAddress(G_H_Module,"VBVMR_GetParameterStringA"); + iVMR.VBVMR_GetParameterStringW =(T_VBVMR_GetParameterStringW)GetProcAddress(G_H_Module,"VBVMR_GetParameterStringW"); + iVMR.VBVMR_GetLevel =(T_VBVMR_GetLevel)GetProcAddress(G_H_Module,"VBVMR_GetLevel"); + iVMR.VBVMR_GetMidiMessage =(T_VBVMR_GetMidiMessage)GetProcAddress(G_H_Module,"VBVMR_GetMidiMessage"); + + iVMR.VBVMR_SetParameterFloat =(T_VBVMR_SetParameterFloat)GetProcAddress(G_H_Module,"VBVMR_SetParameterFloat"); + iVMR.VBVMR_SetParameters =(T_VBVMR_SetParameters)GetProcAddress(G_H_Module,"VBVMR_SetParameters"); + iVMR.VBVMR_SetParametersW =(T_VBVMR_SetParametersW)GetProcAddress(G_H_Module,"VBVMR_SetParametersW"); + iVMR.VBVMR_SetParameterStringA =(T_VBVMR_SetParameterStringA)GetProcAddress(G_H_Module,"VBVMR_SetParameterStringA"); + iVMR.VBVMR_SetParameterStringW =(T_VBVMR_SetParameterStringW)GetProcAddress(G_H_Module,"VBVMR_SetParameterStringW"); + + iVMR.VBVMR_Output_GetDeviceNumber =(T_VBVMR_Output_GetDeviceNumber)GetProcAddress(G_H_Module,"VBVMR_Output_GetDeviceNumber"); + iVMR.VBVMR_Output_GetDeviceDescA =(T_VBVMR_Output_GetDeviceDescA)GetProcAddress(G_H_Module,"VBVMR_Output_GetDeviceDescA"); + iVMR.VBVMR_Output_GetDeviceDescW =(T_VBVMR_Output_GetDeviceDescW)GetProcAddress(G_H_Module,"VBVMR_Output_GetDeviceDescW"); + iVMR.VBVMR_Input_GetDeviceNumber =(T_VBVMR_Input_GetDeviceNumber)GetProcAddress(G_H_Module,"VBVMR_Input_GetDeviceNumber"); + iVMR.VBVMR_Input_GetDeviceDescA =(T_VBVMR_Input_GetDeviceDescA)GetProcAddress(G_H_Module,"VBVMR_Input_GetDeviceDescA"); + iVMR.VBVMR_Input_GetDeviceDescW =(T_VBVMR_Input_GetDeviceDescW)GetProcAddress(G_H_Module,"VBVMR_Input_GetDeviceDescW"); + + // check pointers are valid + if (iVMR.VBVMR_Login == NULL) return -1; + if (iVMR.VBVMR_Logout == NULL) return -2; + if (iVMR.VBVMR_RunVoicemeeter == NULL) return -2; + if (iVMR.VBVMR_GetVoicemeeterType == NULL) return -3; + if (iVMR.VBVMR_GetVoicemeeterVersion == NULL) return -4; + if (iVMR.VBVMR_IsParametersDirty == NULL) return -5; + if (iVMR.VBVMR_GetParameterFloat == NULL) return -6; + if (iVMR.VBVMR_GetParameterStringA == NULL) return -7; + if (iVMR.VBVMR_GetParameterStringW == NULL) return -8; + if (iVMR.VBVMR_GetLevel == NULL) return -9; + if (iVMR.VBVMR_SetParameterFloat == NULL) return -10; + if (iVMR.VBVMR_SetParameters == NULL) return -11; + if (iVMR.VBVMR_SetParametersW == NULL) return -12; + if (iVMR.VBVMR_SetParameterStringA == NULL) return -13; + if (iVMR.VBVMR_SetParameterStringW == NULL) return -14; + if (iVMR.VBVMR_GetMidiMessage == NULL) return -15; + + if (iVMR.VBVMR_Output_GetDeviceNumber == NULL) return -30; + if (iVMR.VBVMR_Output_GetDeviceDescA == NULL) return -31; + if (iVMR.VBVMR_Output_GetDeviceDescW == NULL) return -32; + if (iVMR.VBVMR_Input_GetDeviceNumber == NULL) return -33; + if (iVMR.VBVMR_Input_GetDeviceDescA == NULL) return -34; + if (iVMR.VBVMR_Input_GetDeviceDescW == NULL) return -35; + + return 0; + } + + +#endif + + +/*******************************************************************************/ +/* CONSTANT FUNCTION OF VOICEMEETER TYPE */ +/*******************************************************************************/ + + +static char * G_szBUSNameList_v1[2]={"A", "B"}; +static char * G_szBUSNameList_v2[5]={"A1", "A2", "A3", "B1", "B2"}; +static char * G_szBUSNameList_v3[8]={"A1", "A2", "A3", "A4", "A5", "B1", "B2", "B3"}; + +static char * G_szStripNameList_v1[3]={"IN #1", "IN #2", "VIN #1"}; +static char * G_szStripNameList_v2[5]={"IN #1", "IN #2", "IN #3", "VIN #1", "VIN #2"}; +static char * G_szStripNameList_v3[8]={"IN #1", "IN #2", "IN #3", "IN #4", "IN #5", "VIN #1", "VIN #2", "VIN #3"}; + +static long G_nbChannelPerStrip_v1[3]={2, 2, 8}; +static long G_nbChannelPerStrip_v2[5]={2, 2, 2, 8, 8}; +static long G_nbChannelPerStrip_v3[8]={2, 2, 2, 2, 2, 8, 8, 8}; + + +/*******************************************************************************/ +/* COLOR / PEN TOOLS */ +/*******************************************************************************/ + +typedef struct tagCOLORPENBRUSH +{ + COLORREF color; + HPEN pen; + HBRUSH brush; +} T_COLORPENBRUSH, *PT_COLORPENBRUSH, *LPT_COLORPENBRUSH; + +long CreateColorPenBrush(LPT_COLORPENBRUSH lpgdi, COLORREF color) +{ + LOGBRUSH lb; + if (lpgdi == NULL) return -1; + lpgdi->color=color; + lpgdi->pen=CreatePen(PS_SOLID,0,color); + + lb.lbStyle=BS_SOLID; + lb.lbColor=color; + lpgdi->brush=CreateBrushIndirect(&lb); + return 0; +} + +long DestroyColorPenBrush(LPT_COLORPENBRUSH lpgdi) +{ + if (lpgdi == NULL) return -1; + + lpgdi->color=0; + if (lpgdi->pen != NULL) DeleteObject(lpgdi->pen); + lpgdi->pen=NULL; + if (lpgdi->brush != NULL) DeleteObject(lpgdi->brush); + lpgdi->brush=NULL; + return 0; +} + + + + +/*******************************************************************************/ +/* OUR PARAM STRUCTURE */ +/* to store all voicemeeter parameter we manage */ +/*******************************************************************************/ + + + +typedef struct tagMYVM_PARAMETERS +{ + long nbStrip; + T_VMSCTL_STRIP_DATA strip[VMSCTL_MAX_NBSTRIP]; + + long nbBus; + T_VMSCTL_BUS_DATA bus[VMSCTL_MAX_NBBUS]; + + long monitorbus; +} T_MYVM_PARAMETERS, *PT_MYVM_PARAMETERS, *LPT_MYVM_PARAMETERS; + + +/*******************************************************************************/ +/* APPLICATION CONTEXT */ +/*******************************************************************************/ + +#define SLIDERLINKMODE_INDEPENDENT 0 +#define SLIDERLINKMODE_ABSLINK 1 +#define SLIDERLINKMODE_RELLINK 2 + +#define SLIDERLINKMODE_DX 80 + +typedef struct tagVBAN_CMD_PARAM +{ + char VBAN_szStreamName[32]; + char VBAN_szIPAddress[32]; + long VBAN_UDPport; +} T_VBAN_CMD_PARAM, *PT_VBAN_CMD_PARAM, *LPT_VBAN_CMD_PARAM; + + +typedef struct tagAPP_CONTEXT +{ + HWND hwnd_MainWindow; + HINSTANCE hinstance; + size_t wTimer; + long hw_dx; + long hw_dy; + long vbvmr_NotInstalled; + long vbvmr_error; + long vbvmr_connect; + long vbvmr_nbbus; + long vbvmr_nbstrip; + long vbvmr_multilayer; + long vbvmr_version; + long vbvmr_monitor_support; + + char ** vbvmr_pBUSName; + char ** vbvmr_pStripName; + long * vbvmr_pStripChannel; + DWORD msLastTimeForVBANRegister; // time reference in ms + DWORD msLastTimeForVBANCheck; // time reference in ms + DWORD LastCounter; // time reference in ms + BOOL VBANisConnected; // time reference in ms + T_MYVM_PARAMETERS current_param; + long StripSliderMode; + + long VMConnectionType; // 0 = direct, 1 = VBAN1, 2 = VBAN2, 3 = VBAN3, 4 = VBAN4. + T_VBAN_CMD_PARAM VMLinkVBAN[4]; + + HWND hw_StripList[VMSCTL_MAX_NBSTRIP]; + HWND hw_BusList[VMSCTL_MAX_NBBUS]; + + HFONT font0; + HFONT font1; + HFONT font2; + + T_COLORPENBRUSH gdiobjects_black; + T_COLORPENBRUSH gdiobjects_bkg; + T_COLORPENBRUSH gdiobjects_bkg_ctl; + T_COLORPENBRUSH gdiobjects_blue0; + T_COLORPENBRUSH gdiobjects_blue1; + T_COLORPENBRUSH gdiobjects_blue2; + T_COLORPENBRUSH gdiobjects_blue3; + T_COLORPENBRUSH gdiobjects_buttongreen; + T_COLORPENBRUSH gdiobjects_slidergreen; + T_COLORPENBRUSH gdiobjects_sliderred; + T_COLORPENBRUSH gdiobjects_white; + T_COLORPENBRUSH gdiobjects_meter_blue; + T_COLORPENBRUSH gdiobjects_meter_green; + T_COLORPENBRUSH gdiobjects_meter_red; + T_COLORPENBRUSH gdiobjects_mute; + T_COLORPENBRUSH gdiobjects_monitor; + T_COLORPENBRUSH gdiobjects_grey; + + RECT CurrentWindowRect; + RECT rect_inputs; + RECT rect_outputs; + RECT rect_SliderMode; + RECT rect_VMConnectionType; +} T_APP_CONTEXT, *PT_APP_CONTEXT, *LPT_APP_CONTEXT; + +static T_APP_CONTEXT G_MainAppCtx = {NULL, NULL}; + + + +long InitResources(LPT_APP_CONTEXT lpapp) +{ + LOGFONT lf; + + if (lpapp == NULL) return -1; + + //make Font + memset(&lf,0, sizeof(LOGFONT)); + lf.lfHeight = 14; + lf.lfWeight = 400; + strcpy(lf.lfFaceName,"Arial"); + lpapp->font0 =CreateFontIndirect(&lf); + + lf.lfHeight = 16; + lf.lfWeight = 400; + strcpy(lf.lfFaceName,"Arial"); + lpapp->font1 =CreateFontIndirect(&lf); + + lf.lfHeight = 18; + lf.lfWeight = 600; + strcpy(lf.lfFaceName,"Arial"); + lpapp->font2 =CreateFontIndirect(&lf); + + //make pen brush + CreateColorPenBrush(&(lpapp->gdiobjects_black), RGB(0,0,0)); + CreateColorPenBrush(&(lpapp->gdiobjects_bkg), RGB(18,32,41)); + CreateColorPenBrush(&(lpapp->gdiobjects_bkg_ctl), RGB(44,61,77)); + CreateColorPenBrush(&(lpapp->gdiobjects_blue0), RGB(71,90,103)); + CreateColorPenBrush(&(lpapp->gdiobjects_blue1), RGB(95,120,137)); + CreateColorPenBrush(&(lpapp->gdiobjects_blue2), RGB(111,140,160)); + CreateColorPenBrush(&(lpapp->gdiobjects_blue3), RGB(104,230,248)); + CreateColorPenBrush(&(lpapp->gdiobjects_buttongreen), RGB(36,167,49)); + CreateColorPenBrush(&(lpapp->gdiobjects_slidergreen), RGB(112,195,153)); + CreateColorPenBrush(&(lpapp->gdiobjects_sliderred), RGB(248,99,77)); + CreateColorPenBrush(&(lpapp->gdiobjects_white), RGB(255,255,255)); + + CreateColorPenBrush(&(lpapp->gdiobjects_meter_blue), RGB(130,170,180)); + CreateColorPenBrush(&(lpapp->gdiobjects_meter_green), RGB(30,255,90)); + CreateColorPenBrush(&(lpapp->gdiobjects_meter_red), RGB(250,0,0)); + + CreateColorPenBrush(&(lpapp->gdiobjects_mute), RGB(246,91,81)); + CreateColorPenBrush(&(lpapp->gdiobjects_monitor), RGB(203,174,130)); + CreateColorPenBrush(&(lpapp->gdiobjects_grey), RGB(100,100,100)); + + return 0; +} + +long EndResources(LPT_APP_CONTEXT lpapp) +{ + if (lpapp == NULL) return -1; + //Delete font Object + if (lpapp->font0 != NULL) DeleteObject(lpapp->font0); + lpapp->font0=NULL; + if (lpapp->font1 != NULL) DeleteObject(lpapp->font1); + lpapp->font1=NULL; + if (lpapp->font2 != NULL) DeleteObject(lpapp->font2); + lpapp->font2=NULL; + //Delete Pen Brush + DestroyColorPenBrush(&(lpapp->gdiobjects_black)); + DestroyColorPenBrush(&(lpapp->gdiobjects_bkg)); + DestroyColorPenBrush(&(lpapp->gdiobjects_bkg_ctl)); + DestroyColorPenBrush(&(lpapp->gdiobjects_blue0)); + DestroyColorPenBrush(&(lpapp->gdiobjects_blue1)); + DestroyColorPenBrush(&(lpapp->gdiobjects_blue2)); + DestroyColorPenBrush(&(lpapp->gdiobjects_blue3)); + DestroyColorPenBrush(&(lpapp->gdiobjects_buttongreen)); + DestroyColorPenBrush(&(lpapp->gdiobjects_slidergreen)); + DestroyColorPenBrush(&(lpapp->gdiobjects_sliderred)); + DestroyColorPenBrush(&(lpapp->gdiobjects_white)); + + DestroyColorPenBrush(&(lpapp->gdiobjects_meter_blue)); + DestroyColorPenBrush(&(lpapp->gdiobjects_meter_green)); + DestroyColorPenBrush(&(lpapp->gdiobjects_meter_red)); + DestroyColorPenBrush(&(lpapp->gdiobjects_mute)); + DestroyColorPenBrush(&(lpapp->gdiobjects_monitor)); + return 0; +} + + +/*******************************************************************************/ +/* LOCAL TOOL Functions */ +/*******************************************************************************/ + + +#ifndef SM_CXPADDEDBORDER + #define SM_CXPADDEDBORDER 92 +#endif + +typedef struct tagVBNONCLIENTMETRICS +{ + UINT cbSize; + int iBorderWidth; + int iScrollWidth; + int iScrollHeight; + int iCaptionWidth; + int iCaptionHeight; + LOGFONT lfCaptionFont; + int iSmCaptionWidth; + int iSmCaptionHeight; + LOGFONT lfSmCaptionFont; + int iMenuWidth; + int iMenuHeight; + LOGFONT lfMenuFont; + LOGFONT lfStatusFont; + LOGFONT lfMessageFont; + int iPaddedBorderWidth; +} VBNONCLIENTMETRICS, *LPVBNONCLIENTMETRICS; + + +void TOOL_GetWindowsMetricInfo(long * win_border, long * win_title,long * win_menu) +{ + long xyadjust=0; + BOOL ok; + VBNONCLIENTMETRICS ncm; + ncm.cbSize=sizeof(VBNONCLIENTMETRICS); + ok=SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(VBNONCLIENTMETRICS),&ncm,0L); + if (ok != 0) + { + xyadjust=ncm.iPaddedBorderWidth;//+2; + if (win_menu != NULL) *win_menu =ncm.iMenuHeight; + if (win_border != NULL) *win_border =xyadjust+ncm.iBorderWidth; + if (win_title != NULL) *win_title =ncm.iCaptionHeight; + return; + } + xyadjust=GetSystemMetrics(SM_CXPADDEDBORDER); + if (win_menu != NULL) *win_menu=GetSystemMetrics(SM_CYMENU); + if (win_border != NULL) *win_border= xyadjust+GetSystemMetrics(SM_CXDLGFRAME); //SM_CXDLGFRAME SM_CXBORDER ncm.iBorderWidth; + if (win_title != NULL) *win_title=GetSystemMetrics(SM_CYCAPTION);//ncm.iCaptionHeight; +} + + + +void TOOL_RemoveUnauthorizedChar(char * szString) +{ + char cc,* lpTarget,*lpSource; + if (szString == NULL) return; + lpSource=szString; + lpTarget=szString; + + while(*lpSource != 0) + { + cc=*lpSource; + if (((cc > 47) && (cc<58)) || + ((cc>64) && (cc<91)) || + ((cc>96) && (cc<123)) || + (cc == '-') || (cc == '_') || (cc == '{') || (cc == '}') || (cc =='(') || + (cc == ')') || (cc == '[') || (cc == ']') || (cc == 32)) + { + *lpTarget=cc; + lpTarget++; + } + lpSource++; + } + *lpTarget=0; +} + + +long TOOL_IsItIPAddress(char* sss) +{ + long nbn=0,num=0,fdigi=0; + char cc; + cc=*sss++; + while (cc > 31) + { + if ((cc > 47) && (cc < 58)) + { + num = (num*10) + (cc - 48); + fdigi=1; + } + else + { + if (cc == '.') + { + fdigi=0; + if ((num >= 0) && (num < 256)) nbn++; + else return -2; + num=0; + } + else + { + if (cc != 32) return -1; + } + } + cc=*sss++; + } + if (fdigi != 0) + { + if ((num >= 0) && (num < 256)) nbn++; + } + if (nbn == 4) return 1; + return 0; +} + +DWORD TOOL_GetDeltaMsDword(DWORD previous_ms, DWORD current_ms) +{ + DWORD delta; + if (current_ms >= previous_ms) delta = current_ms-previous_ms; + else + { + delta = (0xFFFFFFFF-previous_ms); + delta +=current_ms; + } + return delta; +} + + + +/*******************************************************************************/ +/* REGISTRY TOOL */ +/*******************************************************************************/ + + +BOOL __cdecl TOOL_RegistrySaveUserString(char * key,char * ValueName,char * strvalue) +{ + DWORD nbc; + HKEY hkResult; + LONG rep; + rep=RegOpenKey(HKEY_CURRENT_USER,key,&hkResult); + if (rep != ERROR_SUCCESS) + { + rep=RegCreateKey(HKEY_CURRENT_USER,key,&hkResult); + if (rep != ERROR_SUCCESS) return FALSE; + } + nbc= (DWORD)((strlen(strvalue)+1)*sizeof(char)); + rep=RegSetValueEx(hkResult, ValueName,0,REG_SZ,(unsigned char *)strvalue,nbc); + RegCloseKey(hkResult); + if (rep != ERROR_SUCCESS) return FALSE; + return TRUE; +} + +BOOL __cdecl TOOL_RegistryLoadUserString(char * key,char * ValueName,char * strvalue) +{ + char sss[4100]; + DWORD nnsize=4096; + HKEY hkResult; + LONG rep; + DWORD pptype=REG_SZ; + sss[0]=0; + rep=RegOpenKey(HKEY_CURRENT_USER,key,&hkResult); + if (rep != ERROR_SUCCESS) return FALSE; + strvalue[0]=0; + rep=RegQueryValueEx(hkResult,ValueName,0,&pptype,(unsigned char *)sss,&nnsize); + RegCloseKey(hkResult); + if (pptype != REG_SZ) return FALSE; + if (rep != ERROR_SUCCESS) return FALSE; + if (nnsize>4050) nnsize=4050; + strncpy(strvalue,sss,nnsize); + return TRUE; +} + +BOOL __cdecl TOOL_RegistrySaveUserDWORD(char * key,char * ValueName,DWORD value) +{ + HKEY hkResult; + LONG rep; + rep=RegOpenKey(HKEY_CURRENT_USER,key,&hkResult); + if (rep != ERROR_SUCCESS) + { + rep=RegCreateKey(HKEY_CURRENT_USER,key,&hkResult); + if (rep != ERROR_SUCCESS) return FALSE; + } + rep=RegSetValueEx(hkResult, ValueName,0,REG_DWORD,(unsigned char *)&value,sizeof(DWORD)); + RegCloseKey(hkResult); + if (rep != ERROR_SUCCESS) return FALSE; + return TRUE; +} + +BOOL __cdecl TOOL_RegistryLoadUserDWORD(char * key,char * ValueName,DWORD * pvalue) +{ + HKEY hkResult; + LONG rep; + DWORD bSize = sizeof(DWORD); + DWORD bType = REG_DWORD; + + rep=RegOpenKey(HKEY_CURRENT_USER,key,&hkResult); + if (rep != ERROR_SUCCESS) return FALSE; + rep=RegQueryValueEx(hkResult, ValueName,0,&bType,(unsigned char *)pvalue,&bSize); + RegCloseKey(hkResult); + if (bType != REG_DWORD) return FALSE; + if (rep != ERROR_SUCCESS) return FALSE; + return TRUE; +} + + + + + + + + +/*******************************************************************************/ +/* VBAN CONFIGURATION DIALOG BOX */ +/*******************************************************************************/ + + +//VBAN Edit Dialog Box Context +typedef struct tagVBANOPTION_DIALOGBOX +{ + HGLOBAL hdlgtemplate; + HWND hparent; + HWND hw; + int fInit; + long x0,y0,dx,dy; + long style; + + HWND hw_StreamName[4]; + HWND hw_StreamIPTo[4]; + HWND hw_StreamPort[4]; + HWND hw_StreamCheck[4]; + +} T_VBANOPTION_DIALOGBOX, *PT_VBANOPTION_DIALOGBOX, *LPT_VBANOPTION_DIALOGBOX; + +static T_VBANOPTION_DIALOGBOX G_VBANDialog_CTX={NULL,NULL, NULL}; + + +#define IDC_VBANEDIT_NAME 100 +#define IDC_VBANEDIT_IP 200 +#define IDC_VBANEDIT_CHECK 300 +#define IDC_VBANEDIT_PORT 400 + +void VBANDIALOG_CreateControls(LPT_VBANOPTION_DIALOGBOX lpctx, HWND hwParent) +{ + LPT_VBAN_CMD_PARAM lpVBAN_param; + char sz[128]; + long x0,y0,vi; + HWND hh; + LPT_APP_CONTEXT lpapp; + lpapp=&G_MainAppCtx; + + y0=10+30+20; + for (vi=0;vi<4;vi++) + { + lpVBAN_param = &(lpapp->VMLinkVBAN[vi]); + x0=10; + + //name + x0=x0+80; + hh=CreateWindowEx(WS_EX_CLIENTEDGE,"edit",lpVBAN_param->VBAN_szStreamName, + WS_CHILD | WS_VISIBLE | ES_LEFT | WS_TABSTOP | ES_AUTOHSCROLL, + x0,y0,200,26, + hwParent,(HMENU)(IDC_VBANEDIT_NAME+vi),lpapp->hinstance,NULL); + SendMessage(hh,WM_SETFONT,(WPARAM)lpapp->font1,MAKELPARAM(1,0)); + SendMessage(hh,EM_SETMARGINS,EC_LEFTMARGIN | EC_RIGHTMARGIN,(LPARAM) MAKELONG(2,2)); + lpctx->hw_StreamName[vi]=hh; + + //IP to + x0=x0+210; + hh=CreateWindowEx(WS_EX_CLIENTEDGE,"edit",lpVBAN_param->VBAN_szIPAddress, + WS_CHILD | WS_VISIBLE | ES_LEFT | WS_TABSTOP | ES_AUTOHSCROLL, + x0,y0,180,26, + hwParent,(HMENU)(IDC_VBANEDIT_IP+vi),lpapp->hinstance,NULL); + SendMessage(hh,WM_SETFONT,(WPARAM)lpapp->font1,MAKELPARAM(1,0)); + SendMessage(hh,EM_SETMARGINS,EC_LEFTMARGIN | EC_RIGHTMARGIN,(LPARAM) MAKELONG(2,2)); + lpctx->hw_StreamIPTo[vi]=hh; + + // + x0=x0+190; + sprintf(sz,"%i", lpVBAN_param->VBAN_UDPport); + hh=CreateWindowEx(WS_EX_CLIENTEDGE,"edit",sz, + WS_CHILD | WS_VISIBLE | ES_LEFT | WS_TABSTOP | ES_AUTOHSCROLL, + x0,y0,80,26, + hwParent,(HMENU)(IDC_VBANEDIT_PORT+vi),lpapp->hinstance,NULL); + SendMessage(hh,WM_SETFONT,(WPARAM)lpapp->font1,MAKELPARAM(1,0)); + SendMessage(hh,EM_SETMARGINS,EC_LEFTMARGIN | EC_RIGHTMARGIN,(LPARAM) MAKELONG(2,2)); + lpctx->hw_StreamPort[vi]=hh; + + y0=y0+40; + } + + + // + // button Ok/Cancel + // + hh=CreateWindow("button","Ok",WS_CHILD | WS_VISIBLE | WS_TABSTOP, + lpctx->dx-200,lpctx->dy-40,90,30, + hwParent,(HMENU)1,lpapp->hinstance,NULL); + + hh=CreateWindow("button","Cancel",WS_CHILD | WS_VISIBLE | WS_TABSTOP, + lpctx->dx-100,lpctx->dy-40,90,30, + hwParent,(HMENU)2,lpapp->hinstance,NULL); + + // + +} + +static void VBANDIALOG_ValidateOption(LPT_VBANOPTION_DIALOGBOX lpctx) +{ + LPT_VBAN_CMD_PARAM lpVBAN_param; + char sz[128]; + long nnn,vi; + LPT_APP_CONTEXT lpapp; + lpapp=&G_MainAppCtx; + + for (vi=0;vi<4;vi++) + { + lpVBAN_param = &(lpapp->VMLinkVBAN[vi]); + + GetWindowText(lpctx->hw_StreamName[vi],sz,64); + TOOL_RemoveUnauthorizedChar(sz); + sz[17]=0; + strcpy(lpVBAN_param->VBAN_szStreamName, sz); + + GetWindowText(lpctx->hw_StreamIPTo[vi],sz,64); + if (TOOL_IsItIPAddress(sz) == 1) + { + strcpy(lpVBAN_param->VBAN_szIPAddress, sz); + } + + GetWindowText(lpctx->hw_StreamPort[vi],sz,64); + nnn=atoi(sz); + nnn=nnn & 0x0000FFFF; + if (nnn > 0) + { + lpVBAN_param->VBAN_UDPport= nnn; + } + } +} + + + +void VBANDIALOG_DrawStuff(LPT_VBANOPTION_DIALOGBOX lpctx, HDC dc) +{ + long vi, x0,y0; + char sss[512]; + HBRUSH oldbrush; + HPEN oldpen; + HFONT oldfont; + LPT_APP_CONTEXT lpapp; + lpapp=&G_MainAppCtx; + + oldbrush=(HBRUSH)SelectObject(dc,lpapp->gdiobjects_grey.brush); + oldpen=(HPEN)SelectObject(dc,GetStockObject(NULL_PEN)); + oldfont=(HFONT)SelectObject(dc,lpapp->font1); + SetBkMode(dc,TRANSPARENT); + + x0=10; + y0=10; + + SetTextColor(dc,RGB(0,0,0)); + strcpy(sss,"VBAN Connections Configuration:"); + TextOut(dc,x0+5,y0+2,sss,(int)strlen(sss)); + + SetTextColor(dc,RGB(255,255,255)); + y0=y0+30; + x0=x0+80; + strcpy(sss,"Stream Name:"); + Rectangle(dc,x0,y0,x0+200,y0+20); + TextOut(dc,x0+5,y0+2,sss,(int)strlen(sss)); + + x0=x0+210; + strcpy(sss,"IP Addres To:"); + Rectangle(dc,x0,y0,x0+200,y0+20); + TextOut(dc,x0+5,y0+2,sss,(int)strlen(sss)); + + x0=x0+190; + strcpy(sss,"UDP port:"); + Rectangle(dc,x0,y0,x0+80,y0+20); + TextOut(dc,x0+5,y0+2,sss,(int)strlen(sss)); + + + y0=10+30+20; + x0=10; + SetTextColor(dc,RGB(0,0,0)); + for (vi=0;vi<4;vi++) + { + sprintf(sss,"VBAN #%i", vi+1); + TextOut(dc,x0+5,y0+2,sss,(int)strlen(sss)); + y0=y0+40; + } + + strcpy(sss,"WARNING: VBAN Incoming Command Stream must be activated on Voicemeeter."); + TextOut(dc,x0+45,y0+2,sss,(int)strlen(sss)); + + SelectObject(dc,oldfont); + SelectObject(dc,oldbrush); + SelectObject(dc,oldpen); + +} + +static BOOL CALLBACK VBANDIALOG_DialogProc(HWND hw, //handle de la fenetre concernés. + UINT te, //Type d'événement. + WPARAM p1, //paramètre 1. + LPARAM p2) //Ligne de paramètre 2 +{ + char sss[128]; + LPT_VBANOPTION_DIALOGBOX lpctx; + HPEN oldpen; + HBRUSH oldbrush; + long win_border, win_title, win_menu; + RECT rect; + HDC dc; + PAINTSTRUCT ps; + long dx,dy,nnn,nNotify; + lpctx=&G_VBANDialog_CTX; + switch (te) + { + case WM_INITDIALOG: + lpctx->hw=hw; + //-------------------------------------------- + strcpy(sss,"VBAN Configuration..."); + SetWindowText(hw,sss); + VBANDIALOG_CreateControls(lpctx, hw); + TOOL_GetWindowsMetricInfo(&win_border, &win_title,&win_menu); + + dx=lpctx->dx+(win_border*2); + dy=lpctx->dy+(win_border*2)+win_title; + SetWindowPos(hw,HWND_TOP,lpctx->x0,lpctx->y0,dx,dy,SWP_SHOWWINDOW); + SetFocus(hw); + lpctx->fInit=1; + break; + + case WM_COMMAND: + if (lpctx->fInit == 0) break; + nnn=LOWORD(p1); + nNotify=HIWORD(p1); + switch(nnn) + { + case 1: + //CancelEditFlag(lpctx, lpctx->dialopt_track,FALSE); + VBANDIALOG_ValidateOption(lpctx); + EndDialog(hw,1); + break; + case 2: + EndDialog(hw,0); + break; + + } + break; + case WM_PAINT: + dc=BeginPaint(hw,&ps); + VBANDIALOG_DrawStuff(lpctx, dc); + EndPaint(hw,&ps); + break; + + case WM_ERASEBKGND: + dc=(HDC)p1; + GetClientRect(hw,&rect); + oldpen=(HPEN)SelectObject(dc,GetStockObject(WHITE_PEN)); + oldbrush=(HBRUSH)SelectObject(dc,GetStockObject(LTGRAY_BRUSH)); + Rectangle(dc, 0,0,rect.right,rect.bottom); + SelectObject(dc,oldpen); + SelectObject(dc,oldbrush); + return TRUE; + + case WM_KEYDOWN: + switch(p1) + { + case VK_RETURN: + PostMessage(hw,WM_COMMAND,1,0); + return 0; + case VK_ESCAPE: + PostMessage(hw,WM_COMMAND,2,0); + return 0; + } + return -1; + case WM_CLOSE: + PostMessage(hw,WM_COMMAND,2,0); + return TRUE; + case WM_DESTROY: + GlobalFree(lpctx->hdlgtemplate); + lpctx->hw=NULL; + break; + } + return 0; +} + +BOOL VBANDIALOG_DialogGo(HWND h_parent,DWORD style) +{ + LPDLGTEMPLATE lpdlgtemplate; + RECT rect; + LPT_VBANOPTION_DIALOGBOX lpctx; + LPT_APP_CONTEXT lpapp; + lpctx=&G_VBANDialog_CTX; + lpapp=&G_MainAppCtx; + + if (lpctx->hw != NULL) EndDialog(lpctx->hw, 0); + GetWindowRect(h_parent, &rect); + + lpctx->hparent=h_parent; + lpctx->style=style; + lpctx->dx=600; + lpctx->dy=300; + lpctx->fInit = 0; + + lpctx->x0 = ((rect.right-rect.left)-lpctx->dx)>>1; + lpctx->y0 = ((rect.bottom-rect.top)-lpctx->dy)>>1; + if (lpctx->x0 < 0) lpctx->x0=0; + if (lpctx->y0 < 0) lpctx->y0=0; + lpctx->x0 +=rect.left; + lpctx->y0 +=rect.top; + + //------------------------------------------------------------- + lpctx->hdlgtemplate=GlobalAlloc(GMEM_ZEROINIT,1024); + lpdlgtemplate=(LPDLGTEMPLATE)GlobalLock(lpctx->hdlgtemplate); + lpdlgtemplate->style=WS_POPUP | DS_NOIDLEMSG | WS_VISIBLE | WS_CLIPCHILDREN | WS_BORDER | WS_CAPTION | WS_SYSMENU; + lpdlgtemplate->dwExtendedStyle=0L; + lpdlgtemplate->cdit=0L; + GlobalUnlock(lpctx->hdlgtemplate); + + return (BOOL)DialogBoxIndirectParam(lpapp->hinstance,(const DLGTEMPLATE *)lpctx->hdlgtemplate,h_parent,(DLGPROC)VBANDIALOG_DialogProc,(LPARAM)lpctx); +} + + + + + + + + + + + + + + + + + +/*******************************************************************************/ +/* LOAD / SAVE CONFIGURATION */ +/*******************************************************************************/ + +static char * G_OptionDirKey ="VB-Audio\\VMStreamerView"; + +static char * G_OptionKey_VBANx_name="VBAN%i_name"; +static char * G_OptionKey_VBANx_ip="VBAN%i_ip"; +static char * G_OptionKey_VBANx_port="VBAN%i_port"; + +static char * G_OptionKey_ConnectionType="VMConnectType"; +static char * G_OptionKey_StripSliderMode="StripSliderMode"; + +static char * G_OptionKey_WindowRectLeft="WinPos_X0"; +static char * G_OptionKey_WindowRectTop="WinPos_Y0"; +static char * G_OptionKey_WindowRectRight="WinPos_X1"; +static char * G_OptionKey_WindowRectBottom="WinPos_Y1"; + + +void LoadAppConfiguration(LPT_APP_CONTEXT lpapp) +{ + LPT_VBAN_CMD_PARAM lpVBANParam; + BOOL ok; + long nnn; + int vi; + char sz[2048]; + char szKey[128]; + + // set default parameters + for (vi=0;vi<4;vi++) + { + lpVBANParam = &(lpapp->VMLinkVBAN[vi]); + strcpy(lpVBANParam->VBAN_szStreamName, "Command1"); + sprintf(lpVBANParam->VBAN_szIPAddress, "192.168.10.%i", 10+vi); + lpVBANParam->VBAN_UDPport = 6980; + } + + // windows rect + ok=TOOL_RegistryLoadUserDWORD(G_OptionDirKey, G_OptionKey_WindowRectLeft, &nnn); + if (ok == TRUE) lpapp->CurrentWindowRect.left = nnn; + ok=TOOL_RegistryLoadUserDWORD(G_OptionDirKey, G_OptionKey_WindowRectTop, &nnn); + if (ok == TRUE) lpapp->CurrentWindowRect.top = nnn; + ok=TOOL_RegistryLoadUserDWORD(G_OptionDirKey, G_OptionKey_WindowRectRight, &nnn); + if (ok == TRUE) lpapp->CurrentWindowRect.right = nnn; + ok=TOOL_RegistryLoadUserDWORD(G_OptionDirKey, G_OptionKey_WindowRectBottom, &nnn); + if (ok == TRUE) lpapp->CurrentWindowRect.bottom = nnn; + + // SliderMode + ok=TOOL_RegistryLoadUserDWORD(G_OptionDirKey, G_OptionKey_StripSliderMode, &nnn); + if (ok == TRUE) + { + nnn=nnn & 0x0000000F; + if (nnn > 2) nnn=0; + lpapp->StripSliderMode = nnn; + } + + // Link Type + ok=TOOL_RegistryLoadUserDWORD(G_OptionDirKey, G_OptionKey_ConnectionType, &nnn); + if (ok == TRUE) + { + nnn=nnn & 0x0000000F; + if (nnn > 4) nnn=0; + lpapp->VMConnectionType = nnn; + } + + // VBAN Configuration + for (vi=0;vi<4;vi++) + { + lpVBANParam = &(lpapp->VMLinkVBAN[vi]); + + sprintf(szKey,G_OptionKey_VBANx_name, vi+1); + ok=TOOL_RegistryLoadUserString(G_OptionDirKey, szKey, sz); + if (ok == TRUE) + { + strncpy(lpVBANParam->VBAN_szStreamName,sz,32); + lpVBANParam->VBAN_szStreamName[32-1]=0; + } + sprintf(szKey,G_OptionKey_VBANx_ip, vi+1); + ok=TOOL_RegistryLoadUserString(G_OptionDirKey, szKey, sz); + if (ok == TRUE) + { + strncpy(lpVBANParam->VBAN_szIPAddress,sz,32); + lpVBANParam->VBAN_szIPAddress[32-1]=0; + } + sprintf(szKey,G_OptionKey_VBANx_port, vi+1); + ok=TOOL_RegistryLoadUserDWORD(G_OptionDirKey, szKey, &nnn); + if (ok == TRUE) + { + lpVBANParam->VBAN_UDPport = nnn & 0x0000FFFF; + } + } +} + +void SaveAppConfiguration(LPT_APP_CONTEXT lpapp) +{ + LPT_VBAN_CMD_PARAM lpVBANParam; + DWORD nnn; + int vi; + char szKey[128]; + + // store current windows rect + TOOL_RegistrySaveUserDWORD(G_OptionDirKey, G_OptionKey_WindowRectLeft, lpapp->CurrentWindowRect.left); + TOOL_RegistrySaveUserDWORD(G_OptionDirKey, G_OptionKey_WindowRectTop, lpapp->CurrentWindowRect.top); + TOOL_RegistrySaveUserDWORD(G_OptionDirKey, G_OptionKey_WindowRectRight, lpapp->CurrentWindowRect.right); + TOOL_RegistrySaveUserDWORD(G_OptionDirKey, G_OptionKey_WindowRectBottom, lpapp->CurrentWindowRect.bottom); + + // SliderMode + nnn=lpapp->StripSliderMode; + TOOL_RegistrySaveUserDWORD(G_OptionDirKey, G_OptionKey_StripSliderMode, nnn); + + // Link Type + nnn=lpapp->VMConnectionType; + TOOL_RegistrySaveUserDWORD(G_OptionDirKey, G_OptionKey_ConnectionType, nnn); + + // VBAN Configuration + for (vi=0;vi<4;vi++) + { + lpVBANParam = &(lpapp->VMLinkVBAN[vi]); + + sprintf(szKey,G_OptionKey_VBANx_name, vi+1); + TOOL_RegistrySaveUserString(G_OptionDirKey, szKey, lpVBANParam->VBAN_szStreamName); + + sprintf(szKey,G_OptionKey_VBANx_ip, vi+1); + TOOL_RegistrySaveUserString(G_OptionDirKey, szKey, lpVBANParam->VBAN_szIPAddress); + + sprintf(szKey,G_OptionKey_VBANx_port, vi+1); + nnn=lpVBANParam->VBAN_UDPport; + TOOL_RegistrySaveUserDWORD(G_OptionDirKey, szKey, nnn); + } +} + + + + + + +/*******************************************************************************/ +/* VBAN OR DIRECT */ +/*******************************************************************************/ + + +long SendParameterToVoicemeeter(char * szParam, float value) +{ + LPT_APP_CONTEXT lpapp; + lpapp=&G_MainAppCtx; + // If Direct Link (we use Voicemeeter Remote API + if (lpapp->VMConnectionType == 0) + { + if (lpapp->vbvmr_NotInstalled != 0) return -1; + return iVMR.VBVMR_SetParameterFloat(szParam, value); // set value in Local Voicemeeter + } + // Otherwise we send the VBAN request. + else + { + return VBANCMD_SendRequest_Float(szParam, value); // set value by a VBAN request + } +} + + +long GetCurrentVoicemeeterType(unsigned long * pType) +{ + LPT_APP_CONTEXT lpapp; + lpapp=&G_MainAppCtx; + // If Direct Link (we use Voicemeeter Remote API + if (lpapp->VMConnectionType == 0) + { + if (lpapp->vbvmr_NotInstalled != 0) return -1; + return iVMR.VBVMR_GetVoicemeeterType(pType); + } + // Otherwise we ask to our VBANCMD Lib. + else + { + return VBANCMD_GetVoicemeeterType(pType); + } +} + +long GetCurrentVoicemeeterVersion(unsigned long * pVersion) +{ + LPT_APP_CONTEXT lpapp; + lpapp=&G_MainAppCtx; + // If Direct Link (we use Voicemeeter Remote API + if (lpapp->VMConnectionType == 0) + { + if (lpapp->vbvmr_NotInstalled != 0) return -1; + return iVMR.VBVMR_GetVoicemeeterVersion(pVersion); + } + // Otherwise we ask to our VBANCMD Lib. + else + { + return VBANCMD_GetVoicemeeterVersion(pVersion); + } +} + +long GetCurrentBusLabel(long index, WCHAR * pwsz) +{ + char szParam[128]; + LPT_APP_CONTEXT lpapp; + lpapp=&G_MainAppCtx; + if (lpapp->VMConnectionType == 0) + { + if (lpapp->vbvmr_NotInstalled != 0) return -1; + sprintf(szParam,"Bus[%i].Label", index); + return iVMR.VBVMR_GetParameterStringW(szParam, pwsz); + } + else return VBANCMD_GetBusLabel(index, pwsz); +} + +long GetCurrentBusGain(long index, float * pValue) +{ + char szParam[128]; + LPT_APP_CONTEXT lpapp; + lpapp=&G_MainAppCtx; + if (lpapp->VMConnectionType == 0) + { + if (lpapp->vbvmr_NotInstalled != 0) return -1; + sprintf(szParam,"Bus[%i].Gain", index); + return iVMR.VBVMR_GetParameterFloat(szParam, pValue); + } + else return VBANCMD_GetBusGain(index, pValue); +} + +long GetCurrentBusSel(long index, float * pValue) +{ + char szParam[128]; + LPT_APP_CONTEXT lpapp; + lpapp=&G_MainAppCtx; + if (lpapp->VMConnectionType == 0) + { + if (lpapp->vbvmr_NotInstalled != 0) return -1; + sprintf(szParam,"Bus[%i].Sel", index); + return iVMR.VBVMR_GetParameterFloat(szParam, pValue); + } + else return VBANCMD_GetBusSel(index, pValue); +} + +long GetCurrentBusMute(long index, float * pValue) +{ + char szParam[128]; + LPT_APP_CONTEXT lpapp; + lpapp=&G_MainAppCtx; + if (lpapp->VMConnectionType == 0) + { + if (lpapp->vbvmr_NotInstalled != 0) return -1; + sprintf(szParam,"Bus[%i].Mute", index); + return iVMR.VBVMR_GetParameterFloat(szParam, pValue); + } + else return VBANCMD_GetBusMute(index, pValue); +} + +long GetCurrentBusMonitor(long index, float * pValue) +{ + char szParam[128]; + LPT_APP_CONTEXT lpapp; + lpapp=&G_MainAppCtx; + if (lpapp->VMConnectionType == 0) + { + if (lpapp->vbvmr_NotInstalled != 0) return -1; + sprintf(szParam,"Bus[%i].Monitor", index); + return iVMR.VBVMR_GetParameterFloat(szParam, pValue); + } + else return VBANCMD_GetBusMonitor(index, pValue); +} + + +long GetCurrentStripLabel(long index, WCHAR * pwsz) +{ + char szParam[128]; + LPT_APP_CONTEXT lpapp; + lpapp=&G_MainAppCtx; + if (lpapp->VMConnectionType == 0) + { + if (lpapp->vbvmr_NotInstalled != 0) return -1; + sprintf(szParam,"Strip[%i].Label", index); + return iVMR.VBVMR_GetParameterStringW(szParam, pwsz); + } + else return VBANCMD_GetStripLabel(index, pwsz); +} + +long GetCurrentStripGain(long index, float * pValue) +{ + char szParam[128]; + LPT_APP_CONTEXT lpapp; + lpapp=&G_MainAppCtx; + if (lpapp->VMConnectionType == 0) + { + if (lpapp->vbvmr_NotInstalled != 0) return -1; + sprintf(szParam,"Strip[%i].Gain", index); + return iVMR.VBVMR_GetParameterFloat(szParam, pValue); + } + else return VBANCMD_GetStripGain(index, pValue); +} + +long GetCurrentStripGainLayer(long index, long layer, float * pValue) +{ + char szParam[128]; + LPT_APP_CONTEXT lpapp; + lpapp=&G_MainAppCtx; + if (lpapp->VMConnectionType == 0) + { + if (lpapp->vbvmr_NotInstalled != 0) return -1; + sprintf(szParam,"Strip[%i].GainLayer[%i]", index, layer); + return iVMR.VBVMR_GetParameterFloat(szParam, pValue); + } + else return VBANCMD_GetStripGainLayer(index, layer, pValue); +} + +long GetCurrentStripMute(long index, float * pValue) +{ + char szParam[128]; + LPT_APP_CONTEXT lpapp; + lpapp=&G_MainAppCtx; + if (lpapp->VMConnectionType == 0) + { + if (lpapp->vbvmr_NotInstalled != 0) return -1; + sprintf(szParam,"Strip[%i].Mute", index); + return iVMR.VBVMR_GetParameterFloat(szParam, pValue); + } + else return VBANCMD_GetStripMute(index, pValue); +} + +long GetCurrentStripAssignation(long index, long nuBus, float * pValue) +{ + char szParam[128]; + LPT_APP_CONTEXT lpapp; + lpapp=&G_MainAppCtx; + if (lpapp->VMConnectionType == 0) + { + if (lpapp->vbvmr_NotInstalled != 0) return -1; + sprintf(szParam,"Strip[%i].%s", index, lpapp->vbvmr_pBUSName[nuBus]); + return iVMR.VBVMR_GetParameterFloat(szParam, pValue); + } + else return VBANCMD_GetStripAssignation(index, nuBus, pValue); +} + +long GetCurrentLevelDB(long index, long nuChannel, float * pLevelDB) +{ + long rep; + float NormalLevel; + LPT_APP_CONTEXT lpapp; + lpapp=&G_MainAppCtx; + if (lpapp->VMConnectionType == 0) + { + if (lpapp->vbvmr_NotInstalled != 0) return -1; + NormalLevel =0.0f; + rep= iVMR.VBVMR_GetLevel(index, nuChannel, &NormalLevel); + if (NormalLevel > 1.0e-5f) *pLevelDB=(float)(20.0*log10(NormalLevel)); + else *pLevelDB=-100.0f; + return rep; + } + else return VBANCMD_GetLevel(index, nuChannel, pLevelDB); +} + + +/*******************************************************************************/ +/* UPDATE CONTROLS */ +/*******************************************************************************/ + +#define VMRS_BITSTRIP 0x00000001 +#define VMRS_BITBUS 0x00000100 +#define VMRS_BITSTRIPNB 0x00010000 +#define VMRS_BITBUSNB 0x00020000 +//#define VMRS_BITMONBUT 0x00040000 +#define VMRS_BITMON 0x01000000 + +#define VMRS_BITALL 0xFFFFFFFF + + +#define VMRS_BITSTRIP_MASK 0x000000FF +#define VMRS_BITBUS_MASK 0x0000FF00 + + +static long UpdateAllControl(LPT_APP_CONTEXT lpapp, long nChangeBit) +{ + BOOL fStripMustBeUpdated; + LPT_MYVM_PARAMETERS lpp; + long nu,mask,fUpdateAll; + lpp = &(lpapp->current_param); + if (nChangeBit == VMRS_BITALL) fUpdateAll=1; + else fUpdateAll=0; + //if BUS parameters are changed + if ((nChangeBit & VMRS_BITBUS_MASK) != 0) + { + mask=VMRS_BITBUS; + for (nu=0;nuvbvmr_nbbus;nu++) + { + if ((nChangeBit & mask) != 0) + { + VMSCTL_SetDataBUS(lpapp->hw_BusList[nu], &(lpp->bus[nu]), fUpdateAll); + } + mask = mask << 1; + } + } + //if STRIP parameters are changed + fStripMustBeUpdated = ((nChangeBit & VMRS_BITBUSNB) != 0); + if (((nChangeBit & VMRS_BITSTRIP_MASK) != 0) || (fStripMustBeUpdated == TRUE)) + { + mask=VMRS_BITSTRIP; + for (nu=0;nuvbvmr_nbstrip;nu++) + { + if (((nChangeBit & mask) != 0) || (fStripMustBeUpdated == TRUE)) + { + VMSCTL_SetDataSTRIP(lpapp->hw_StripList[nu], &(lpp->strip[nu]), fUpdateAll); + } + mask = mask << 1; + } + } + + return 0; +} + + + + +static long AnalyseParamChange(LPT_APP_CONTEXT lpapp) +{ + char c1,c2, bus_assignbit[VMSCTL_MAX_NBBUS]; //0x10 bus activated / 0x01 bus assigned + WCHAR wszString[256]; + LPT_MYVM_PARAMETERS lpp; + float fff; + long vi, nu, nbstrip, nbbus, rep, updatebit=0; + long mask, monitorbus=-1; + +#ifdef _DEBUG + if (lpapp->vbvmr_pStripName == NULL) + { + return 0; + } + if (lpapp->vbvmr_pBUSName == NULL) + { + return 0; + } +#endif + + lpp = &(lpapp->current_param); + nbstrip=0; + nbbus = 0; + + for (vi=0;vivbvmr_nbbus; vi++) + { + lpp->bus[vi].bus_fMonitorSupport = lpapp->vbvmr_monitor_support; + strcpy(lpp->bus[vi].bus_nickname,lpapp->vbvmr_pBUSName[vi]); + // bus label + rep = GetCurrentBusLabel(vi, wszString); + if (rep >= 0) + { + if (wcscmp(wszString, lpp->bus[vi].bus_namew) != 0) + { + updatebit |= mask; + } + wcscpy(lpp->bus[vi].bus_namew, wszString); + } + // if the BUS is displayed + if ((lpp->bus[vi].bus_namew[0] != 0) || (vi==0)) + { + bus_assignbit[vi] = 0x10; + nbbus++; + } + // bus gain + rep = GetCurrentBusGain(vi, &fff); + if (rep >= 0) + { + if (fff != lpp->bus[vi].bus_gain) + { + updatebit |= mask; + } + lpp->bus[vi].bus_gain = fff; + } + // BUS SEL + if (lpapp->vbvmr_multilayer != 0) + { + rep=GetCurrentBusSel(vi, &fff); + if (rep >= 0) + { + if ((long)fff != lpp->bus[vi].bus_monitor) + { + updatebit |= mask; + } + lpp->bus[vi].bus_monitor = (long)fff; + } + } + else lpp->bus[vi].bus_monitor=0; + // Bus Mute + rep=GetCurrentBusMute(vi, &fff); + if (rep >= 0) + { + if ((long)fff != lpp->bus[vi].bus_mute) + { + updatebit |= mask; + } + lpp->bus[vi].bus_mute = (long)fff; + } + // Bus Monitor + rep=GetCurrentBusMonitor(vi, &fff); + if (rep >= 0) + { + if ((fff != 0.0f) && (monitorbus < 0)) + { + monitorbus = vi; + } + } + + mask=mask<<1; + } + // check monitoring options + if (lpapp->vbvmr_multilayer != 0) + { + // define what is the BUS monitoring + if (monitorbus != lpp->monitorbus) + { + lpp->monitorbus = monitorbus; + updatebit |= VMRS_BITMON; + } + //check bus monitoring option consistency (only one BUS can be monitored) + nu=0; + for (vi=0;vivbvmr_nbbus; vi++) + { + if (lpp->bus[vi].bus_monitor != 0) nu++; + } + //otherwise we consider there is no monitoring + if (nu > 1) + { + mask = VMRS_BITBUS; + for (vi=0;vivbvmr_nbbus; vi++) + { + if (lpp->bus[vi].bus_monitor != 0) updatebit |= mask; + lpp->bus[vi].bus_monitor =0; + } + mask=mask<<1; + } + } + // + //get parameters for strips + // + mask = VMRS_BITSTRIP; + for (vi=0;vivbvmr_nbstrip; vi++) + { + strcpy(lpp->strip[vi].strip_nickname,lpapp->vbvmr_pStripName[vi]); + // Strip label + rep = GetCurrentStripLabel(vi, wszString); + if (rep >= 0) + { + if (wcscmp(wszString, lpp->strip[vi].strip_namew) != 0) + { + updatebit |= mask; + } + wcscpy(lpp->strip[vi].strip_namew, wszString); + } + if (lpp->strip[vi].strip_namew[0] != 0) nbstrip++; + + // Strip Gain + if (lpapp->vbvmr_multilayer == 0) + { + rep = GetCurrentStripGain(vi, &fff); + if (rep >= 0) + { + if (fff != lpp->strip[vi].strip_gain[0]) + { + updatebit |= mask; + } + for (nu=0;nuvbvmr_nbbus;nu++) + lpp->strip[vi].strip_gain[nu] = fff; + } + } + else + { + for (nu=0;nuvbvmr_nbbus;nu++) + { + rep= GetCurrentStripGainLayer(vi, nu, &fff); + if (rep >= 0) + { + if (fff != lpp->strip[vi].strip_gain[nu]) + { + updatebit |= mask; + } + lpp->strip[vi].strip_gain[nu] = fff; + } + } + + } + + // bus assignation on the strip + lpp->strip[vi].strip_pBUSNameList = lpapp->vbvmr_pBUSName; + lpp->strip[vi].strip_nbBusDisplayed = nbbus; + lpp->strip[vi].strip_fMultiLayer = lpapp->vbvmr_multilayer; + + for (nu=0;nuvbvmr_nbbus;nu++) + { + c1=0; + rep= GetCurrentStripAssignation(vi, nu, &fff); + if (rep >= 0) + { + if (fff != 0) c1 = 0x01; + c2= lpp->strip[vi].strip_assignmentbit[nu] & 0x0F; + if (c1 != c2) + { + updatebit |= mask; + } + } + lpp->strip[vi].strip_assignmentbit[nu] = bus_assignbit[nu] | c1; + } + // Strip Mute + rep =GetCurrentStripMute(vi,&fff); + if (rep >= 0) + { + if (fff != lpp->strip[vi].strip_mute) + { + updatebit |= mask; + } + lpp->strip[vi].strip_mute = (long)fff; + } + mask=mask<<1; + } + + + //check if the number of strip to display is changed... + if (nbstrip != lpp->nbStrip) + { + updatebit |= VMRS_BITSTRIPNB; + lpp->nbStrip=nbstrip; + } + //check if the number of bus to display is changed... + if (nbbus != lpp->nbBus) + { + updatebit |= VMRS_BITBUSNB; + lpp->nbBus=nbbus; + } + return updatebit; +} + + +void UpdateAllPeakMeters(LPT_APP_CONTEXT lpapp) +{ + float dBlevel; + long nu, *pChannel, nuChannel, nc, nbMax; + T_VMSCTL_RT_DATA rtData; + + //update peak meters for all STRIP + pChannel= lpapp->vbvmr_pStripChannel; + nuChannel=0; + for (nu=0;nuvbvmr_nbstrip;nu++) + { + nbMax=pChannel[nu]; // get number of channel per Strip + for (nc = 0; nc hw_StripList[nu], &rtData); + } + + //update peak meters for all BUS + nuChannel =0; + for (nu=0;nuvbvmr_nbbus;nu++) + { + for (nc = 0; nc <8; nc++) // always 8 channel per Bus + { + GetCurrentLevelDB(3, nuChannel, &dBlevel); + rtData.dbLevel[nc] = dBlevel; + nuChannel++; + } + VMSCTL_SetRTDataBUS(lpapp->hw_BusList[nu], &rtData); + } +} + + + + +/*******************************************************************************/ +/* DISPLAY FUNCTIONS */ +/*******************************************************************************/ + +void DrawVMConnectionMode(LPT_APP_CONTEXT lpapp, HDC dc) +{ + HBRUSH oldbrush; + HPEN oldpen; + HFONT oldfont; + char sz1[128]; + char sss[256]; + RECT rect; + rect=lpapp->rect_VMConnectionType; + + oldpen = (HPEN)SelectObject(dc,lpapp->gdiobjects_blue0.pen); + oldbrush = (HBRUSH)SelectObject(dc,lpapp->gdiobjects_bkg.brush); + oldfont = (HFONT)SelectObject(dc,lpapp->font1); + SetBkMode(dc,TRANSPARENT); + SetTextColor(dc,RGB(255,255,255)); + if (lpapp->vbvmr_connect == 0) SetTextColor(dc,RGB(200,0,0)); + + RoundRect(dc,rect.left,rect.top,rect.right,rect.bottom,7,7); + + if (lpapp->VMConnectionType == 0) strcpy(sz1,"Direct"); + else + { + if (lpapp->VBANisConnected == FALSE) SetTextColor(dc,RGB(200,0,0)); + sprintf(sz1,"VBAN #%i", lpapp->VMConnectionType); + } + strcpy(sss,"Connection: "); + strcat(sss,sz1); + + DrawText(dc,sss,(int)strlen(sss),&rect,DT_SINGLELINE | DT_CENTER | DT_VCENTER); + + SelectObject(dc,oldpen); + SelectObject(dc,oldbrush); + SelectObject(dc,oldfont); +} + +void DrawSliderMode(LPT_APP_CONTEXT lpapp, HDC dc) +{ + HBRUSH oldbrush; + HPEN oldpen; + HFONT oldfont; + char sss[128]; + RECT rect; + rect=lpapp->rect_SliderMode; + + oldpen = (HPEN)SelectObject(dc,lpapp->gdiobjects_blue0.pen); + oldbrush = (HBRUSH)SelectObject(dc,lpapp->gdiobjects_blue0.brush); + oldfont = (HFONT)SelectObject(dc,lpapp->font1); + SetBkMode(dc,TRANSPARENT); + SetTextColor(dc,RGB(255,255,255)); + + RoundRect(dc,rect.left,rect.top,rect.right,rect.bottom,7,7); + + strcpy(sss,"NO Link"); + if (lpapp->StripSliderMode == SLIDERLINKMODE_ABSLINK) strcpy(sss,"ABS Link"); + if (lpapp->StripSliderMode == SLIDERLINKMODE_RELLINK) strcpy(sss,"REL Link"); + + DrawText(dc,sss,(int)strlen(sss),&rect,DT_SINGLELINE | DT_CENTER | DT_VCENTER); + + SelectObject(dc,oldpen); + SelectObject(dc,oldbrush); + SelectObject(dc,oldfont); +} + +void DrawAllStuff(LPT_APP_CONTEXT lpapp, HWND hw, HDC dc) +{ + char sss[512]; + long nBus, xCenter; + long x0,y0,dx,dy; + RECT rect; + HBRUSH oldbrush; + HPEN oldpen; + HFONT oldfont; + + oldpen = (HPEN)SelectObject(dc,lpapp->gdiobjects_blue0.pen); + oldbrush = (HBRUSH)SelectObject(dc,lpapp->gdiobjects_blue2.brush); + oldfont = (HFONT)SelectObject(dc,lpapp->font2); + SetBkMode(dc,TRANSPARENT); + SetTextColor(dc,RGB(0,0,0)); + + rect=lpapp->rect_inputs; + dx=(rect.right-rect.left) / 8; + dy = rect.bottom-rect.top; + x0=rect.left; + y0=rect.top; + + nBus=lpapp->vbvmr_nbbus; + if (nBus < 2) + { + if (lpapp->VMConnectionType == 0) strcpy(sss,"Voicemeeter is not running..."); + else sprintf(sss,"Voicemeeter is not responding on VBAN #%i", lpapp->VMConnectionType); + Rectangle(dc,rect.left,rect.top,rect.right,rect.bottom); + DrawText(dc,sss,(long)strlen(sss),&rect,DT_SINGLELINE | DT_VCENTER | DT_CENTER); + } + else + { + SelectObject(dc,lpapp->gdiobjects_bkg.pen); + SelectObject(dc,lpapp->gdiobjects_bkg.brush); + SetTextColor(dc,lpapp->gdiobjects_blue2.color); + SelectObject(dc,lpapp->font1); + // Display STRIP LABEL + if (lpapp->current_param.nbStrip < 1) + { + strcpy(sss,"Label Voicemeeter Strip you want to see in the INPUTS section..."); + Rectangle(dc,rect.left,rect.top,rect.right,rect.bottom); + DrawText(dc,sss,(long)strlen(sss),&rect,DT_SINGLELINE | DT_VCENTER | DT_LEFT); + + } + else + { + strcpy(sss,"INPUT STRIP"); + Rectangle(dc,rect.left,rect.top,rect.right,rect.bottom); + DrawText(dc,sss,(long)strlen(sss),&rect,DT_SINGLELINE | DT_VCENTER | DT_LEFT); + lpapp->rect_VMConnectionType = rect; + + // display Strip slider mode + lpapp->rect_SliderMode.left=rect.right; + lpapp->rect_SliderMode.top=0; + if (lpapp->vbvmr_multilayer != 0) + { + + strcpy(sss,"Slider Mode:"); + rect.left = rect.right - 72- SLIDERLINKMODE_DX-10; + if (rect.left < 120) rect.left=120; + rect.right = rect.left+300; + + DrawText(dc,sss,(long)strlen(sss),&rect,DT_SINGLELINE | DT_VCENTER | DT_LEFT); + + rect.top+=2; + rect.bottom-=2; + lpapp->rect_SliderMode = rect; + lpapp->rect_SliderMode.left +=80; + lpapp->rect_SliderMode.right= lpapp->rect_SliderMode.left+SLIDERLINKMODE_DX; + + DrawSliderMode(lpapp, dc); + + } + // display connection type + lpapp->rect_VMConnectionType.left =100; + lpapp->rect_VMConnectionType.right=lpapp->rect_SliderMode.left-100; + if ((lpapp->rect_VMConnectionType.right - lpapp->rect_VMConnectionType.left) > 140) + { + xCenter = ((lpapp->rect_VMConnectionType.left +lpapp->rect_VMConnectionType.right)>>1); + lpapp->rect_VMConnectionType.left =xCenter-70; + lpapp->rect_VMConnectionType.right=xCenter+70; + DrawVMConnectionMode(lpapp, dc); + } + + } + // Display BUS LABEL + SetTextColor(dc,lpapp->gdiobjects_blue2.color); + rect=lpapp->rect_outputs; + strcpy(sss,"OUTPUT BUS"); + Rectangle(dc,rect.left,rect.top,rect.right,rect.bottom); + DrawText(dc,sss,(long)strlen(sss),&rect,DT_SINGLELINE | DT_VCENTER | DT_LEFT); + if (lpapp->vbvmr_multilayer != 0) + { + rect.left = rect.right - 110; + if (rect.left < 120) rect.left=120; + strcpy(sss,"Monitor BUS: "); + if (lpapp->vbvmr_monitor_support == 0) strcat(sss, "OFF"); + else + { + if (lpapp->current_param.monitorbus >=0) + { + nBus = (lpapp->current_param.monitorbus) & 0x00000007; + if (lpapp->vbvmr_pBUSName != NULL) strcat(sss,lpapp->vbvmr_pBUSName[nBus]); + else strcat(sss, "OFF"); + } + else strcat(sss, "OFF"); + } + DrawText(dc,sss,(long)strlen(sss),&rect,DT_SINGLELINE | DT_VCENTER | DT_LEFT); + } + } + SelectObject(dc,oldpen); + SelectObject(dc,oldbrush); + SelectObject(dc,oldfont); +} + + + + +/*******************************************************************************/ +/* USER ACTIONS MANAGEMENT */ +/*******************************************************************************/ + +#define APP_ZONE_SLIDERMODE 100 + + +long APP_WhereAmI(LPT_APP_CONTEXT lpapp, long x0, long y0, long * pnuOut, long * pnuIn) +{ + RECT rect; + + if (lpapp->vbvmr_multilayer != 0) + { + rect= lpapp->rect_SliderMode; + if ((x0>=rect.left) && (x0<=rect.right) && (y0>=rect.top) && (y0<=rect.bottom)) return APP_ZONE_SLIDERMODE; + } + return -1; +} + +void APP_ManageLRButtonDown(LPT_APP_CONTEXT lpapp, HWND hw, long x0, long y0, long fRightClick) +{ + HDC dc; + long rep, nuIn,nuOut; + rep= APP_WhereAmI(lpapp, x0, y0, &nuOut, &nuIn); + if (rep <0) return; + + switch(rep) + { + case APP_ZONE_SLIDERMODE: + lpapp->StripSliderMode++; + if (lpapp->StripSliderMode > 2) lpapp->StripSliderMode=0; + dc=GetDC(hw); + DrawSliderMode(lpapp, dc); + ReleaseDC(hw,dc); + break; + } +} + + +/*******************************************************************************/ +/* Init / End Software */ +/*******************************************************************************/ + + +long DetectVoicemeeterType(LPT_APP_CONTEXT lpapp, HWND hw) +{ + char szParam[128]; + long rep,vmType; + + lpapp->vbvmr_nbbus =0; + lpapp->vbvmr_nbstrip =0; + lpapp->vbvmr_multilayer =0; + lpapp->vbvmr_monitor_support=0; + + rep = GetCurrentVoicemeeterType(&vmType); + if (rep == 0) + { + rep=GetCurrentVoicemeeterVersion(&(lpapp->vbvmr_version)); + if (lpapp->vbvmr_connect != vmType) + { + lpapp->vbvmr_connect =vmType; + switch(vmType) + { + case 1://Voicemeeter + lpapp->vbvmr_nbbus =2; + lpapp->vbvmr_nbstrip =3; + lpapp->vbvmr_pBUSName =G_szBUSNameList_v1; + lpapp->vbvmr_pStripName =G_szStripNameList_v1; + lpapp->vbvmr_pStripChannel =G_nbChannelPerStrip_v1; + break; + case 2://Voicemeeter Banana + lpapp->vbvmr_nbbus =5; + lpapp->vbvmr_nbstrip =5; + lpapp->vbvmr_pBUSName =G_szBUSNameList_v2; + lpapp->vbvmr_pStripName =G_szStripNameList_v2; + lpapp->vbvmr_pStripChannel =G_nbChannelPerStrip_v2; + break; + case 3://Voicemeeter 8 + lpapp->vbvmr_nbbus =8; + lpapp->vbvmr_nbstrip =8; + lpapp->vbvmr_multilayer =1; + lpapp->vbvmr_pBUSName =G_szBUSNameList_v3; + lpapp->vbvmr_pStripName =G_szStripNameList_v3; + lpapp->vbvmr_pStripChannel =G_nbChannelPerStrip_v3; + if (lpapp->vbvmr_version >= 0x02000109) + { + // we activate the Monitor on SEL option + strcpy(szParam,"Option.MonitorOnSEL"); + rep=SendParameterToVoicemeeter(szParam, 1.0f); + if (rep >= 0) + { + lpapp->vbvmr_monitor_support=1; + } + } + break; + } + return 1; + } + } + return 0; +} + + + +BOOL InitSoftware(LPT_APP_CONTEXT lpapp, HWND hw) +{ + char szTitle[]="Init Error"; + long rep; + + //init context + lpapp->hwnd_MainWindow = hw; + lpapp->vbvmr_connect=0; + + //init resources + InitResources(lpapp); + + //get DLL interface for Voicemeeter remote API (local use) + //the VM Streamer View can work with Voicemeeter Dll + lpapp->vbvmr_NotInstalled=0; + rep=InitializeDLLInterfaces(); + if (rep >= 0) + { + //Log in + rep=iVMR.VBVMR_Login(); + if (rep < 0) + { + MessageBox(hw,"Failed To Login",szTitle,MB_APPLMODAL | MB_OK | MB_ICONERROR); + lpapp->vbvmr_NotInstalled=1; + } + //call this to get first parameters state (if server already launched) + lpapp->vbvmr_error = iVMR.VBVMR_IsParametersDirty(); + if (lpapp->vbvmr_error == 0) + { + DetectVoicemeeterType(lpapp, hw); + AnalyseParamChange(lpapp); + } + } + else lpapp->vbvmr_NotInstalled=1; + // we return always true, because the application can work with VBAN connection only + return TRUE; +} + +BOOL EndSoftware(LPT_APP_CONTEXT lpapp, HWND hw) +{ + VBANCMD_StopThread(); + if (iVMR.VBVMR_Logout != NULL) iVMR.VBVMR_Logout(); + EndResources(lpapp); + return TRUE; +} + + + +void ManageMenu(LPT_APP_CONTEXT lpapp, HWND hw, WPARAM wparam, LPARAM lparam) +{ + switch(LOWORD(wparam)) + { + case IDM_UPDATE_ALL_CONTROL: + UpdateAllControl(lpapp, VMRS_BITALL); + break; + + } +} + + +/*******************************************************************************/ +/* CONTROLS CALLBACK */ +/*******************************************************************************/ + +void __stdcall APP_InputCtlCallback(void * lpuser,long Ident, long ICtl, float value) +{ + float delta, vvv; + char szParam[128], c1, bus_assignbit; + long rep,nuStrip, nuVisibleSlider, index, nu; + LPT_MYVM_PARAMETERS lpp; + LPT_APP_CONTEXT lpapp; + lpapp=(LPT_APP_CONTEXT)lpuser; + lpp = &(lpapp->current_param); + nuStrip = Ident; + + // from gain slider (8 possible slider + if ((ICtl >= VMSCTL_STRIP_ID_GAIN) && (ICtl < (VMSCTL_STRIP_ID_GAIN + VMSCTL_MAX_NBBUS))) + { + nuVisibleSlider = ICtl - VMSCTL_STRIP_ID_GAIN; + index = VMSCTL_GetIndexSTRIP(lpapp->hw_StripList[nuStrip],nuVisibleSlider); + + // no multi layer + if (lpapp->vbvmr_multilayer == 0) + { + sprintf(szParam,"Strip[%i].Gain", nuStrip); + rep=SendParameterToVoicemeeter(szParam, value); + if (rep >= 0) + { + for (nu=0;nuvbvmr_nbbus;nu++) + lpp->strip[nuStrip].strip_gain[nu] = value; + } + VMSCTL_SetDataSTRIP(lpapp->hw_StripList[nuStrip], &(lpp->strip[nuStrip]), FALSE); + } + // multi layer + else + { + delta=0.0f; + sprintf(szParam,"Strip[%i].GainLayer[%i]", nuStrip, index); + rep=SendParameterToVoicemeeter(szParam, value); + if (rep >= 0) + { + delta= value-lpp->strip[nuStrip].strip_gain[index]; + lpp->strip[nuStrip].strip_gain[index] = value; + } + switch(lpapp->StripSliderMode) + { + case SLIDERLINKMODE_ABSLINK: // absolute link = all slider get the same value + for (nu=0;nuvbvmr_nbbus;nu++) + { + // we update other slider / visible on the strip + if ((nu != index) && ((lpp->strip[nuStrip].strip_assignmentbit[nu] & 0xF0) != 0)) + { + sprintf(szParam,"Strip[%i].GainLayer[%i]", nuStrip, nu); + rep=SendParameterToVoicemeeter(szParam, value); + if (rep >= 0) + { + lpp->strip[nuStrip].strip_gain[nu] = value; + } + } + } + VMSCTL_SetDataSTRIP(lpapp->hw_StripList[nuStrip], &(lpp->strip[nuStrip]), FALSE); + break; + case SLIDERLINKMODE_RELLINK:// relative link = all slider are moved by the same amount (delta) + for (nu=0;nuvbvmr_nbbus;nu++) + { + // we update other slider / visible on the strip + if ((nu != index) && ((lpp->strip[nuStrip].strip_assignmentbit[nu] & 0xF0) != 0)) + { + vvv = lpp->strip[nuStrip].strip_gain[nu] + delta; + sprintf(szParam,"Strip[%i].GainLayer[%i]", nuStrip, nu); + rep=SendParameterToVoicemeeter(szParam, vvv); + if (rep >= 0) + { + lpp->strip[nuStrip].strip_gain[nu] = vvv; + } + } + } + VMSCTL_SetDataSTRIP(lpapp->hw_StripList[nuStrip], &(lpp->strip[nuStrip]), FALSE); + break; + } + } + return; + } + // from BUS Assignation button + if ((ICtl >= VMSCTL_STRIP_ID_ASSIGN) && (ICtl < (VMSCTL_STRIP_ID_ASSIGN + VMSCTL_MAX_NBBUS))) + { + nuVisibleSlider = ICtl - VMSCTL_STRIP_ID_ASSIGN; + index = VMSCTL_GetIndexSTRIP(lpapp->hw_StripList[nuStrip],nuVisibleSlider); + + if ((index >=0) && (lpapp->vbvmr_pBUSName!=NULL)) + { + sprintf(szParam,"Strip[%i].%s", nuStrip, lpapp->vbvmr_pBUSName[index]); + rep=SendParameterToVoicemeeter(szParam, value); + if (rep >= 0) + { + c1=0x00; + bus_assignbit = lpp->strip[nuStrip].strip_assignmentbit[index] & 0xF0; + if (value != 0.0f) c1=0x01; + lpp->strip[nuStrip].strip_assignmentbit[index] = bus_assignbit | c1; + } + } + return; + } + + // other sub control + switch(ICtl) + { + case VMSCTL_STRIP_ID_MUTE: + sprintf(szParam,"Strip[%i].Mute", nuStrip); + rep=SendParameterToVoicemeeter(szParam, value); // set value in Voicemeeter + if (rep >= 0) lpp->strip[nuStrip].strip_mute = (long)value; // update internal parameters. + break; + } +} + +void __stdcall APP_OutputCtlCallback(void * lpuser,long Ident, long ICtl, float value) +{ + char szParam[128]; + LPT_MYVM_PARAMETERS lpp; + long rep,nuBus, vi; + LPT_APP_CONTEXT lpapp; + lpapp=(LPT_APP_CONTEXT)lpuser; + lpp = &(lpapp->current_param); + nuBus = Ident; + switch(ICtl) + { + // From Mute button + case VMSCTL_BUS_ID_MUTE: + sprintf(szParam,"Bus[%i].Mute", nuBus); + rep=SendParameterToVoicemeeter(szParam, value); // set value in Voicemeeter + if (rep >= 0) lpp->bus[nuBus].bus_mute = (long)value; // update internal parameters. + break; + // From Gain Slider + case VMSCTL_BUS_ID_GAIN: + sprintf(szParam,"Bus[%i].Gain", nuBus); + rep=SendParameterToVoicemeeter(szParam, value); // set value in Voicemeeter + if (rep >= 0) lpp->bus[nuBus].bus_gain = value; // update internal parameters. + break; + // from monitor + case VMSCTL_BUS_ID_MONITOR: + sprintf(szParam,"Bus[%i].Sel", nuBus); + rep=SendParameterToVoicemeeter(szParam, value); // set value in Voicemeeter + if (rep >= 0) + { + lpp->bus[nuBus].bus_monitor = (long)value; // update internal parameters. + if (value != 0.0) + { + // Remove all other SEL (Monitor = exclusive SEL) + for (vi=0;vivbvmr_nbbus;vi++) + { + if (vi != nuBus) + { + sprintf(szParam,"Bus[%i].Sel", vi); + rep=SendParameterToVoicemeeter(szParam, 0.0f); + if (rep >= 0) + { + lpp->bus[nuBus].bus_monitor=0; + VMSCTL_SetDataBUS(lpapp->hw_BusList[vi], &(lpp->bus[vi]), FALSE); + } + } + } + } + } + break; + } +} + + + +/*******************************************************************************/ +/* CONTROLS */ +/*******************************************************************************/ + +static long CreateAllControls(LPT_APP_CONTEXT lpapp, HWND hParent) +{ + T_VMSCTL_STRIPPARAM param_strip; + T_VMSCTL_BUSPARAM param_bus; + long vi; + + // Create all STRIP Control + memset(¶m_strip, 0, sizeof(T_VMSCTL_STRIPPARAM)); + + param_strip.vmin =-60.0f; + param_strip.vmax =+12.0f; + + param_strip.font0 =lpapp->font0; + param_strip.font1 =lpapp->font1; + param_strip.font2 =lpapp->font2; + param_strip.bkg0_brush =lpapp->gdiobjects_bkg.brush; + param_strip.bkg1_brush =lpapp->gdiobjects_bkg_ctl.brush; + + param_strip.lpCallback =APP_InputCtlCallback; + param_strip.lpuser =lpapp; + + param_strip.assignbus_pen =lpapp->gdiobjects_blue1.pen; + param_strip.assignbus_color =lpapp->gdiobjects_blue1.color; + param_strip.name_color =lpapp->gdiobjects_white.color; + param_strip.meter_brush1 =lpapp->gdiobjects_meter_blue.brush; + param_strip.meter_brush2 =lpapp->gdiobjects_meter_green.brush; + param_strip.meter_brush3 =lpapp->gdiobjects_meter_red.brush; + + param_strip.slider_pen_green =lpapp->gdiobjects_slidergreen.pen; + param_strip.slider_brush_green =lpapp->gdiobjects_slidergreen.brush; + param_strip.slider_pen_red =lpapp->gdiobjects_sliderred.pen; + param_strip.slider_brush_red =lpapp->gdiobjects_sliderred.brush; + + param_strip.mutered_color =lpapp->gdiobjects_mute.color; + param_strip.mutered_pen =lpapp->gdiobjects_mute.pen; + param_strip.assigned_color =lpapp->gdiobjects_slidergreen.color; + param_strip.assigned_pen =lpapp->gdiobjects_slidergreen.pen; + + + for (vi=0;vihw_StripList[vi] = VMSCTL_CreateSTRIP(hParent, vi, 10,10, ¶m_strip); + } + + + // Create all BUS Control + memset(¶m_bus, 0, sizeof(T_VMSCTL_STRIPPARAM)); + + param_bus.vmin =-60.0f; + param_bus.vmax =+12.0f; + + param_bus.font0 =lpapp->font0; + param_bus.font1 =lpapp->font1; + param_bus.font2 =lpapp->font2; + param_bus.bkg0_brush =lpapp->gdiobjects_bkg.brush; + param_bus.bkg1_brush =lpapp->gdiobjects_bkg_ctl.brush; + param_bus.assignbus_pen =lpapp->gdiobjects_blue1.pen; + param_bus.assignbus_color=lpapp->gdiobjects_blue1.color; + param_bus.name_color =lpapp->gdiobjects_white.color; + param_bus.meter_brush1 =lpapp->gdiobjects_meter_blue.brush; + param_bus.meter_brush2 =lpapp->gdiobjects_meter_green.brush; + param_bus.meter_brush3 =lpapp->gdiobjects_meter_red.brush; + + param_bus.slider_pen_green =lpapp->gdiobjects_slidergreen.pen; + param_bus.slider_brush_green=lpapp->gdiobjects_slidergreen.brush; + param_bus.slider_pen_red =lpapp->gdiobjects_sliderred.pen; + param_bus.slider_brush_red =lpapp->gdiobjects_sliderred.brush; + + param_bus.mutered_color =lpapp->gdiobjects_mute.color; + param_bus.mutered_pen =lpapp->gdiobjects_mute.pen; + + param_bus.monitor_brush =lpapp->gdiobjects_monitor.brush; + param_bus.monitor_pen =lpapp->gdiobjects_monitor.pen; + + param_bus.lpCallback =APP_OutputCtlCallback; + param_bus.lpuser =lpapp; + + for (vi=0;vihw_BusList[vi]; + lpapp->hw_BusList[vi] = VMSCTL_CreateBUS(hParent, vi, 10,10, ¶m_bus); + + } + return 0; +} + + +static void DestroyAllControls(LPT_APP_CONTEXT lpapp) +{ + long vi; + for (vi=0;vihw_StripList[vi] != NULL) DestroyWindow(lpapp->hw_StripList[vi]); + lpapp->hw_StripList[vi]=NULL; + + } + for (vi=0;vihw_BusList[vi] != NULL) DestroyWindow(lpapp->hw_BusList[vi]); + lpapp->hw_BusList[vi]=NULL; + } +} + +#define APP_MARGIN 10 +#define APP_SECTIONLABEL 25 + +static void APP_RecomputeLayout(LPT_APP_CONTEXT lpapp, long dx, long dy) +{ + RECT rect; + LPT_MYVM_PARAMETERS lpp; + long fShow; + long vi, x0, y0; + long nbStrip, nbBus; + long dx_strip, dy_strip; + long dx_bus, dy_bus; + long fRecompute = 0; + if ((dx == 0) || (dy == 0)) fRecompute=1; + if (dx > 0) + { + if (lpapp->hw_dx !=dx) fRecompute=1; + lpapp->hw_dx =dx; + } + else dx = lpapp->hw_dx; + if (dy > 0) + { + if (lpapp->hw_dy !=dy) fRecompute=1; + lpapp->hw_dy =dy; + } + else dy = lpapp->hw_dy; + if (fRecompute == 0) return; + + rect.left=APP_MARGIN; + rect.right=dx-APP_MARGIN; + rect.top=APP_MARGIN; + rect.bottom=dy-APP_MARGIN; + + dx=dx-APP_MARGIN; + dy=dy-APP_MARGIN; + lpp = &(lpapp->current_param); + nbStrip =lpp->nbStrip; + nbBus =lpp->nbBus; + + dx_bus = dx-APP_MARGIN; + dy_bus = 40; + if (nbStrip > 0) dx_strip = dx / nbStrip; + else dx_strip=dx; + dy_strip = dy - (dy_bus*nbBus) - APP_SECTIONLABEL - APP_SECTIONLABEL-APP_MARGIN-APP_MARGIN; + + lpapp->rect_inputs=rect; + lpapp->rect_inputs.bottom=lpapp->rect_inputs.top+APP_SECTIONLABEL; + + lpapp->rect_outputs=rect; + lpapp->rect_outputs.top += APP_SECTIONLABEL + dy_strip+APP_MARGIN; + lpapp->rect_outputs.bottom=lpapp->rect_outputs.top+APP_SECTIONLABEL; + + //position strip + x0 = APP_MARGIN; + y0 = APP_MARGIN+APP_SECTIONLABEL+10; + dy_strip -=10; + for (vi = 0; vi < VMSCTL_MAX_NBSTRIP; vi++) + { + if (lpp->strip[vi].strip_namew[0] != 0) + { + fShow=1; + } + else fShow=0; + VMSCTL_PositionSTRIP(lpapp->hw_StripList[vi], x0,y0, dx_strip-APP_MARGIN, dy_strip, fShow); + if (fShow != 0) x0=x0+dx_strip; + } + + //position bus + x0 = APP_MARGIN; + y0 = lpapp->rect_outputs.bottom+10; + for (vi = 0; vi < VMSCTL_MAX_NBBUS; vi++) + { + if ((lpp->bus[vi].bus_namew[0] != 0) || (vi==0)) + { + fShow=1; + } + else fShow=0; + VMSCTL_PositionBUS(lpapp->hw_BusList[vi], x0,y0, dx_bus, dy_bus-APP_MARGIN, fShow); + if (fShow != 0) y0=y0+dy_bus; + } +} + +static void APP_ResetData(LPT_APP_CONTEXT lpapp) +{ + long vi; + memset(&(lpapp->current_param), 0 , sizeof(T_MYVM_PARAMETERS )); //reset parameters + for (vi = 0; vi < VMSCTL_MAX_NBSTRIP; vi++) + { + VMSCTL_ResetDataSTRIP(lpapp->hw_StripList[vi]); + } + for (vi = 0; vi < VMSCTL_MAX_NBBUS; vi++) + { + VMSCTL_ResetDataBUS(lpapp->hw_BusList[vi]); + } +} + + + +/*******************************************************************************/ +/* WIN CALLBACK */ +/*******************************************************************************/ + +#define MYTIMERID 16489 + +static void StartVBANConnection(LPT_APP_CONTEXT lpapp, HWND hw, long nuVBAN) +{ + LPT_VBAN_CMD_PARAM lpVBANParam; + lpVBANParam = &(lpapp->VMLinkVBAN[nuVBAN]); + VBANCMD_StartThread(lpVBANParam->VBAN_szStreamName, lpVBANParam->VBAN_szIPAddress, (unsigned short)lpVBANParam->VBAN_UDPport); + lpapp->VMConnectionType =nuVBAN+1; + // send request to register for RT-Packet. + VBANCMD_SendRequest_RegisterRTPacket(15, "VMStreamerView"); + //disconnect to force reconnection + lpapp->vbvmr_connect =0; + if (hw != NULL) InvalidateRect(hw,NULL,TRUE); +} + + +LRESULT CALLBACK MainWindowManageEvent(HWND hw, //handle of the window. + UINT msg, //Message Ident. + WPARAM wparam, //parameter 1. + LPARAM lparam) //parameter 2 +{ + HMENU sysmenu; + HPEN oldpen; + HBRUSH oldbrush; + RECT rect; + long dx,dy, nChange, nNewLogin, fUpdatePaint; + long nCommand, nuVBAN; + BOOL LastConnectedState; + DWORD ms, delta, nnn; + LPT_APP_CONTEXT lpapp; + HDC dc; + PAINTSTRUCT ps; + + lpapp = &G_MainAppCtx; + switch (msg) + { + + + case WM_CREATE: + if (InitSoftware(lpapp,hw) == FALSE) return -1;//return -1 here cancel the window creation + CreateAllControls(lpapp, hw); + + // add item in system menu + sysmenu=GetSystemMenu(hw,FALSE); + if (sysmenu != NULL) + { + AppendMenu(sysmenu,MF_SEPARATOR,0,NULL); + AppendMenu(sysmenu,MF_STRING,IDMSYS_LINK_DIRECT,"Direct Connection"); + AppendMenuA(sysmenu,MF_STRING,IDMSYS_LINK_VBAN1,"VBAN #1 Connection"); + AppendMenuA(sysmenu,MF_STRING,IDMSYS_LINK_VBAN2,"VBAN #2 Connection"); + AppendMenuA(sysmenu,MF_STRING,IDMSYS_LINK_VBAN3,"VBAN #3 Connection"); + AppendMenuA(sysmenu,MF_STRING,IDMSYS_LINK_VBAN4,"VBAN #4 Connection"); + AppendMenu(sysmenu,MF_SEPARATOR,0,NULL); + AppendMenuA(sysmenu,MF_STRING,IDMSYS_VBAN_CONFIG,"VBAN Configuration..."); + } + PostMessage(hw,WM_COMMAND, IDM_UPDATE_ALL_CONTROL,0); + lpapp->wTimer = SetTimer(hw,MYTIMERID, 30,NULL);//30 Hz timer + + if (lpapp->VMConnectionType > 0) + { + StartVBANConnection(lpapp, NULL, lpapp->VMConnectionType-1); + } + break; + case WM_INITMENU: + sysmenu = GetSystemMenu(hw,FALSE); + if (sysmenu != NULL) + { + if (lpapp->VMConnectionType == 0) CheckMenuItem(sysmenu, IDMSYS_LINK_DIRECT, MF_BYCOMMAND | MF_CHECKED); + else CheckMenuItem(sysmenu, IDMSYS_LINK_DIRECT, MF_BYCOMMAND | MF_UNCHECKED); + if (lpapp->VMConnectionType == 1) CheckMenuItem(sysmenu, IDMSYS_LINK_VBAN1, MF_BYCOMMAND | MF_CHECKED); + else CheckMenuItem(sysmenu, IDMSYS_LINK_VBAN1, MF_BYCOMMAND | MF_UNCHECKED); + if (lpapp->VMConnectionType == 2) CheckMenuItem(sysmenu, IDMSYS_LINK_VBAN2, MF_BYCOMMAND | MF_CHECKED); + else CheckMenuItem(sysmenu, IDMSYS_LINK_VBAN2, MF_BYCOMMAND | MF_UNCHECKED); + if (lpapp->VMConnectionType == 3) CheckMenuItem(sysmenu, IDMSYS_LINK_VBAN3, MF_BYCOMMAND | MF_CHECKED); + else CheckMenuItem(sysmenu, IDMSYS_LINK_VBAN3, MF_BYCOMMAND | MF_UNCHECKED); + if (lpapp->VMConnectionType == 4) CheckMenuItem(sysmenu, IDMSYS_LINK_VBAN4, MF_BYCOMMAND | MF_CHECKED); + else CheckMenuItem(sysmenu, IDMSYS_LINK_VBAN4, MF_BYCOMMAND | MF_UNCHECKED); + } + break; + case WM_LBUTTONDOWN: + APP_ManageLRButtonDown(lpapp, hw, (short int)LOWORD(lparam),(short int)HIWORD(lparam),0); + break; + case WM_SIZE: + dx=(short)LOWORD(lparam); + dy=(short)HIWORD(lparam); + APP_RecomputeLayout(lpapp, dx,dy); + break; + + case WM_COMMAND: + ManageMenu(lpapp,hw,wparam,lparam); + break; + + case WM_SYSCOMMAND: + nCommand = LOWORD(wparam); + switch(nCommand) + { + case IDMSYS_VBAN_CONFIG: + VBANDIALOG_DialogGo(hw,0); + break; + case IDMSYS_LINK_DIRECT: + if (lpapp->VMConnectionType == 0) break; + VBANCMD_StopThread(); + lpapp->VMConnectionType =0; + //disconnect to force reconnection + lpapp->vbvmr_connect =0; + InvalidateRect(hw,NULL,TRUE); + break; + case IDMSYS_LINK_VBAN1: + case IDMSYS_LINK_VBAN2: + case IDMSYS_LINK_VBAN3: + case IDMSYS_LINK_VBAN4: + nuVBAN = nCommand-IDMSYS_LINK_VBAN1; + if (lpapp->VMConnectionType == (nuVBAN+1)) break; + StartVBANConnection(lpapp, hw, nuVBAN); + break; + + default: + return DefWindowProc(hw,msg,wparam,lparam); + } + break; + case WM_TIMER: + if (wparam == MYTIMERID) + { + ms = GetTickCount(); + + // if direct connection + if ((lpapp->VMConnectionType == 0) && (lpapp->vbvmr_NotInstalled == 0)) + { + //check what is changed + lpapp->vbvmr_error=iVMR.VBVMR_IsParametersDirty(); + } + // if VBAN connection + else + { + // every 1 seconds + delta = TOOL_GetDeltaMsDword(lpapp->msLastTimeForVBANCheck, ms); + if (delta > 1000) + { + LastConnectedState = lpapp->VBANisConnected; + nnn = VBANCMD_GetIncomingRequestCounter(); + if (nnn != lpapp->LastCounter) lpapp->VBANisConnected=TRUE; + else lpapp->VBANisConnected=FALSE; + lpapp->LastCounter = nnn; + lpapp->msLastTimeForVBANCheck = ms; + // if the VBAN connection is changed, we update the display + if (LastConnectedState != lpapp->VBANisConnected) + { + dc=GetDC(hw); + DrawVMConnectionMode(lpapp, dc); + ReleaseDC(hw,dc); + } + } + // every 10 seconds + delta = TOOL_GetDeltaMsDword(lpapp->msLastTimeForVBANRegister, ms); + if (delta > 10000) + { + // we ask for 15 second timeout = we will get RT-Packet for 15 seconds + VBANCMD_SendRequest_RegisterRTPacket(15, "VMStreamerView"); + lpapp->msLastTimeForVBANRegister = ms; + } + lpapp->vbvmr_error=VBANCMD_IsParameterDirty(); + } + // manage behavior + if (lpapp->vbvmr_error >= 0) + { + //if not already connected we detect Voicemeeter type + nNewLogin=0; + if (lpapp->vbvmr_connect == 0) + { + nNewLogin = DetectVoicemeeterType(lpapp, hw); + if (nNewLogin != 0) APP_ResetData(lpapp); + } + //if param change + if ((lpapp->vbvmr_error == 1) || (nNewLogin != 0)) + { + fUpdatePaint=0; + nChange=AnalyseParamChange(lpapp); + if (nNewLogin != 0) nChange=VMRS_BITALL; + //if layout change + if ((nChange & (VMRS_BITSTRIPNB | VMRS_BITBUSNB)) != 0) + { + APP_RecomputeLayout(lpapp, 0,0); + fUpdatePaint=1; + } + if ((nChange & VMRS_BITMON) != 0) fUpdatePaint=1; + if (nChange != 0) + { + UpdateAllControl(lpapp, nChange); + if (fUpdatePaint != 0) InvalidateRect(hw,NULL,FALSE); + } + } + } + // otherwise we consider it's not connected + else + { + // manage disconnection + if (lpapp->vbvmr_connect != 0) + { + //Voicemeeter has been shut down / disconnected + lpapp->vbvmr_connect =0; + InvalidateRect(hw,NULL,TRUE); + } + } + //Peak Meter display + if (lpapp->vbvmr_connect != 0) UpdateAllPeakMeters(lpapp); + } + break; + case WM_PAINT: + dc=BeginPaint(hw,&ps); + DrawAllStuff(lpapp,hw, dc); + EndPaint(hw,&ps); + break; + case WM_ERASEBKGND: + dc=(HDC)wparam; + GetClientRect(hw,&rect); + oldbrush = (HBRUSH)SelectObject(dc,lpapp->gdiobjects_bkg.brush); + oldpen = (HPEN)SelectObject(dc,lpapp->gdiobjects_bkg.pen); + Rectangle(dc,rect.left,rect.top,rect.right,rect.bottom); + SelectObject(dc,oldpen); + SelectObject(dc,oldbrush); + return 0; + case WM_DESTROY: + GetWindowRect(hw, &(lpapp->CurrentWindowRect)); + SaveAppConfiguration(lpapp); + if (lpapp->wTimer != 0) KillTimer(hw,lpapp->wTimer); + lpapp->wTimer=0; + DestroyAllControls(lpapp); + EndSoftware(lpapp,hw); + PostQuitMessage(0); + break; + default: + return (DefWindowProc(hw,msg,wparam,lparam)); + + } + return (0L); +} + + +/*******************************************************************************/ +/** MAIN PROCDURE **/ +/*******************************************************************************/ + +int APIENTRY WinMain(HINSTANCE handle_app, //Application hinstance. + HINSTANCE handle_prev, //NULL. + LPTSTR param, //Command Line Parameter. + int com_show) //How to display window (optionnal). +{ + HANDLE hMutex; + HWND hh; + long wstyle, wdx, wdy; + MSG msg; + char szWindowClassName[]="MainWindowClass"; + char * title="Sorry"; + + WNDCLASS wc; + LPT_APP_CONTEXT lpapp; + lpapp = &G_MainAppCtx; + + //we first store the APP Hinstance + memset(lpapp, 0, sizeof(T_APP_CONTEXT)); + lpapp->hinstance=handle_app; + + // + // Use Mutex to prevent to launch several instance of the application + // + hMutex = CreateMutex(NULL,TRUE,APP_UNIQUEMUTEX); + if (hMutex == NULL) return -1; + if (GetLastError() == ERROR_ALREADY_EXISTS) + { + ReleaseMutex(hMutex); + return -1; + } + else WaitForSingleObject(hMutex,INFINITE); + +#ifdef VBUSE_LOCALLIB + //if we directly link source code (VB local development only) + VBVMR_SetHinstance(handle_app); +#endif + //here you can make some early initialization and analyze command line if any. + VMSCTL_InitLib(handle_app); + VBANCMD_InitLib(0); + + //load last configuration and get Windows position/size + lpapp->CurrentWindowRect.left = CW_USEDEFAULT; + lpapp->CurrentWindowRect.top = CW_USEDEFAULT; + lpapp->CurrentWindowRect.right = CW_USEDEFAULT+UI_WIN_DX; + lpapp->CurrentWindowRect.bottom = CW_USEDEFAULT+UI_WIN_DY; + LoadAppConfiguration(lpapp); + wdx = lpapp->CurrentWindowRect.right-lpapp->CurrentWindowRect.left; + wdy = lpapp->CurrentWindowRect.bottom - lpapp->CurrentWindowRect.top; + + //we define a window class to create a window from this class + wc.style =CS_HREDRAW | CS_VREDRAW; //property. + wc.lpfnWndProc=(WNDPROC)MainWindowManageEvent; //Adresse of our Callback. + wc.cbClsExtra =0; //Possibility to store some byte inside a class object. + wc.cbWndExtra =0; //Possibility to store some byte inside a window object. + wc.hInstance =handle_app; //handle of the application hinstance. + wc.hIcon =LoadIcon(handle_app, MAKEINTRESOURCE(100)); //handle of icon displayed in the caption. + wc.hCursor =LoadCursor(NULL,IDC_ARROW); //handle of cursor mouse . + wc.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);//Background color. + wc.lpszMenuName=NULL; //pointer on menu defined in resource. + wc.lpszClassName=szWindowClassName; //pointer on class name. + + //register class. + if (RegisterClass(&wc)==0) + { + MessageBox(NULL,"Failed to register main class...",title,MB_APPLMODAL | MB_OK | MB_ICONERROR); + return 0; + } + + + //classical Main Window + wstyle = WS_OVERLAPPEDWINDOW | WS_VISIBLE; + + hh=CreateWindow(szWindowClassName, // address of registered class name. + SZPUBLICNAME, // address of window name string + wstyle, // window style + lpapp->CurrentWindowRect.left, // horizontal position of window + lpapp->CurrentWindowRect.top, // vertical position of window + wdx, // window width + wdy, // window height + NULL, // parent handle is NULL since it's a main window. + NULL, // menu name defined in resource (NULL if no menu or already defined in the Class). + handle_app, // handle of application instance + NULL); // address of window-creation data + + if (hh==NULL) + { + MessageBox(NULL,"Failed to create window...",title,MB_APPLMODAL | MB_OK | MB_ICONERROR); + return 0; + } + ShowWindow(hh,SW_SHOW); //Display the window. + UpdateWindow(hh); //Send WM_PAINT. + /*---------------------------------------------------------------------------*/ + /* Messages Loop. */ + /*---------------------------------------------------------------------------*/ + while (GetMessage(&msg,NULL,0,0)) //Get Message if any. + { + TranslateMessage(&msg); //Translate the virtuel keys event. + DispatchMessage(&msg); //DispatchMessage to the related window. + } + + //here you can make last uninitialization and release + VBANCMD_EndLib(); + VMSCTL_EndLib(); + return (int)(msg.wParam); +} diff --git a/vmr_streamer/source/vmr_streamer.h b/vmr_streamer/source/vmr_streamer.h new file mode 100644 index 0000000..a4874e5 --- /dev/null +++ b/vmr_streamer/source/vmr_streamer.h @@ -0,0 +1,83 @@ +/*--------------------------------------------------------------------------------*/ +/* VMR example: Voicemeeter Custom GUI for Streamers */ +/*--------------------------------------------------------------------------------*/ +/* 'C' Sample Code to make a Voicemeeter Custom GUI V.Burel (c)2016-2021 */ +/* */ +/* THIS PROGRAM PROVIDES A GUI TO CONTROL VOICEMEETER */ +/* PROVIDES A SIMPLIFIED GUI WITH ONLY USED STRIP/BUS */ +/* PROVIDES A RESIZABLE GRAPHIC USER INTERFACE */ +/* */ +/* This program example shows */ +/* - How to link VoicemeeterRemote.dll */ +/* - How to Login / logout */ +/* - How to Manage regular parameters to make a custom controller. */ +/* */ +/*--------------------------------------------------------------------------------*/ +/* */ +/* COMPILATION DIRECTIVES: */ +/* */ +/* To compile With Microsoft VC2005 or higher, you need to create an */ +/* empty Win32 project with the following options: */ +/* - Configuration Properties / General : Char Set = NOT SET */ +/* - Configuration Properties / C/C++ / Preprocessor : _CRT_SECURE_NO_DEPRECATE */ +/* */ +/* This source code can be compiled for 32bit or 64 bits targets as well */ +/* WARNING: FOR 64x COMPILATION, ADD PREPROCESSOR DEFINE: VB_X64 */ +/* */ +/*--------------------------------------------------------------------------------*/ +/* */ +/* LICENSING: VoicemeeterRemote.dll usage is driven by a license agreement */ +/* given in VoicemeeterRemoteAPI.pdf or readme.txt */ +/* THIS SOURCE CODE CAN BE USED ONLY IN A PROGRAM USING VOICEMEETER */ +/* REMOTE API */ +/* */ +/*--------------------------------------------------------------------------------*/ + +#ifndef __VMR_STREAMER_H__ +#define __VMR_STREAMER_H__ + +//to prevent to launch the same application twice (single instance app) +#define APP_UNIQUEMUTEX "VB-AudioVMRStreamerViewExample_VoicemeeterCustomGUI" + +//version information (for program) +#define SZPUBLICVERSION "1.0.0.2" //displayed version in about box +#define SZPUBLICNAME "VM-Streamer View (Voicemeeter Custom GUI Example)" //displayed title in main window + +//Information for Main window +#define UI_WIN_DX 800 +#define UI_WIN_DY 600 + +//version information (used in resource file) +#define __FILEVERSION__ 1,0,0,2 +#define __PRODUCTVERSION__ 1,0,0,2 +#define __SZFILEVERSION__ "1, 0, 0, 2\0" +#define __SZPRODUCTVERSION__ "1, 0, 0, 2\0" + + #define __COMMENTS__ "Example of custom GUI mae for Voicemeeter with the Voicemeeter Remote API" + #define __COMPANYNAME__ "Audio Mechanic & Sound Breeder\0" + #define __FILEDESCRIPTION__ "Custom GUI for Streamers, Remoting Voicemeeter potato\0" + #define __INTERNALNAME__ "vmr_streamer" + #define __LEGALCOPYRIGHT__ "Copyright V.Burel©2015-2021\0" + #define __ORIGINALFILENAME__ "vmr_streamer.EXE\0" + #define __PRODUCTNAME__ "vmr_streamer\0" + + + +//definitions for MENU + +#define IDM_QUIT 100 +#define IDM_ABOUT 101 + +#define IDM_UPDATE_ALL_CONTROL 200 + +#define IDMSYS_LINK_DIRECT 300 +#define IDMSYS_LINK_VBAN1 301 +#define IDMSYS_LINK_VBAN2 302 +#define IDMSYS_LINK_VBAN3 303 +#define IDMSYS_LINK_VBAN4 304 + +#define IDMSYS_VBAN_CONFIG 350 + +#endif /*__VMR_STREAMER_H__*/ + + diff --git a/vmr_streamer/source/vmr_streamer.ico b/vmr_streamer/source/vmr_streamer.ico new file mode 100644 index 0000000000000000000000000000000000000000..75e8d7ef05e08678614b199ff2d4939415f67cc5 GIT binary patch literal 7358 zcmeHLu@S;R411Q~C>Vf}kr;(>*b)Thd_s;tB!No`2NGo2vK1F!(Ao~4^SQmQ+p)Dh z&s2k<;s5S8bp+P#aiv19mEzg$yIhhZprS+N5%|G;o)ZT;!~odJlXGtwdQ-!MEP zYuNY0*->nkM#}~ZGHu2WHWBh4+9f^3UWK)R+Q8}?z)@Y_+CXifHn6D;*ufYr@qx+N zSU*_Fq+{-r;n*LQOfr^~gj~ru8y$I5iB`f%L!q@Pu}PdB8B>W?!byI7L~P=z4uHzC z4iLsx%w$-maG9jCkR=&5ZI)$TrdW!fQV>J#mf?kd;?NG0d0>93A84bbSKb5Kt)CPXK0sBv-p6hJj0X19|h5!Hn literal 0 HcmV?d00001 diff --git a/vmr_streamer/source/vmr_streamer.rc b/vmr_streamer/source/vmr_streamer.rc new file mode 100644 index 0000000..3aac284 --- /dev/null +++ b/vmr_streamer/source/vmr_streamer.rc @@ -0,0 +1,78 @@ +/*--------------------------------------------------------------------------------*/ +/* VMR example: Voicemeeter Custom GUI for Streamers */ +/*--------------------------------------------------------------------------------*/ +/* 'C' Sample Code to make a Voicemeeter Custom GUI V.Burel (c)2016-2021 */ +/* */ +/* THIS PROGRAM PROVIDES A GUI TO CONTROL VOICEMEETER */ +/* PROVIDES A SIMPLIFIED GUI WITH ONLY USED STRIP/BUS */ +/* PROVIDES A RESIZABLE GRAPHIC USER INTERFACE */ +/* */ +/* This program example shows */ +/* - How to link VoicemeeterRemote.dll */ +/* - How to Login / logout */ +/* - How to Manage regular parameters to make a custom controller. */ +/* */ +/*--------------------------------------------------------------------------------*/ +/* */ +/* COMPILATION DIRECTIVES: */ +/* */ +/* To compile With Microsoft VC2005 or higher, you need to create an */ +/* empty Win32 project with the following options: */ +/* - Configuration Properties / General : Char Set = NOT SET */ +/* - Configuration Properties / C/C++ / Preprocessor : _CRT_SECURE_NO_DEPRECATE */ +/* */ +/* This source code can be compiled for 32bit or 64 bits targets as well */ +/* WARNING: FOR 64x COMPILATION, ADD PREPROCESSOR DEFINE: VB_X64 */ +/* */ +/*--------------------------------------------------------------------------------*/ +/* */ +/* LICENSING: VoicemeeterRemote.dll usage is driven by a license agreement */ +/* given in VoicemeeterRemoteAPI.pdf or readme.txt */ +/* */ +/*--------------------------------------------------------------------------------*/ + + +#include "vmr_streamer.h" + +100 ICON "vmr_streamer.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +1 VERSIONINFO + FILEVERSION __FILEVERSION__ + PRODUCTVERSION __PRODUCTVERSION__ + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x0L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "Comments", __COMMENTS__ + VALUE "CompanyName", __COMPANYNAME__ + VALUE "FileDescription", __FILEDESCRIPTION__ + VALUE "FileVersion", __SZFILEVERSION__ + VALUE "InternalName", __INTERNALNAME__ + VALUE "LegalCopyright", __LEGALCOPYRIGHT__ + VALUE "OriginalFilename", __ORIGINALFILENAME__ + VALUE "ProductName", __PRODUCTNAME__ + VALUE "ProductVersion", __SZPRODUCTVERSION__ + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END + + diff --git a/vmr_streamer/targetver.h b/vmr_streamer/targetver.h new file mode 100644 index 0000000..bf75e08 --- /dev/null +++ b/vmr_streamer/targetver.h @@ -0,0 +1,6 @@ +#pragma once + +// // Including SDKDDKVer.h defines the highest available Windows platform. +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. +#include diff --git a/vmr_streamer/vmr_streamer.cpp b/vmr_streamer/vmr_streamer.cpp new file mode 100644 index 0000000..1630a06 --- /dev/null +++ b/vmr_streamer/vmr_streamer.cpp @@ -0,0 +1,180 @@ +// vmr_streamer.cpp : Defines the entry point for the application. +// + +#include "framework.h" +#include "vmr_streamer.h" + +#define MAX_LOADSTRING 100 + +// Global Variables: +HINSTANCE hInst; // current instance +WCHAR szTitle[MAX_LOADSTRING]; // The title bar text +WCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name + +// Forward declarations of functions included in this code module: +ATOM MyRegisterClass(HINSTANCE hInstance); +BOOL InitInstance(HINSTANCE, int); +LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); +INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); + +int APIENTRY wWinMain(_In_ HINSTANCE hInstance, + _In_opt_ HINSTANCE hPrevInstance, + _In_ LPWSTR lpCmdLine, + _In_ int nCmdShow) +{ + UNREFERENCED_PARAMETER(hPrevInstance); + UNREFERENCED_PARAMETER(lpCmdLine); + + // TODO: Place code here. + + // Initialize global strings + LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); + LoadStringW(hInstance, IDC_VMRSTREAMER, szWindowClass, MAX_LOADSTRING); + MyRegisterClass(hInstance); + + // Perform application initialization: + if (!InitInstance (hInstance, nCmdShow)) + { + return FALSE; + } + + HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_VMRSTREAMER)); + + MSG msg; + + // Main message loop: + while (GetMessage(&msg, nullptr, 0, 0)) + { + if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + return (int) msg.wParam; +} + + + +// +// FUNCTION: MyRegisterClass() +// +// PURPOSE: Registers the window class. +// +ATOM MyRegisterClass(HINSTANCE hInstance) +{ + WNDCLASSEXW wcex; + + wcex.cbSize = sizeof(WNDCLASSEX); + + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = WndProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInstance; + wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_VMRSTREAMER)); + wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); + wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_VMRSTREAMER); + wcex.lpszClassName = szWindowClass; + wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); + + return RegisterClassExW(&wcex); +} + +// +// FUNCTION: InitInstance(HINSTANCE, int) +// +// PURPOSE: Saves instance handle and creates main window +// +// COMMENTS: +// +// In this function, we save the instance handle in a global variable and +// create and display the main program window. +// +BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) +{ + hInst = hInstance; // Store instance handle in our global variable + + HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); + + if (!hWnd) + { + return FALSE; + } + + ShowWindow(hWnd, nCmdShow); + UpdateWindow(hWnd); + + return TRUE; +} + +// +// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM) +// +// PURPOSE: Processes messages for the main window. +// +// WM_COMMAND - process the application menu +// WM_PAINT - Paint the main window +// WM_DESTROY - post a quit message and return +// +// +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_COMMAND: + { + int wmId = LOWORD(wParam); + // Parse the menu selections: + switch (wmId) + { + case IDM_ABOUT: + DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); + break; + case IDM_EXIT: + DestroyWindow(hWnd); + break; + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + } + break; + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hdc = BeginPaint(hWnd, &ps); + // TODO: Add any drawing code that uses hdc here... + EndPaint(hWnd, &ps); + } + break; + case WM_DESTROY: + PostQuitMessage(0); + break; + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + return 0; +} + +// Message handler for about box. +INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + UNREFERENCED_PARAMETER(lParam); + switch (message) + { + case WM_INITDIALOG: + return (INT_PTR)TRUE; + + case WM_COMMAND: + if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) + { + EndDialog(hDlg, LOWORD(wParam)); + return (INT_PTR)TRUE; + } + break; + } + return (INT_PTR)FALSE; +} diff --git a/vmr_streamer/vmr_streamer.vcxproj b/vmr_streamer/vmr_streamer.vcxproj new file mode 100644 index 0000000..ba96530 --- /dev/null +++ b/vmr_streamer/vmr_streamer.vcxproj @@ -0,0 +1,165 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {cb959fdd-2aa4-4ecd-8a50-41777bf38eea} + vmrstreamer + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + NotSet + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + NotSet + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + + + Windows + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Ws2_32.lib ;%(AdditionalDependencies) + + + + + Level3 + true + _DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + + + Windows + true + + + + + Level3 + true + true + true + NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;VB_X64;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Ws2_32.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/vmr_streamer/vmr_streamer.vcxproj.filters b/vmr_streamer/vmr_streamer.vcxproj.filters new file mode 100644 index 0000000..3b6604b --- /dev/null +++ b/vmr_streamer/vmr_streamer.vcxproj.filters @@ -0,0 +1,58 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file