It is Mixcraft time

Post any tips and tricks you've discovered for using Acoustica software here.

Moderators: Acoustica Greg, Acoustica Chris, Acoustica Eric, Acoustica Dan, rsaintjohn

Post Reply
jwmix
Posts: 39
Joined: Mon Apr 30, 2018 12:06 pm

It is Mixcraft time

Post by jwmix »

Since the weather is starting to get cold (around the poster), well then, there is nothing like a
warm, healthy Dark Chocolate drink (or even a solid or cold Dark Chocolate object). And to the poster,
a warm, healthy Dark Chocolate drink always means, it's Mixcraft time.

Why?

Well...

Doesn't the post reader know, that just maybe, Mixcraft 10 might have been made, while the
programmers/office workers/artists (and other such artiste people), where drinking warm, healthy
Dark Chocolate (or even a solid or cold Dark Chocolate object)?

Well, maybe the poster might be wrong about the above, but in the Mixcraft 10 code, it shows that
Dark Chocolate was involved as shown by an app that is available within every modern Windows computer
and that app is the Windows task automation/scripting tool, named Windows PowerShell or as it is now
called just PowerShell (now that it is out for other Operating Systems too). But what exactly is
PowerShell?

What is PowerShell?
https://docs.microsoft.com/en-us/powers ... rshell-5.1

What is Windows PowerShell Integrated Scripting Environment (ISE)?
https://docs.microsoft.com/en-us/powers ... rshell-5.1

What is Windows Terminal?
https://learn.microsoft.com/en-us/windows/terminal/

Note: If the post reader reads the above (and trys some of their examples), then the post reader
will know what to do with the below forum code sections (full of PowerShell text/code/actions).

Note: All of the PowerShell text/code/actions were created and ran within the Windows PowerShell ISE.

Time for some PowerShell interactive user, copy and paste, PowerShell text/code/actions.

Always have a good idea (understanding) of what any text/code/action will do.

Code: Select all


$mixcraft10ExeFolder = "$env:ProgramFiles\Acoustica Mixcraft 10"

$fileName = "mixcraft10.VisualElementsManifest.xml"

$searchFilePath = "$mixcraft10ExeFolder\$fileName"

$find = "back"

Write-Host
Write-Host "Searching for " -NoNewline
Write-Host "$find " -NoNewline -ForegroundColor Cyan
Write-Host "in the below file:"
Write-Host $searchFilePath -ForegroundColor Yellow

$found = Select-String -Pattern $find -Path $searchFilePath -SimpleMatch

Write-Host
Write-Host "The full found data is shown below:"
Write-Host $found -ForegroundColor Green

Write-Host
Write-Host "Or the search returned the below found objects (data, line number, path and more): " 
Write-Host "The found data is "-NoNewLine
Write-Host $found.Line -ForegroundColor Green
Write-Host "on line number " -NoNewline
Write-Host $found.LineNumber -ForegroundColor Cyan
Write-Host "in the file: " -NoNewline

$fileFullName = $found.Path 

Write-Host $fileFullName -ForegroundColor Yellow

Write-Host
Write-Host "But this post only needs the found line's data:"
Write-Host $found.Line -ForegroundColor Green

Write-Host
Write-Host "Mmmm, but what objects, are in the above data's blank area (spaces, tabs and so on...)?"

$found.Line.ToCharArray()[0..4].ToByte($null) -join " " | 
  Out-Default

Write-Host
Write-Host "Ahh tab (ASCII 9) characters, that are not needed in this post, so get rid of them."

$foundData = $found.Line.TrimStart(9)

Write-Host
Write-Host $foundData -ForegroundColor Green

Write-Host
Write-Host "Note that the color site, that will be used in this post"
Write-Host "works better without the double quote characters. So replace"
Write-Host "those characters with nothing."

$foundData = $foundData.Replace('"',"")

Write-Host
Write-Host "So now the found data is:"
Write-Host $foundData -ForegroundColor Green

Write-Host
Write-Host "Now the last thing needed for the color site " -NoNewline
Write-Host "is just the color's number."

$colorNumber = $foundData.Substring( $foundData.IndexOf("#") + 1 )

Write-Host
Write-Host "Will use the color number: " -NoNewline
Write-Host $colorNumber -ForegroundColor Cyan

Write-Host
Write-Host "Ready to " -NoNewline
Write-Host "start" -NoNewline -ForegroundColor Cyan
Write-Host ", one's " -NoNewline
Write-Host "defaulted browser" -NoNewline -ForegroundColor Green
Write-Host ","
Write-Host "via the url: " -NoNewline

$url = "https://www.color-name.com/hex/$colorNumber"

Write-Host $url -ForegroundColor Yellow 
Write-Host "to find out what the data " -NoNewline
Write-Host "might be" -NoNewline -ForegroundColor Green
Write-Host ", for the color number " -NoNewline
Write-Host "$colorNumber" -NoNewline -ForegroundColor Cyan
Write-Host "?"

Write-Host
Write-Host "Press Ctrl+C to quit now or"
pause

Write-Host
Write-Host "Starting " -NoNewline -ForegroundColor Cyan
Write-Host "the " -NoNewline
Write-Host "defaulted browser " -NoNewline -ForegroundColor Green
Write-Host "by using the url: " -NoNewline
Write-Host $url -ForegroundColor Yellow

Start-Process -FilePath $url    

PS returns (and no errors).

Searching for back in the below file:
C:\Program Files\Acoustica Mixcraft 10\mixcraft10.VisualElementsManifest.xml

The full found data is shown below:
C:\Program Files\Acoustica Mixcraft 10\mixcraft10.VisualElementsManifest.xml:3: BackgroundColor="#410000"

Or the search returned the below found objects (data, line number, path and more):
The found data is - - - - - - - - BackgroundColor="#410000"
on line number 3
in the file: C:\Program Files\Acoustica Mixcraft 10\mixcraft10.VisualElementsManifest.xml

But this post only needs the found line's data:
- - - - - - - - - BackgroundColor="#410000"

Mmmm, but what objects, are in the above data's blank area (spaces, tabs and so on...)?
9 9 66 97 99

Ahh tab (ASCII 9) characters, that are not needed in this post, so get rid of them.

BackgroundColor="#410000"

Note that the color site, that will be used in this post
works better without the double quote characters. So replace
those characters with nothing.

So now the found data is:
BackgroundColor=#410000

Now the last thing needed for the color site is just the color's number.

Will use the color number: 410000

Ready to start, one's defaulted browser,
via the url: https://www.color-name.com/hex/410000
to find out what the data might be, for the color number 410000?

Press Ctrl+C to quit now or
Press Enter to continue...:

Then after pressing the Enter key,

PS returns (and no errors).

Starting the defaulted browser by using the url: https://www.color-name.com/hex/410000

Then the poster's browser (here Edge), shows the color's data, including Closest Name: Dark Chocolate.

End of PS returned output.

Mmm, Closest Name: Dark Chocolate.

The poster wondered if Dark Chocolate was a Windows known color, so the poster loaded a Windows
needed Assembly System.Drawing (think of them like a library of Windows actions, just like Mixcraft
loads in a plugin's actions to use too).

Note: The ISE really does not need to load this System.Drawing assembly,
because the ISE loads this assembly and also the System.Windows.Forms assembly too, when starting
the PowerShell ISE app. But doing the Add-Type cmdlet (think command) again, has no bad effects.

Code: Select all


Add-Type -AssemblyName System.Drawing

Write-Host
Write-Host "Is Hot Pink a Windows known color? " -NoNewline

$answer = [System.Enum]::IsDefined("System.Drawing.KnownColor","HotPink")

If($answer) { 
  Write-Host $answer -ForegroundColor Cyan
}
Else { 
  Write-Host $answer -ForegroundColor Red
}

Write-Host
Write-Host "Is Dark Chocolate a Windows known color? " -NoNewline

$answer = [System.Enum]::IsDefined("System.Drawing.KnownColor","DarkChocolate")

If($answer) { 
  Write-Host $answer -ForegroundColor Cyan
}
Else { 
  Write-Host $answer -ForegroundColor Red
}

PS returns (and no errors).

Is Hot Pink a Windows known color? True

Is Dark Chocolate a Windows known color? False

End of PS returned output.

Well, since #410000 is not, a truly known color, then just like Mixcraft workflows differ, other
color sites usage of color names varies. But like Santa and the Tooth Fairy, today, to the poster
(and friends, Bing, Edge and PowerShell), the color name just has to be, Dark Chocolate.

Was this post really about Dark Chocolate (yeah), plus it was also an introduction to PowerShell
usage too, so that the poster doesn't need to explain what's PowerShell and how to use PowerShell in
every DawPsDemo example (like this one). Where by the way, Daw here means Ditigal audio whatever app,
like Sound Forge, Midi-Ox, Windows OS tools, controllers, plugins, midi in text, DAWs, libraries, Guitar Pro,
and any other such audio or midi or sound objects and not just Ditigal Audio Workstations.

So yeah, the poster does love some warm and healthy Dark Chocolate drinks, but this post leads to
reading any Daw apps's, like Mixcraft's XML (EXtensible Markup Language) and (usually) uses (.xml)
files,

https://www.geeksforgeeks.org/what-is-xml/

which PowerShell reads along with text (.txt) files, binary (many extensions .wav, .dat, .mx10, .ini,
and so on) files, CSV (Common Separated Value) files (.csv) and other such object types.

And PowerShell can create/read/change/save XML files, as soon seen in the below forum sections that
are reading an XML file by just casting or changing the returned text data into XML data.

Note: And since PowerShell remembers everything done within it's session (until the window is closed)
then all of the above variables are still usable.

Code: Select all


Write-Host
Write-Host "Text reading " -NoNewline
Write-Host $fileFullName -ForegroundColor Yellow

$textReadData = Get-Content $fileFullName

Write-Host 
Write-Host "The regular text reading object's type is:"

$textReadData.GetType() | 
  Out-Default

Write-Host
Write-Host "And it's text data is:"

Write-Host
$textReadData | 
  Out-Default

Write-Host 
Write-Host "But casting or changing the returned read data shows the type is:"

[xml] $mixcraft10VisualElementsManifestXlmData = Get-Content $fileFullName

$mixcraft10VisualElementsManifestXlmData.GetType() | 
  Out-Default

Write-Host
Write-Host "and the XML data is:"

Write-Host
$mixcraft10VisualElementsManifestXlmData | 
  Out-Default

Write-Host
Write-Host "And now just walk the data dot ( . ) by dot, until the needed data is found."

Write-Host '$mixcraft10VisualElementsManifestXlmData.Application.VisualElements.BackgroundColor returns:'

Write-Host
$mixcraft10VisualElementsManifestXlmData.Application.VisualElements.BackgroundColor | 
  Out-Default

PS returns (and no errors).

Text reading C:\Program Files\Acoustica Mixcraft 10\mixcraft10.VisualElementsManifest.xml

A regular reading object's type is:

IsPublic - IsSerial - Name - - - BaseType
-------- -------- ---- --------
True - - True --- Object[] - System.Array

And it's text data is:

<Application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- - <VisualElements
- - - - - - - - BackgroundColor="#410000"
- - - ShowNameOnSquare150x150Logo="off"
- - - ForegroundText="light"
- - - Square150x150Logo="Assets\150x150.png"
- - - Square70x70Logo="Assets\70x70.png"
/>
</Application>

But casting or changing the returned read data shows the type is:

IsPublic - IsSerial - Name BaseType
-------- ------------ ----- --------
True - False - - XmlDocument System.Xml.XmlNode

and the XML data is:

Application
-----------
Application

And now just walk the data dot ( . ) by dot, until the needed data is found.

$mixcraft10VisualElementsManifestXlmData.Application.VisualElements.BackgroundColor returns:

#410000

End of PS returned output.

Or use the XML ChildNodes.

Code: Select all


Write-Host
Write-Host 'The $mixcraft10VisualElementsManifestXlmData.ChildNodes.Count is: ' -NoNewline
Write-Host $mixcraft10VisualElementsManifestXlmData.ChildNodes.Count -NoNewline -ForegroundColor Cyan 
Write-Host "."

Write-Host
Write-Host "And the ChildNodes' beginning data is:"
$mixcraft10VisualElementsManifestXlmData.ChildNodes[0] | 
  Out-Default

Write-Host
Write-Host '$mixcraft10VisualElementsManifestXlmData.ChildNodes[0].VisualElements.Attributes.Count is ' -NoNewline

$numberOfAttributesCount = $mixcraft10VisualElementsManifestXlmData.ChildNodes[0].VisualElements.Attributes.Count 

Write-Host $numberOfAttributesCount -NoNewline -ForegroundColor Cyan
Write-Host "."

Write-Host
Write-Host "And so the XML's data is:"

$mixcraft10VisualElementsManifestXlmData.ChildNodes[0].VisualElements.Attributes | 
  ForEach-Object -Process { 
    Write-Host 
    Write-Host "Name: "$PSItem.Name
    Write-Host "Value:"$PSItem.value 
  } # End of  ForEach-Object -Process { }.

PS returns (and no errors).

The $mixcraft10VisualElementsManifestXlmData.ChildNodes.Count is: 1.

And the ChildNodes' beginning data is:

xsi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VisualElements
--- ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --------------
http://www.w3.org/2001/XMLSchema-instance - - VisualElements

$mixcraft10VisualElementsManifestXlmData.ChildNodes[0].VisualElements.Attributes.Count is 5.

And so the XML's data is:

Name: BackgroundColor
Value: #410000

Name: ShowNameOnSquare150x150Logo
Value: off

Name: ForegroundText
Value: light

Name: Square150x150Logo
Value: Assets\150x150.png

Name: Square70x70Logo
Value: Assets\70x70.png

End of PS returned output.

Mmmm now the post reader can read and obtain any XML's needed data. Yes the post reader will need
to pactice this action, just like the post reader does/did for using any of Mixcraft's plugins too.
And of course, there are many other XML reading PowerShell ways.

But don't worry, be happy,
by using the Windows PowerShell ISE,
that provides the data to use from each dot ( . ) usage,
and also because, all of the DawPsDemo examples, like this one,
are written and ran (and meant to be used) within the Windows PowerShell ISE.

And then later, after learning more, those more interested post readers can adjust these into any
PowerShell type of usage. Usage such as Windows PowerShell stand alone window usage. Or PowerShell
version seven (7 and up) windows usage, and of course, PowerShell scripting (.ps1) files, that can
be ran in all of the above PowerShell windows (write them once, run them forever).

But most post readers will get by just fine, with the plain Windows PowerShell ISE active user usage.

So from here on out post readers,
just PowerShell interactive user, copy and paste, PowerShell text/code/actions, written and ran
within the Windows PowerShell ISE, where the ISE is being used as a music data controller for
various audio/midi/apps/devices/files and registry type of actions.
jwmix
Posts: 39
Joined: Mon Apr 30, 2018 12:06 pm

Re: It is Mixcraft time

Post by jwmix »

Play/share your music, whether one is at grandma's house or that hip Paris jazz spot.

Try using the Windows PowerShell ISE (as one's music data controller), where one can use any project
file or design a complete playlist and auto run through it.

Here is how (when ran within the PowerShell ISE) to auto start various Daw objects, playing their
own last closed project's sounds, by using most of the same PowerShell text/code/actions, for each
of the Daw objects.

Note: All of the PowerShell text/code/actions were created and ran within the Windows PowerShell ISE.

Time for some PowerShell interactive user, copy and paste, PowerShell text/code/actions.

Always have a good idea (understanding) of what any text/code/action will do.

Code: Select all


Add-Type -AssemblyName System.Windows.Forms

# $daw = "Guitar Pro"

# $daw = "Music Maker"

$daw = "Mixcraft"

If($daw -match "gui") { 
  $find = "*gp*"
}

If($daw -match "mus") {
  $find = "*mmm*"
}

If($daw -match "mix") {
  $find = "*mx10*"
}
 
$windowsRecentList = "$env:AppData\Microsoft\Windows\Recent"

$lastClosedProjectPath = Get-ChildItem -Path $windowsRecentList -Filter $find | 
  Sort-Object -Descending -Property LastWriteTime | 
    Select-Object -First 1 | 
      Select-Object -ExpandProperty FullName

Write-Host
Write-Host "Ready to auto start $daw playing it's sounds via the below project?"
Write-Host $lastClosedProjectPath -ForegroundColor Yellow

Write-Host
Write-Host "Press Ctrl+C to quit or"
pause

Start-Process -FilePath $lastClosedProjectPath

Write-Host
Write-Host "Started the above " -NoNewline

If($daw -match "gui") { 
  $sleepSeconds = 10
  Write-Host "$daw project, that should be running in about $sleepSeconds seconds."
}
Else { 
  $sleepSeconds = 45
  Write-Host "(" -NoNewline
  Write-Host "now an on line access object" -NoNewline -ForegroundColor Green
  Write-Host ") $daw project,"
  Write-Host "that (" -NoNewline
  Write-Host "usually" -NoNewline -ForegroundColor Cyan
  Write-Host ") takes less than $sleepSeconds seconds. So wait for it..."
} 

Start-Sleep -Seconds $sleepSeconds
 
[System.Windows.Forms.SendKeys]::SendWait(" ")

Write-Host
Write-Host "Hopefully, the $daw's sounds are playing."

PS returns (and no errors and showing all three outputs).

Ready to auto start Guitar Pro playing it's sounds via the below project?
C:\Users\UserId\AppData\Roaming\Microsoft\Windows\Recent\FingerPick Test A.gp.lnk

Press Ctrl+C to quit or
Press Enter to continue...:

Started the above Guitar Pro project, that should be running in about 5 seconds.

Hopefully, the Guitar Pro's sounds are playing.


Ready to auto start Music Maker playing it's sounds via the below project?
C:\Users\UserId\AppData\Roaming\Microsoft\Windows\Recent\Bass_Shuffle_E.MMM.lnk

Press Ctrl+C to quit or
Press Enter to continue...:

Started the above (now an on line access object) Music Maker project,
that (usually) takes less than 45 seconds. So wait for it...

Hopefully, the Music Maker's sounds are playing.


Ready to auto start Mixcraft playing it's sounds via the below project?
C:\Users\UserId\AppData\Roaming\Microsoft\Windows\Recent\Country Rock Bass.mx10.lnk

Press Ctrl+C to quit or
Press Enter to continue...:

Started the above (now an on line access object) Mixcraft project,
that (usually) takes less than 45 seconds. So wait for it...

Hopefully, the Mixcraft's sounds are playing.

Did the post reader notice that each Daw's last closed project's paths were link ( .lnk ) files?
They work because within each link file's shell object is the fully named project path.

Note: In the below a shell object is created and used but nothing was damaged, because the object
is only read and not saved.

Code: Select all


$wshShell = New-Object -ComObject WScript.Shell

Write-Host
Write-Host "Using the below link file's data:"
Write-Host $lastClosedProjectPath -ForegroundColor Yellow

Write-Host
Write-Host "And shown below is the real fully named project path."

$linkObjectData = $wshShell.CreateShortcut("$lastClosedProjectPath")

Write-Host $linkObjectData.TargetPath -ForegroundColor Yellow

PS returns (and no errors).

Using the below link file's data:
C:\Users\UserId\AppData\Roaming\Microsoft\Windows\Recent\Country Rock Bass.mx10.lnk

And shown below is the real fully named project path.
C:\Users\UserId\Documents\DawPsDemo\Acoustica\Mixcraft Test Projects\Country Rock Bass.mx10

So by using the Windows PowerShell ISE as one's music's data controller, the user can easily set up
what one needs, for the next project, or song lists via the file system, before even starting the
next project or song list (or Daw app).
jwmix
Posts: 39
Joined: Mon Apr 30, 2018 12:06 pm

Re: It is Mixcraft time

Post by jwmix »

When it's snowing outside,
the poster likes to warm up with a few warm Dark Chocolate drinks,
and relax by reading midi files,
with the help of the Windows PowerShell ISE,
that is being used as a music data controller.

Anyway, so all can read and play along, the poster will use one of Mixcraft's teacher's midi files.

https://acoustica.com/mixcraft-10-teach ... troduction

There's a zip file in the second paragraph using the above Mixcraft location.

Download it. Scan it. Place it wherever the post reader wants to place it.

Then in the PowerShell text/code/actions below, be sure to change the midi path into the post
reader's midi file path.

PowerShell (usually) is not character case sensitive, either upper and/or lower case characters work.

Note: All of the PowerShell text/code/actions were created and ran within the Windows PowerShell ISE.

Time for some PowerShell interactive user, copy and paste, PowerShell text/code/actions.

Always have a good idea (understanding) of what any text/code/action will do.

Code: Select all


Write-Host
$home, $HoMe, $HOME, $env:USERPROFILE, $env:UsErPrOfIlE, $env:userprofile | 
  Out-Default

PS returns (and no errors).

C:\Users\UserId
C:\Users\UserId
C:\Users\UserId
C:\Users\UserId
C:\Users\UserId
C:\Users\UserId

Okay moving on to one way to read a midi file.

Code: Select all


# Adjust to the user's location of the midi file's path.

$forumShorterPathPart1 = "$env:USERPROFILE\Documents\DawPsDemo\Acoustica\"
$forumShorterPathPart2 = "Mixcraft Teachers Materials\mixcraft-teachers-guide-additional-"
$forumShorterPathPart3 = "materials\Sample Projects\Lesson 11 - MIDI Instrument Survey Project"

$midiFilesDirectoryPath = $forumShorterPathPart1 + $forumShorterPathPart2 + $forumShorterPathPart3

$mixcraftTeachersMidiFilesSortedDirInfo = Get-ChildItem -Path $midiFilesDirectoryPath | 
  Sort-Object -Property Length 

Write-Host
Write-Host "What type of object is " -NoNewline

# Use a single ( ' ) quote around a variable to display the variable's name.

Write-Host '$mixcraftTeachersMidiFilesSortedDirInfo' -NoNewline -ForegroundColor Green

# Back to using double ( " ) quotes around any data to display what's in the data.

Write-Host "?"

Write-Host
$mixcraftTeachersMidiFilesSortedDirInfo.GetType() | 
  Out-Default

Write-Host
Write-Host "And it contains:"

Write-Host
$mixcraftTeachersMidiFilesSortedDirInfo | 
  Out-Default

Write-Host
Write-Host "What type of object is the second object (file) listed above?"

# Humans count 1, 2, 3 but computers count 0, 1, 2 (one less than humans).

$midiFilePath = $mixcraftTeachersMidiFilesSortedDirInfo[1]

$midiFilePath.GetType() | 
  Out-Default

Write-Host
Write-Host "Using the file named " -NoNewline
Write-Host $midiFilePath -NoNewline -ForegroundColor Green
Write-Host "."

PS returns (and no errors).

What type of object is $mixcraftTeachersMidiFilesSortedDirInfo?

To correctly keep the PowerShell's outputted format,
the PowerShell output is also placed within a code section too.
(Not code, just the formatted outputted data.)

Code: Select all


IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

And it contains:


    Directory: C:\Users\UserId\Documents\DawPsDemo\Acoustica\Mixcraft Teachers
    Materials\mixcraft-teachers-guide-additional-materials\Sample Projects\Lesson 11 - MIDI Instrument Survey Project


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         1/30/2020   4:01 PM            389 Fais dodo, Colin.mid
-a----         1/30/2020   4:01 PM            389 Hush Little Baby.mid
-a----         1/30/2020   4:01 PM            407 Frere Jacques.mid
-a----         1/30/2020   4:01 PM            465 Eency Weency Spider.American.mid
-a----         1/30/2020   4:01 PM            471 Wildwood Flower.mid
-a----         1/30/2020   4:01 PM            479 Three Little Fishies - American.mid
-a----         1/30/2020   4:01 PM            569 Yankee Doodle.mid
-a----         1/30/2020   4:01 PM            651 Coucou.mid
-a----         1/30/2020   4:01 PM           1110 Erie Canal.mid



What type of object is the second object (file) listed above?

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     FileInfo                                 System.IO.FileSystemInfo

Using the file named Hush Little Baby.mid.

But before the poster runs/reads/plays any object (file), the poster wants to check and see,
if the file is really what is says it is, here a midi file?

The poster will use the cmdlet Format-Hex to get the midi file's complete
header's data, (which is the first line of the Format-Hex output) and for fun, also get the line
after the found date (for later usage).

Code: Select all


Format-Hex -Path $midiFilePath.FullName | 
  Select-Object -First 2 | 
    Out-Default

To correctly keep the PowerShell's outputted format,
the PowerShell output is also placed within a code section too.
(Not code, just the formatted outputted data.)

Code: Select all



           Path: C:\Users\UserId\Documents\DawPsDemo\Acoustica\Mixcraft Teachers 
Materials\mixcraft-teachers-guide-additional-materials\Sample Projects\Lesson 11 - MIDI 
Instrument Survey Project\Hush Little Baby.mid


           00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000   4D 54 68 64 00 00 00 06 00 01 00 02 03 E8 4D 54  MThd.........èMT
00000010   72 6B 00 00 00 13 00 FF 51 03 09 27 C0 00 FF 58  rk......Q..'À..X

Ahhh the complete midi header is on the first line. If the post reader is just reading for only
the midi header, change the PowerShell text/code/actions from Select-Object -First 2 into
Select-Object -First 1. The poster used 2, to read more than just the midi's header's data.

File location's 00000000 to 0000000D is the complete midi header:

File location 00000000 holds Hexadecimal number 4D which in ASCII is M
File location 00000001 holds Hexadecimal number 54 which in ASCII is T
File location 00000002 holds Hexadecimal number 68 which in ASCII is h
File location 00000003 holds Hexadecimal number 64 which in ASCII is d

That is the Midi Track header marker.

The next four file locations and Hexadecimal numbers, which also will always be the same data in
every midi header, contains the size of of the header data that has data that can change from file
to file, and that size is always six ( 6 ). Which means the next six file location's holds data that
changes. Note also that in the ASCII section there are only dots ( ..... ) displayed, because these
Hexadecimal numbers are too low or too high to be ASCII displayed.

File location 00000004 holds Hexadecimal number 00 which in ASCII is .
File location 00000005 holds Hexadecimal number 00 which in ASCII is .
File location 00000006 holds Hexadecimal number 00 which in ASCII is .
File location 00000007 holds Hexadecimal number 06 which in ASCII is .

The last six file locations and Hexadecimal numbers, are three midi changeable settings, with each
setting using two of the Hexadecimal numbers.

The midi file type setting for this midi file:

File location 00000008 holds Hexadecimal number 00 which in ASCII is .
File location 00000009 holds Hexadecimal number 01 which in ASCII is .

Combine the file location's 08 and 09's Hexadecmimal numbers together is 0001 or decimal number 1.

File type 0 is a single track midi file type.
File type 1 is a multi track midi file type.
File type 2 is a sequential track midi file type.

The midi file's number of tracks setting for this midi file:

File location 0000000A holds Hexadecimal number 00 which in ASCII is .
File location 0000000B holds Hexadecimal number 02 which in ASCII is .

Combine the file location's 0A and 0B's Hexadecmimal numbers together is 0002 or decimal number 2.

So the file's count of tracks is 2.

The midi file's Ticks Per Quarter Note setting for this midi file:

File location 0000000C holds Hexadecimal number 03 which in ASCII is .
File location 0000000D holds Hexadecimal number E8 which in ASCII is .

Combine the file location's 0C and 0D's Hexadecmimal numbers together is 03E8 or decimal number 1000.

The post reader can use PowerShell to combine the Hexadecimal numbers and then convert them to
decimal numbers.

Code: Select all


Write-Host
Write-Host "Combining Hexadecimal numbers 00 and 01 together is 0001 which in Decimal is " -NoNewline

$answer = 0x0001

Write-Host $answer -NoNewline -ForegroundColor Cyan
Write-Host "."

Write-Host
Write-Host "Combining Hexadecimal numbers 00 and 02 together is 0002 which in Decimal is " -NoNewline

$answer = 0x0002

Write-Host $answer -NoNewline -ForegroundColor Cyan
Write-Host "."

Write-Host
Write-Host "Combining Hexadecimal numbers 03 and E8 together is 03E8 which in Decimal is " -NoNewline

$answer = 0x03E8

Write-Host $answer -NoNewline -ForegroundColor Cyan
Write-Host "."

PS returns (and no errors).

Combining Hexadecimal numbers 00 and 01 together is 0001 which in Decimal is 1.

Combining Hexadecimal numbers 00 and 02 together is 0002 which in Decimal is 2.

Combining Hexadecimal numbers 03 and E8 together is 03E8 which in Decimal is 1000.

Remember that the poster selected the first 2 objects (lines of data) from the Format-Hex output.
Well in that second line is a Set Tempo Meta Event (there may be more that one Set Tempo within a
midi file - so always check for them). The ASCII section is not really useful with this setting.

- - - - - - - -00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000010 - 72 6B 00 00 00 13 00 FF 51 03 09 27 C0 00 FF 58

File location 00000016 holds Hexadecimal number 00 is the delta time zero ( 00 ).
File location 00000017 holds Hexadecimal number FF is the Status marker.
File location 00000018 holds Hexadecimal number 51 is the type (Set Tempo).
File location 00000019 holds Hexadecimal number 03 use the next 3 Hexadecimal numbers.

So combine the file location's 1A and 1B and 1C's Hexadecmimal numbers together is 0927C0 and then
let PowerShell do the math.

Code: Select all


Write-Host
Write-Host "Combining Hexadecimal numbers 09 and 27 and C0 together " -NoNewline
Write-Host "is 0927C0 which in Decimal is " -NoNewline

$answer = 0x0927C0

Write-Host $answer -NoNewline -ForegroundColor Cyan
Write-Host "."

PS returns (and no errors).

Combining Hexadecimal numbers 09 and 27 and C0 together is 0927C0 which in Decimal is 600000.

So Set Tempo in microseconds is 600000, and that means Beats Per Minute (BPM) is,
well, let PowerShell do math again.

Code: Select all


Write-Host
Write-Host "If the midi Meta Event Set Tempo is set to " -NoNewline

$setTempo = "600000"

Write-Host "$setTempo" -NoNewline -ForegroundColor Cyan
Write-Host ", then the Beats Per Minute (BPM) is " -NoNewline

# The below number is 60 then six more zeros ( 000000 ).

$bpm = 60000000 / $setTempo

Write-Host $bpm -NoNewline -ForegroundColor Cyan
Write-Host "."

PS returns (and no errors).

If the midi Meta Event Set Tempo is set to 600000, then the Beats Per Minute (BPM) is 100.

If any post reader is really interested in this advance way of reading midi files, well there are
websites that can help one learn how to Hexadecimal\Decimal read midi files.

After Hexadecimal reading of few midi files, the post reader will only need PowerShell to help with
some of the math, some of the time.

But don't worry. Be Happy.

There's another way to read a midi file's data, such as the midi file's header's data by using
the text or binary reader cmdlet named Get-Content.

Yeap, as the post reader will soon see, PowerShell always has many different ways.
jwmix
Posts: 39
Joined: Mon Apr 30, 2018 12:06 pm

Re: It is Mixcraft time

Post by jwmix »

The poster will read a midi file's header, this time by using the text and binary reader named
Get-Content.

Anyway, so all can read and play along, the poster will use one of Mixcraft's teacher's midi files.

https://acoustica.com/mixcraft-10-teach ... troduction

There's a zip file in the second paragraph using the above Mixcraft location.

Download it. Scan it. Place it wherever the post reader wants to place it.

Then in the PowerShell text/code/actions below, be sure to change the midi path into the post
reader's midi file path.

Note: All of the PowerShell text/code/actions were created and ran within the Windows PowerShell ISE.

Time for some PowerShell interactive user, copy and paste, PowerShell text/code/actions.

Always have a good idea (understanding) of what any text/code/action will do.

Code: Select all


# Adjust to the user's location of the midi file's path.

$forumShorterPathPart1 = "$env:USERPROFILE\Documents\DawPsDemo\Acoustica\"
$forumShorterPathPart2 = "Mixcraft Teachers Materials\mixcraft-teachers-guide-additional-"
$forumShorterPathPart3 = "materials\Sample Projects\Lesson 11 - MIDI Instrument Survey Project"

$midiFilesDirectoryPath = $forumShorterPathPart1 + $forumShorterPathPart2 + $forumShorterPathPart3

$midiFilePath = Get-ChildItem -Path "$midiFilesDirectoryPath\Hush Little Baby.mid"

Write-Host
Write-Host "Using the below midi file path:"
Write-Host $midiFilePath -ForegroundColor Yellow

PS returns (and no errors).

Using the below midi file path:
C:\Users\UserId\Documents\DawPsDemo\Acoustica\Mixcraft Teachers Materials\
mixcraft-teachers-guide-additional-materials\Sample Projects\
Lesson 11 - MIDI Instrument Survey Project\Hush Little Baby.mid


Okay what are the above midi file's header's complete data settings?

Code: Select all


$midiCompleteHeaderData = Get-Content -Path $midiFilePath -TotalCount 14 -Encoding Byte

Write-Host
Write-Host "What is the header marker's data? " -NoNewline

$headerRawData = $midiCompleteHeaderData[0..3]

$headerData = ""

$headerRawData.ForEach({ $headerData += $PSItem.ToChar($null) })

Write-Host $headerData -ForegroundColor Cyan

Write-Host
Write-Host "What is the header's data size? " -NoNewline

$headerDataSize = $midiCompleteHeaderData[7]

Write-Host $headerDataSize -ForegroundColor Cyan 

Write-Host
Write-Host "What is the midi file type? " -NoNewline

Switch ($midiCompleteHeaderData[9]) { 
  0 { Write-Host "0 " -NoNewline -ForegroundColor Cyan
      Write-Host "Single Track" -ForegroundColor Green
    }
  1 { Write-Host "1 " -NoNewline -ForegroundColor Cyan
      Write-Host "Multiple Track" -ForegroundColor Green
    } 
  2 { Write-Host "2 " -NoNewline -ForegroundColor Cyan
      Write-Host "Sequential Track" -ForegroundColor Green
    }  
} # End of Switch ($midiCompleteHeaderData[9]) { }.

Write-Host
Write-Host "What is the number of tracks? " -NoNewline

$firstTrackNumberTotal = $midiCompleteHeaderData[10] * 256
$numberOfTracks = $firstTrackNumberTotal + $midiCompleteHeaderData[11]

Write-Host $numberOfTracks -ForegroundColor Cyan

Write-Host
Write-Host "What is the Ticks Per Quarter Note? " -NoNewline

$firstTicksNumberTotal = $midiCompleteHeaderData[12] * 256
$ticksPerQuarterNote = $firstTicksNumberTotal + $midiCompleteHeaderData[13]

Write-Host $ticksPerQuarterNote -ForegroundColor Cyan

PS returns (and no errors).

What is the header marker's data? MThd

What is the header's data size? 6

What is the midi file type? 1 Multiple Track

What is the number of tracks? 2

What is the Ticks Per Quarter Note? 1000

There's an even easier way to read midi files, via midi-in-text app usage. And as the post reader
will soon see, PowerShell works great with midi-in-text's data.
jwmix
Posts: 39
Joined: Mon Apr 30, 2018 12:06 pm

Re: It is Mixcraft time

Post by jwmix »

The poster will show how useful,
the Windows PowerShell ISE can be,
when used as a music data controller,
by running a midi-in-text app
and then using the midi-in-text app's returned data.

And so all can read and play along, the poster will use one of Mixcraft's teacher's midi files.

https://acoustica.com/mixcraft-10-teach ... troduction

There's a zip file in the second paragraph using the above Mixcraft location.

Download it. Scan it. Place it wherever the post reader wants to place it.

Then in the PowerShell text/code/actions below, be sure to change the midi path into the post
reader's midi file path.

Also needed to play along, are the two midi-in-text apps, midicsv.exe and csvmidi.exe, found at:

https://www.fourmilab.ch/webtools/midicsv/

Both files are in one Windows zip file (located near the middle of the webpage) and while there,
read the whole webpage (the poster often does).

Download it. Scan it. Unzip it. Place them wherever the post reader wants to place them.

Then in the PowerShell text/code/actions below, be sure to change the poster's midi-in-text paths,
into the post reader's midi-in-text paths.

Note: All of the PowerShell text/code/actions were created and ran within the Windows PowerShell ISE.

Time for some PowerShell interactive user, copy and paste, PowerShell text/code/actions.

Always have a good idea (understanding) of what any text/code/action will do.

Code: Select all


# Adjust to the user's location of the midi file's path.

$forumShorterPathPart1 = "$env:USERPROFILE\Documents\DawPsDemo\Acoustica\"
$forumShorterPathPart2 = "Mixcraft Teachers Materials\mixcraft-teachers-guide-additional-"
$forumShorterPathPart3 = "materials\Sample Projects\Lesson 11 - MIDI Instrument Survey Project"

$midiFilesDirectoryPath = $forumShorterPathPart1 + $forumShorterPathPart2 + $forumShorterPathPart3

$midiFilePath = Get-ChildItem -Path "$midiFilesDirectoryPath\Hush Little Baby.mid"

Write-Host
Write-Host "Using the below midi file path:"
Write-Host $midiFilePath -ForegroundColor Yellow

# Adjust to the user's location of the midi-in-text app's path.

$midiToCsvAppPath = "$env:USERPROFILE\Documents\Midi\Apps\Midicsv.exe"

Write-Host
Write-Host "Using the below midi-in-text app's file path:"
Write-Host $midiToCsvAppPath -ForegroundColor Yellow

# The next below path will become the file name and location of the
# soon to be created midi-in-text csv file (this is a human readable midi csv file's data). 

# Adjust to where the user will save this new midi-in-text csv file path.

$midiInTextCsvFilePath = "$env:USERPROFILE\Documents\DawPsDemo-New-Hush Little Baby.csv"  

Write-Host
Write-Host "Below is the soon to be created midi-in-text csv file path:"
Write-Host $midiInTextCsvFilePath -ForegroundColor Yellow

[code]

PS returns (and no errors).

Using the below midi file's path:
[color=yellow]C:\Users\UserId\Documents\DawPsDemo\Acoustica\Mixcraft Teachers Materials\mixcraft-teachers-guide-additional-materials\Sample Proj
ects\Lesson 11 - MIDI Instrument Survey Project\Hush Little Baby.mid[/color]

Using the below midi-in-text app's file path:
[color=yellow]C:\Users\UserId\Documents\Midi\Apps\Midicsv.exe[/color]

Below is the soon to be created midi-in-text csv file's path:
[color=yellow]C:\Users\UserId\Documents\DawPsDemo-New-Hush Little Baby.mid.csv[/color] 

Okay all of the files are defined. Now it's time to show how midicsv.exe works within the Windows
PowerShell ISE. Windows PowerShell has a Run/Invoke operator which is the Ampersand ( & ) 
character, so on the PowerShell command line all one needs to do is:

PS > & "Full\Path\To\MidiCsv.exe" "Full\Path\To\FileName.mid" 

and the midi-in-text csv data displays in the PowerShell window. Note large files will cause the
PowerShell window to scroll and scroll. 

Or in the same PowerShell window, on the command line, to send the midi-in-text csv data to a file,
all one needs to do is:

PS > & "Full\Path\To\MidiCsv.exe" "Full\Path\To\MidiFile.mid" "Full\Path\To\FileName.csv"

and PowerShell creates the new "Full\Path\To\FileName.csv" file.

But the Windows PowerShell ISE uses nice pop up windows with information about the object and the
Ampersand ( & ) character's usage upset's the ISE's pop up windows routines. So the poster, when not
working on just the PowerShell window's command line, or within a PowerShell scripting ( .ps1 )
file, then the poster puts the Ampersand ( & ) command line PowerShell text/code/actions within a
PowerShell script block - { this is the script block's PowerShell text/code/actions } and the
Ampersand now works fine within the ISE.

The poster will now, via a PowerShell script block, create the midi-in-text's csv file and then use
the text/binary reader cmdlet, named Get-Content. The output produced by Get-Content (all of the
midi-in-text csv file lines) will then be piped via the PowerShell pipe ( | ) character or passed
to the Out-GridView cmdlet, that will display all of the csv data lines into a interactive searchable
PowerShell window/app.

[url]https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/out-gridview?view=powershell-5.1[/url]

The interactive table in the Out-GridView window is a very useful music data controller tool for
all sorts of Mixcraft file viewings and file searches. And the Out-GridView window can send back
one's selected data (then closes) or it can be kept open, until the user closes it (or it's parent
window, the PowerShell ISE closes). Plus any selected data can be user Ctrl + C copied. 

[code]

$createMidiInTextCsvFile = { 
  # The character ( & ) is the PowerShell run operator.
  & "$midiToCsvAppPath" "$midiFilePath" "$midiInTextCsvFilePath"
} # End of $createMidiInTextCsvFile = { }.

Invoke-Command -ScriptBlock $createMidiInTextCsvFile

$title = $midiInTextCsvFilePath

Get-Content -Path $midiInTextCsvFilePath | 
  Out-GridView -Title $title
  
PS returns nothing (and no errors).

But the Out-GridView window opens displaying one line of text for each midi file action.

If the text of the Out-GridView window is too small, just press Ctrl + any key with a plus ( + )
sign, and the text increases it's size (Ctrl + Minus ( - ) sign decreases the text's size). Three
times is a nice size.

Now in the textbox with the word Filter in it, type h - now only lines with a H/h in them are
displayed. Only one line shows up. The poster highlights it (by selecting it) and here is the
Ctrl + C copy:

0, 0, Header, 1, 2, 1000

Ohhhh there is the midi header data (and with all the math done by the midicsv.exe app).

What all of the data, for that header line means, will be shown later, when PowerShell reads the
csv file with the cmdlet named, Import-Csv, which will also use a separate header defined for
almost each of the user's needed midi event types.

Okay in the Out-GridView window's filter textbox, backspace away the h and all of the csv lines
reappear and the selected line is lightly highlighted (and if it was in the middle of all of the
text lines, then the lightly highlighted line would be near the bottom of the window). Now the user
can scroll down or up, to see the before and after line's data (to see what was happening).

The poster once said always check for more than one Set Tempo Midi Meta Event. So in the filter
textbox type t. There are a lot of lines with a t, so type e. There are a lot of lines with te,
so type m - Bingo, here is the Ctrl + C copied data:

1, 0, Tempo, 600000

Ahh looks familiar and there is only one Set Tempo event in this file. Okay leave this Out-GridView
open (to maybe check other data returns) and the poster is moving on to using the Import-Csv cmdlet
(think command).

Okay the poster, via the Out-GridView csv data, saw that there is no csv header line, so the
poster will create some helpful header statements for usage with the Import-Csv cmdlet and the
midicsv.exe's csv data.

Code: Select all


$basicHeader = "Track", "Timing", "MidiEvent"

$headerHeader = $basicHeader + "FileType", "NumberOfTracks", "TicksPerQuarterNote"

$tempoHeader = $basicHeader +  "Tempo"

$programHeader = $basicHeader + "Channel", "ProgramNumber"

$controlHeader = $basicHeader + "Data1", "Data2", "Data3"

$noteHeader = $basicHeader + "Channel", "NoteNumber", "Velocity"

$searchAllHeader = $basicHeader +  "Data1", "Data2", "Data3", "Data4", "Data5", "Data6"

Write-Host
Write-Host "What is the midi file's header data?"

Import-Csv -Path $midiInTextCsvFilePath -Header $headerHeader | 
  Where-Object -Property MidiEvent -Match "head" | 
    Out-Default

Import-Csv -Path $midiInTextCsvFilePath -Header $headerHeader | 
  Where-Object -Property MidiEvent -Match "head" | 
    Format-Table -AutoSize | 
      Out-Default

To correctly keep the PowerShell's outputted format,
the PowerShell output is also placed within a code section too.
(Not code, just the formatted outputted data.)

Code: Select all


What is the midi file's header data?

Track               : 0
Timing              : 0
MidiEvent           : Header
FileType            : 1
NumberOfTracks      : 2
TicksPerQuarterNote : 1000


Track Timing MidiEvent FileType NumberOfTracks TicksPerQuarterNote
----- ------ --------- -------- -------------- -------------------
0     0      Header    1        2              1000               

Wow, for that special certain band member/artist/client/boss/grandma who likes, a wee bit more
clarification/information this is better than Hexadecimal or Byte midi file reading output.

The poster will now store all of the csv data (this is a small csv file) into memory for later
usage (less disk readings).

Code: Select all


$allOfTheCsvData = Get-Content -Path $midiInTextCsvFilePath

Write-Host
Write-Host "Stored into memory " -NoNewline

$formmatedLineCount = "{0:n0}" -f $allOfTheCsvData.Count 

Write-Host "$formmatedLineCount " -NoNewline -ForegroundColor Cyan
Write-Host "lines of csv data."

PS returns (and no errors).

Stored into memory 83 lines of csv data.

Now the poster will use that stored into memory data but Import-Csv requires a file path,
so instead the poster will use the cmdlet ConvertFrom-Csv. And also remember that the variable
$PSItem is the current object in the pipeline.

Code: Select all


$findNoteNumber = 62

Write-Host
Write-Host "Any midi Channel Note Events with the midi number " -NoNewline
Write-Host $findNoteNumber -NoNewline -ForegroundColor Cyan
Write-Host "?"

$allOfTheCsvData | 
  ConvertFrom-Csv -Header $noteHeader | 
    Where-Object -FilterScript { 
      $PSItem.midievent -match "note" -and $PSItem.NoteNumber -eq $findNoteNumber 
    } | # End of Where-Object -FilterScript { }. 
        Format-Table -AutoSize | 
          Out-Default

Write-host
Write-Host "Are there any Midi Channel Program Events?"

$allOfTheCsvData | 
  ConvertFrom-Csv -Header $programHeader | 
    Where-Object -FilterScript {
      $PSItem.midievent -match "prog" 
    } | # End of Where-Object -FilterScript { }. 
        Format-Table -AutoSize | 
          Out-Default

Write-Host
Write-Host "And for those 'I think there is an issue between this time and that time' troubles:"
 
$startTime = 20000
$endTime = 25000

Write-Host
Write-Host "Any midi events between the midi timing of " -NoNewline
Write-Host "$startTime " -NoNewline -ForegroundColor Cyan
Write-Host "and " -NoNewline
Write-Host $endTime -NoNewline -ForegroundColor Cyan
Write-Host "?"

$allOfTheCsvData | 
  ConvertFrom-Csv -Header $searchAllHeader | 
    Where-Object -FilterScript { 
      [int]$PSItem.timing -ge $startTime -and [int]$PSItem.Timing -le $endTime  
    } | # End of Where-Object -FilterScript { }. 
        Format-Table -AutoSize | 
          Out-Default

$startTime = 0
$endTime = 1500

Write-Host
Write-Host "Any midi events between the midi timing of " -NoNewline
Write-Host "$startTime " -NoNewline -ForegroundColor Cyan
Write-Host "and " -NoNewline
Write-Host $endTime -NoNewline -ForegroundColor Cyan
Write-Host "?"

$allOfTheCsvData | 
  ConvertFrom-Csv -Header $searchAllHeader | 
    Where-Object -FilterScript { 
      [int]$PSItem.timing -ge $startTime -and [int]$PSItem.Timing -le $endTime  
    } | # End of Where-Object -FilterScript { }. 
        Format-Table -AutoSize | 
          Out-Default

Write-host
Write-Host "Any midi Continuous Controllers Events such as CC 7 or CC 64?"

$allOfTheCsvData | 
  ConvertFrom-Csv -Header $controlHeader | 
    Where-Object -FilterScript {
      $PSItem.midievent -match "cont" 
    } | # End of Where-Object -FilterScript { }.
        Format-Table -AutoSize | 
          Out-Default

To correctly keep the PowerShell's outputted format,
the PowerShell output is also placed within a code section too.
(Not code, just the formatted outputted data.)

Code: Select all


Any midi Channel Note Events with the midi number 62?

Track Timing MidiEvent  Channel NoteNumber Velocity
----- ------ ---------  ------- ---------- --------
2     0      Note_on_c  0       62         100     
2     1000   Note_off_c 0       62         0       
2     8000   Note_on_c  0       62         100     
2     8500   Note_off_c 0       62         0       
2     8500   Note_on_c  0       62         100     
2     9000   Note_off_c 0       62         0       
2     15500  Note_on_c  0       62         100     
2     16000  Note_off_c 0       62         0       
2     16000  Note_on_c  0       62         100     
2     17000  Note_off_c 0       62         0       
2     24000  Note_on_c  0       62         100     
2     24500  Note_off_c 0       62         0       
2     24500  Note_on_c  0       62         100     
2     25000  Note_off_c 0       62         0       


Are there any Midi Channel Program Events?

Track Timing MidiEvent Channel ProgramNumber
----- ------ --------- ------- -------------
2     0      Program_c 0       73           


And for those 'I think there is an issue between this time and that time' troubles:

Any midi events between the midi timing of 20000 and 25000?

Track Timing MidiEvent  Data1 Data2 Data3 Data4 Data5 Data6
----- ------ ---------  ----- ----- ----- ----- ----- -----
2     20000  Note_off_c 0     72    0                      
2     20000  Note_on_c  0     71    100                    
2     21000  Note_off_c 0     71    0                      
2     21000  Note_on_c  0     69    100                    
2     22000  Note_off_c 0     69    0                      
2     22000  Note_on_c  0     69    100                    
2     24000  Note_off_c 0     69    0                      
2     24000  Note_on_c  0     62    100                    
2     24500  Note_off_c 0     62    0                      
2     24500  Note_on_c  0     62    100                    
2     25000  Note_off_c 0     62    0                      
2     25000  Note_on_c  0     69    100                    


Any midi events between the midi timing of 0 and 1500?

Track Timing MidiEvent      Data1  Data2 Data3 Data4 Data5 Data6
----- ------ ---------      -----  ----- ----- ----- ----- -----
0     0      Header         1      2     1000                   
1     0      Start_track                                        
1     0      Tempo          600000                              
1     0      Time_signature 4      2     24    8                
1     0      End_track                                          
2     0      Start_track                                        
2     0      Program_c      0      73                           
2     0      Note_on_c      0      62    100                    
2     1000   Note_off_c     0      62    0                      
2     1000   Note_on_c      0      71    100                    
2     1500   Note_off_c     0      71    0                      
2     1500   Note_on_c      0      71    100                    
0     0      End_of_file                                        


Any midi Continuous Controllers Events such as CC 7 or CC 64?

Note the last action, Any midi Continuous Controllers Events found nothing.

Did anyone notice the cast from a string object, for the $PSItem.timing (the csv data) into an
[int]$PSItem.timing object, for the needed math actions?

Well that's an introduction to the Windows PowerShell ISE as a music data controller using the
midi-in-text app midicsv.exe. Usage of the other midi-in-text app csvmidi.exe that creates a new
midi file out of csv data will be another later post.

There are so many exciting and useful PowerShell text/code/actions, covering so many different
types of text/code/actions that will help with the post reader's audio/midi/sounds needs, that the
poster is showing as many ways as possible. The old walk before one runs.

The poster will most likely move on to other introductions, such as searching the log file, certain
three party libraries usage, Windows OS system usage (like the top most window and such actions) and
other such fun and helpful music creation actions.

And yes post readers, feel free to start one's own Tips and Tricks posts conerning one's PowerShell
usage where that one post's subject can be better covered, via all of the helpful PowerShell ISE
music data contoller users.
jwmix
Posts: 39
Joined: Mon Apr 30, 2018 12:06 pm

Re: It is Mixcraft time

Post by jwmix »

The poster will test some Mixcraft objects to see if they are Portable Executable (PE) objects and
if they are a PE type of object, are they a 32 bit or a 64 bit object. The poster never judges an
object by it's name.

https://en.wikipedia.org/wiki/Portable_Executable

Note: All of the PowerShell text/code/actions were created and ran within the Windows PowerShell ISE.

Time for some PowerShell interactive user, copy and paste, PowerShell text/code/actions.

Always have a good idea (understanding) of what any text/code/action will do.

Code: Select all


$mixcraftVstToolsFilePaths = Get-ChildItem -Path "$env:ProgramFiles\Acoustica Mixcraft 10" -Filter "*t.exe" 

$mixcraftVstToolsFilePaths.ForEach({ 
  Write-Host
  Write-Host "Is " -NoNewline

  # $_ and $PSItem are both PowerShell defined variables 
  # that reference the current pipeline object.

  Write-Host $PSItem.Name -NoNewline -ForegroundColor Cyan
  Write-Host " a Portable Executable (PE) object? " -NoNewline
  
  $foundMzBytes = Get-Content -Path $PSItem.FullName -TotalCount 2 -Encoding Byte

  If($foundMzBytes[0] -eq 77 -and $foundMzBytes[1] -eq 90) { 
    Write-Host "Yes " -NoNewline -ForegroundColor Cyan
    Write-Host "Found " -NoNewline 
    Write-Host $foundMzBytes[0].ToChar($null) -NoNewline -ForegroundColor Cyan
    Write-Host $foundMzBytes[1].ToChar($null) -NoNewline -ForegroundColor Cyan
    Write-Host "."

    Write-Host
    Write-Host "Is it a 32 bit or 64 bit object?"
    
    $hexadecimalDecimalAsciiData = Format-Hex -Path $PSItem.FullName | 
      Select-String -Pattern "pe" -SimpleMatch | 
        Select-Object -First 1
    
    Write-Host
    Write-Host $hexadecimalDecimalAsciiData 
    
    If($hexadecimalDecimalAsciiData -match "PE..L") { 
      Write-Host
      Write-Host "It is a 32 bit object."
    } # End of If($hexadecimalDecimalAsciiData -match "PE..L") { }.
    ElseIf($hexadecimalDecimalAsciiData -match "PE..d") { 
      Write-Host
      Write-Host "It is a 64 bit object."
    } # End of If($hexadecimalDecimalAsciiData -match "PE..d") { }.
  } # End of If($foundMzBytes[0] -eq 77 -and $foundMzBytes[1] -eq 90) { }.
  Else { 
    Write-Host "No" -ForegroundColor Red
    Write-Host "So there is no need to look for the 32 or 64 bit setting."
  } # End of Else { }.
}) # End of $mixcraftVstToolsFilePaths.ForEach({ }).

PS returns (and no errors).

Is Mixcraft32BitVST.exe a Portable Executable (PE) object? Yes Found MZ.

Is it a 32 bit or 64 bit object?

00000100 00 00 00 00 00 00 00 00 50 45 00 00 4C 01 05 00 ........PE..L...

It is a 32 bit object.

Is Mixcraft64BitVST.exe a Portable Executable (PE) object? Yes Found MZ.

Is it a 32 bit or 64 bit object?

000000F0 00 00 00 00 00 00 00 00 50 45 00 00 64 86 06 00 ........PE..d†..

It is a 64 bit object.

The usage of the Format-Hex and the Select-String PE and the Select-Object -First 1 has worked
(so far, but your usage may vary). But the poster does recall that it did not work with one object
(and the poster does not remember what it was), but it turned out to be the second ( 2 ) PE found.

Also watch when doing Format-Hex searchs. The found data could be split between two Format-Hex
outputted lines.

00 00 00 00 00 00 00 00 50 45 00 00 ........PE..
64 86 06 00 00 00 00 00 00 00 00 00 d...........

00 00 00 00 00 00 00 50 .........P
45 00 00 64 86 06 00 00 E..d......

And other such two line splits. If the found object is split, try using:

Select-String -Pattern "pe" -SimpleMatch -Context 0,1

which shows the found line, and the next line, after the found line.

Code: Select all


$mixcraftVstToolsFilePaths = Get-ChildItem -Path "$env:ProgramFiles\Acoustica Mixcraft 10" -Filter "*t.exe" 	

$hexadecimalDecimalAsciiData = Format-Hex -Path $mixcraftVstToolsFilePaths[0].FullName | 	
  Select-String -Pattern "pe" -SimpleMatch -Context 0,1 | 	
    Select-Object -First 1	

$hexadecimalDecimalAsciiData | 
  Out-Default

To correctly keep the PowerShell's outputted format,
the PowerShell output is also placed within a code section too.
(Not code, just the formatted outputted data.)

Code: Select all


> 00000100   00 00 00 00 00 00 00 00 50 45 00 00 4C 01 05 00  ........PE..L...
  00000110   2D 48 00 67 00 00 00 00 00 00 00 00 E0 00 22 01  -H.g........à.".

What happens if the object is not a PE object?

Note: Using a Regex Pattern where the character ( | ) in Regex means the or operator.

Code: Select all


$someMixcraftFilePaths = Get-ChildItem -Path "$env:ProgramFiles\Acoustica Mixcraft 10\*" | 
  Where-Object -Property Extension -Match ".csv|.wav" 

$someMixcraftFilePaths.ForEach({ 
  Write-Host
  Write-Host "Is " -NoNewline
  Write-Host $PSItem.Name -NoNewline -ForegroundColor Cyan
  Write-Host " a Portable Executable (PE) object? " -NoNewline
  
  $firstTwoBytes = Get-Content -Path $PSItem.FullName -TotalCount 2 -Encoding Byte
  
  If($firstTwoBytes[0] -eq 77 -and $fistTwoBytes[1] -eq 90) { 
    Write-Host "Yes " -ForegroundColor Cyan
  } # End of If($firstTwoBytes[0] -eq 77 -and $fistTwoBytes[1] -eq 90) { }.
  Else { 
    Write-Host "No" -ForegroundColor Red

    # Actions in parentheses ( actions ) run first, 
    # then any other line statements/actions run.

    Write-Host ($firstTwoBytes -join " ")
    Write-Host "So there is no need to look for the 32 or 64 bit setting."
  } # End of Else { }.
}) # End of $someMixcraftFilePaths.ForEach({ }).

PS returns (and no errors).

Is HighTone.wav a Portable Executable (PE) object? No
82 73
So there is no need to look for the 32 or 64 bit setting.

Is LowTone.wav a Portable Executable (PE) object? No
82 73
So there is no need to look for the 32 or 64 bit setting.

Is skins.csv a Portable Executable (PE) object? No
83 107
So there is no need to look for the 32 or 64 bit setting.

Is SquareTick-High.wav a Portable Executable (PE) object? No
82 73
So there is no need to look for the 32 or 64 bit setting.

Is SquareTick-Low.wav a Portable Executable (PE) object? No
82 73
So there is no need to look for the 32 or 64 bit setting.

Note: The above PowerShell text/code/actions can also be adjusted to find out
if an object is likely to be a VST/plugin object too.

Use the object's full path ("Full\Path\To\Object") and then try the Regex pattern used below and
do not use the -SimpleMatch parameter. The run time is (usually) less than a minute (but when the
post reader is waiting, it always seems longer). And ten ( 10 ) finds is (usually) enough.

Note: Using a Regex Pattern where the characters ( .+ ) in Regex means any characters.

Code: Select all


Format-Hex -Path "$env:USERPROFILE\Documents\DawPsDemo-CopyOf-AnyName.AnyThing" | 
  Select-String -Pattern ".+vst.+" | 
    Select-Object -First 10 | 
      Out-Default

To correctly keep the PowerShell's outputted format,
the PowerShell output is also placed within a code section too.
(Not code, just the formatted outputted data.)

Code: Select all


0002BF50   76 53 74 72 00 CC CC CC CC CC CC CC CC CC CC CC  vStr.ÌÌÌÌÌÌÌÌÌÌÌ
00192800   3A 3A 49 50 6C 75 67 56 53 54 00 00 00 00 00 00  ::IPlugVST......
00192820   49 50 6C 75 67 56 53 54 3A 3A 56 53 54 44 69 73  IPlugVST::VSTDis
00192850   64 00 00 00 56 53 54 43 61 6E 44 6F 28 25 73 29  d...VSTCanDo(%s)
00192860   00 00 00 00 72 65 63 65 69 76 65 56 73 74 54 69  ....receiveVstTi
00192880   56 73 74 45 76 65 6E 74 73 00 00 00 73 65 6E 64  VstEvents...send
00192890   56 73 74 4D 69 64 69 45 76 65 6E 74 00 00 00 00  VstMidiEvent....
001928A0   72 65 63 65 69 76 65 56 73 74 45 76 65 6E 74 73  receiveVstEvents
001928B0   00 00 00 00 72 65 63 65 69 76 65 56 73 74 4D 69  ....receiveVstMi
00192900   25 64 00 00 49 50 6C 75 67 56 53 54 3A 3A 56 53  %d..IPlugVST::VS

What does the post reader think?

Is it likely a VST/plugin type of object?

Yeap, the poster says object a lot, because everything in PowerShell is an object,
which carries around properties (data) and methods (actions on that data) with the object,
even through out the pipeline.

Anyway,
this is just another tool,
for the Windows PowerShell ISE to use,
when the ISE is being used as a music data controller.
jwmix
Posts: 39
Joined: Mon Apr 30, 2018 12:06 pm

Re: It is Mixcraft time

Post by jwmix »

The poster will read some Comma Separated Values (.csv) files. Csv files (usually) consist of
the first line being a header line - a list of field names separated (usually) by a comma.

Here is a header line example, with field names separated by a comma (from a file named Dogs.csv).

Name,Breed,Health,Grooming

After the header line, then there are data lines, that display the data in the header names layout
pattern. Once again, a comma separates the data. If there is no data for a certain header's field,
then there will only be a comma.

Rover,mutt,Okay,Bald
4856,Bulldog,,Curly
Lassie,Collie,Great,Hairy

So combining both of the above examples:

Name,Breed,Health,Grooming
Rover,mutt,Okay,Bald
4856,BullDog,,Curly
Lassie,Collie,Great,Hairy

Large CSV files with many header names and tons of rows (lines of data) are really hard to read
when using a text reader like Notepad.exe. That's why people use Excel type of apps.

PowerShell can create/read/search/change CSV files (and many other types of files). It can also
use any separating character (not just a comma). It can also read CSV based files without a header
file, by allowing the PowerShell user to define a stand alone header, that will be used with that
headerless CSV based file.

Note: For example, when the poster is working with midi in text csv files,
the poster uses user created headers defined via PowerShell text/code/actions (but this post is
not about midi-in-text).

The poster will use some of the Daw app, Mixcraft 10's CSV based files.

Note: All of the PowerShell text/code/actions were created and ran within the Windows PowerShell ISE.

Time for some PowerShell interactive user, copy and paste, PowerShell text/code/actions.

Always have a good idea (understanding) of what any text/code/action will do.

Code: Select all


$mixcraftProgramDataPath = "$env:ProgramData\Acoustica\Mixcraft"

$csvFilePath = "$mixcraftProgramDataPath\plugin-mods.csv"

Get-ChildItem -Path $csvFilePath | 
  Out-Default

To correctly keep the PowerShell's outputted format,
the PowerShell output is also placed within a code section too.
(Not code, just the formatted outputted data.)

Code: Select all



    Directory: C:\ProgramData\Acoustica\Mixcraft


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         7/27/2024   6:01 PM          19686 plugin-mods.csv

Mmm, but is it a CSV based file, with the first line of the file, a header fields named line,
that all of the other file's data lines, follow and use?

The poster will find out (this time) by reading the first line of the CSV based file with the
PowerShell text and binary reader cmdlet (think command) named Get-Content.

Code: Select all


Get-Content -Path $csvFilePath | 
  Select-Object -First 1 | 
    Out-Default

PS returns (and no errors).

Name,UUID,MaxSampleRate,RunNonDPIAware,forceSize,extraPresetNotifications,vst3releaseOnReset,
safeModeByDefault,fileDate (yyyy-mm-dd),version,noVST3QueryViewCapabilities,DisabledByDefault,
optionalWarning

Yeap, pretty hard to text read CSV based data (and this is just the header's field names).

Okay here's some PowerShell text/code/actions CSV ways, and instead of always running the cmdlet
(think command) named Import-Csv for each action after action, well, instead
the poster will run Import-Csv once, and then store the returned CSV based data into memory, that
will be accessible via a variable's name, for later usage of the CSV's data, over and over again.

Code: Select all


$pluginModsCsvData = Import-Csv -Path $csvFilePath

Write-Host
Write-Host "The number of lines within " -NoNewline
Write-Host '$pluginModsCsvData ' -NoNewline -ForegroundColor Green
Write-Host "is " -NoNewline
Write-Host $pluginModsCsvData.Count -NoNewline -ForegroundColor Cyan
Write-Host "."

Write-Host
Write-Host "What type of object is the first line? " -NoNewline
Write-Host $pluginModsCsvData[0].GetType().FullName -NoNewline -ForegroundColor Green
Write-Host "."

Write-Host 
Write-Host "The number of plugin objects within the csv file is " -NoNewline

$pluginNameCount = $pluginModsCsvData | 
  Select-Object -Property Name | 
    Measure-Object -Property Name 

Write-Host $pluginNameCount.Count -NoNewline -ForegroundColor Cyan
Write-Host  "."

Write-Host
Write-Host "Using only the first and the last objects (plugins), " -NoNewline
Write-Host "to show the returned csv data."

$pluginModsCsvData | 
  Select-Object -First 1 -Last 1 | 
    Out-Default

PS returns (and no errors).

The number of lines within $pluginModsCsvData is 251.

What type of object is the first line? System.Management.Automation.PSCustomObject.

The number of plugin objects within the csv file is 251.

To correctly keep the PowerShell's outputted format,
the PowerShell output is also placed within a code section too.
(Not code, just the formatted outputted data.)

Code: Select all


Using only the first and the last objects (plugins), to show the returned csv data.

Name                        : AAS Journeys VST2
UUID                        : 305a4d33000000000000000000000000
MaxSampleRate               : 0
RunNonDPIAware              : 1
forceSize                   : 0
extraPresetNotifications    :
vst3releaseOnReset          :
safeModeByDefault           :
fileDate (yyyy-mm-dd)       :
version                     :
noVST3QueryViewCapabilities :
DisabledByDefault           :
optionalWarning             :

Name                        : Archetype Gojira X
UUID                        : 230739E4-0000-0000-0000-000000000000
MaxSampleRate               :
RunNonDPIAware              :
forceSize                   :
extraPresetNotifications    :
vst3releaseOnReset          :
safeModeByDefault           :
fileDate (yyyy-mm-dd)       :
version                     :
noVST3QueryViewCapabilities :
DisabledByDefault           : 1
optionalWarning             : Freezes Mixcraft and Juce hosts 7 & 8

Notice that the file line count is the same as the plugin count? This is how a csv file works.

The above left list is the header's field names and the right list is the header's field's data.
There seems to be many blank header field's (no data), in both of the above two plugins, and in
fact, in all of the plugins.

But what if a post reader wants only the header's names to get some certain headers' data?

Remember, PowerShell has both an interactive user way (commonly called the command line style),
plus the other PowerShell scripting style, where one passes in the name of the file (or object),
plus the file's data's needed names, to an already written PowerShell scripting (.ps1) file (this
is commonly called the PowerShell scripting file style).

Scripting usage (usually) uses PowerShell text/code/actions stored within a PowerShell module:

https://learn.microsoft.com/en-us/power ... rshell-5.1

Or stored within a PowerShell function:

https://learn.microsoft.com/en-us/power ... rshell-5.1


Then the module/function is loaded into memory and used within a script (or even within the user
interactive way).

It's called write the PowerShell fuction/module/script once, which by the way, can be written by
bunch of the Daw app's users, working together on the PowerShell text/code/actions, as a group
activity. In the forums it seems there are posts where a few of the post readers/posters say
"as a techy/software/programmer/whatever".... they could/would surely get involved.

So create a new post (most likey in the Tips and Tricks forum) and supply what one has done and see
if any other post readers jump in to help.

Then every Daw app's users can run that group developed PowerShell text/code/actions (as a user tool
via command lines/modules/fuctions) forever, within the PowerShell ISE as a music data controller.

Note: There are also two user PowerShell writing styles/formats too.

There is the fully named everything format, that uses fully named cmdlets, fully named cmdlet's
parameters, fully named paths and other such fully named objects. This PowerShel format writing way,
is known as the fully named everything style, and should be used when ever others will be reading
the poster's PowerShell text/code/actions and always in any scripting file. Because by using the
fully named everything format, it sort of also self documents the PowerShell text/code/actions,
showing what exactly is happening within that fully named PowerShell text/code/actions.

The other PowerShell writing format is the less typing command line format, which uses less typing
of cmdlet names,

https://learn.microsoft.com/en-us/power ... rshell-5.1


less typing of cmdlet's parameters, less typing of Windows paths by using Windows wildcard paths and
other such less typing objects. This less typing PowerShell style/format is meant to be used only
when the user/writer is alone, because this is the only time that the user/writer will not hear the
question, "What does rvpa $home\doc*\da*o\t*junk*y\aco*a\m*0\... really do?

Okay, the poster is moving on back to CSV usage ways in the style of fully named everything using
interactive user's PowerShell text/code/actions. So now the poster will get the header field names
in another way, by using the very first line within the memory saved csv data lines.

Code: Select all


$pluginModsCsvDataHeaders = $pluginModsCsvData[0].psobject.properties.Where({
  $PSItem.MemberType -eq "NoteProperty" }).Name

Write-Host
Write-Host "What type of PowerShell object is the variable " -NoNewline

Write-Host '$pluginModsCsvDataHeaders' -NoNewline -ForegroundColor Green
Write-Host "?"

$pluginModsCsvDataHeaders.GetType() | 
  Out-Default

Write-Host
Write-Host "There are " -NoNewline
Write-Host $pluginModsCsvDataHeaders.Count -NoNewline -ForegroundColor Cyan
Write-Host " csv header field names."

Write-Host
$pluginModsCsvDataHeaders | 
  Out-Default

PS returns (and no errors).

What type of PowerShell object is the variable $pluginModsCsvDataHeaders.

To correctly keep the PowerShell's outputted format,
the PowerShell output is also placed within a code section too.
(Not code, just the formatted outputted data.)

Code: Select all


IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

There are 13 csv header field names.

Name
UUID
MaxSampleRate
RunNonDPIAware
forceSize
extraPresetNotifications
vst3releaseOnReset
safeModeByDefault
fileDate (yyyy-mm-dd)
version
noVST3QueryViewCapabilities
DisabledByDefault
optionalWarning

Okay that introduces getting only header names (if needed), now the poster will do various PowerShell
csv data actions, using the stored into memory csv data (accessible via the variable's name).

Search for Acoustica type of plugins.

Code: Select all


$find = "Acou"

$pluginModsCsvData | 
  Where-Object -Property Name -Match $find | 
    Select-Object Name, FileDate*, Version | 
      Out-Default

To correctly keep the PowerShell's outputted format,
the PowerShell output is also placed within a code section too.
(Not code, just the formatted outputted data.)

Code: Select all


Name                             fileDate (yyyy-mm-dd) version
----                             --------------------- -------
Acoustica 31 Band EQ VST2
Acoustica Pianissimo VST2
Acoustica Pro Studio Reverb VST2
Acoustica VocalZap VST2
Acoustica Vocoder VST2

Mmm, right now it seems most plugins only use the first few headers, even Mixcraft's own objects.

Code: Select all


$pluginModsCsvData | 
  Where-Object -Property Name -Match $find | 
    Format-Table -AutoSize -Property Name, UUID, Max*, Run*, ForceSize | 
      Out-Default

$pluginModsCsvData | 
  Where-Object -Property Name -Match $find | 
    Select-Object -First 1 | 
      Out-Default

To correctly keep the PowerShell's outputted format,
the PowerShell output is also placed within a code section too.
(Not code, just the formatted outputted data.)

Code: Select all


Name                             UUID                             MaxSampleRate RunNonDPIAware forceSize
----                             ----                             ------------- -------------- ---------
Acoustica 31 Band EQ VST2        33314571000000000000000000000000 0             1              0        
Acoustica Pianissimo VST2        506e536d000000000000000000000000 0             1              0        
Acoustica Pro Studio Reverb VST2 50535276000000000000000000000000 0             1              0        
Acoustica VocalZap VST2          565a6170000000000000000000000000 0             1              0        
Acoustica Vocoder VST2           4163566f000000000000000000000000 0             1              0        




Name                        : Acoustica 31 Band EQ VST2
UUID                        : 33314571000000000000000000000000
MaxSampleRate               : 0
RunNonDPIAware              : 1
forceSize                   : 0
extraPresetNotifications    : 
vst3releaseOnReset          : 
safeModeByDefault           : 
fileDate (yyyy-mm-dd)       : 
version                     : 
noVST3QueryViewCapabilities : 
DisabledByDefault           : 
optionalWarning             : 

A few of the heavy Mixcraft active post readers, have been interested in DPI (Dots Per Inch)
monitor's actions. The poster doesn't really do a lot of DPI actions. But the poster did read about
them, while also keeping an eye on how PowerShell could be used with Mixcraft's DIP actions too. The
poster will do an advanced PowerShell text/code/actions DPI post later, but for now, notice the
header named RunNonDPIAware. Mmm, how many plugins have any DPI settings?

Code: Select all


$pluginModsCsvData | 
  Where-Object -Property RunNonDPiAware -ge 0 | 
    Sort-Object -Descending -Property Run* | 
      Format-Table -AutoSize -Property Name, RunNonDPiAware | 
        Out-Default

To correctly keep the PowerShell's outputted format,
the PowerShell output is also placed within a code section too.
(Not code, just the formatted outputted data.)

Code: Select all


Name                                                RunNonDPIAware
----                                                --------------
Rob Papen Raw-Kick VST3                             1
Rob Papen RevSane VST3                              1
Rob Papen RG VST3                                   1
Rob Papen Raw VST3                                  1
Rob Papen Punch-BD Multi VST3                       1
Rob Papen Punch-BD VST3                             1
Rob Papen Quad VST3                                 1
Rob Papen RoCoder VST3                              1
Rob Papen RP-EQ VST3                                1
Rob Papen RP-Pan VST3                               1
Rob Papen RP-Reverse VST3                           1
Rob Papen RP-Distort2 VST3                          1
Rob Papen RP-Amod VST3                              1
Rob Papen RP-Delay VST3                             1
Rob Papen RP-Distort VST3                           1
QuikQuak Fusion Field VST2                          1
QuikQuak Glass Viper VST2                           1

and so on to 

G-Sonique VTD-42 Psychedelic Delay VST2             1
G-Sonique Twisthead VS-206 VST2                     1
Auto-Tune+Time_VST                                  0
Messiah 2                                           0
NI Komplete Kontrol VST2                            0
ME80v2.5                                            0

If interested in seeing the full list, just run the PowerShell text/code/actions.

What if a post reader is looking for a plugin's name? And the post reader is only interesed in
that plugin's data?

In the below poster's PowerShell text/code/actions, some PowerShell -Match operator actions are
used and are done via Regex Patterns.

https://learn.microsoft.com/en-us/dotne ... xpressions

The Regex characters ( .+ ) means any following characters.

Code: Select all


Import-Csv -Path $csvFilePath | 
  Where-Object -Property name -Match "aco.+pro" | 
    Out-Default

To correctly keep the PowerShell's outputted format,
the PowerShell output is also placed within a code section too.
(Not code, just the formatted outputted data.)

Code: Select all


Name                        : Acoustica Pro Studio Reverb VST2
UUID                        : 50535276000000000000000000000000
MaxSampleRate               : 0
RunNonDPIAware              : 1
forceSize                   : 0
extraPresetNotifications    :
vst3releaseOnReset          :
safeModeByDefault           :
fileDate (yyyy-mm-dd)       :
version                     :
noVST3QueryViewCapabilities :
DisabledByDefault           :
optionalWarning             :

What if the post reader needs to know if any plugins are DisabledByDefault?

Code: Select all


Import-Csv -Path $csvFilePath | 
  Where-Object -Property disable* -EQ 1 | 
    Out-Default

To correctly keep the PowerShell's outputted format,
the PowerShell output is also placed within a code section too.
(Not code, just the formatted outputted data.)

Code: Select all


Name                        : Harlequin Preamp
UUID                        : 48514E50-0000-0000-0000-000000000000
MaxSampleRate               : 0
RunNonDPIAware              :
forceSize                   :
extraPresetNotifications    :
vst3releaseOnReset          :
safeModeByDefault           :
fileDate (yyyy-mm-dd)       :
version                     :
noVST3QueryViewCapabilities :
DisabledByDefault           : 1
optionalWarning             : This plugin is known to cause crashing in Mixcraft 10

Name                        : TIZE VST3
UUID                        : 31493B7F-0000-0000-0000-000000000000
MaxSampleRate               :
RunNonDPIAware              :
forceSize                   :
extraPresetNotifications    :
vst3releaseOnReset          :
safeModeByDefault           :
fileDate (yyyy-mm-dd)       :
version                     : 1.0.2.0
noVST3QueryViewCapabilities :
DisabledByDefault           : 1
optionalWarning             : This plugin will crash Mixcraft when loading a project with it in it.

Name                        : Archetype Gojira X
UUID                        : 230739E4-0000-0000-0000-000000000000
MaxSampleRate               :
RunNonDPIAware              :
forceSize                   :
extraPresetNotifications    :
vst3releaseOnReset          :
safeModeByDefault           :
fileDate (yyyy-mm-dd)       :
version                     :
noVST3QueryViewCapabilities :
DisabledByDefault           : 1
optionalWarning             : Freezes Mixcraft and Juce hosts 7 & 8

So the post reader is slowly seeing how helpful it is, when one uses the Windows PowerShell ISE as
one's own music data controller. Some post readers use a midi controller, an audio controller and
possibly a video controller, so why not a music data controller (and one where the user has full
control of it)?
jwmix
Posts: 39
Joined: Mon Apr 30, 2018 12:06 pm

Re: It is Mixcraft time

Post by jwmix »

Time for the poster to look at some devices (for maybe some useful information) that are used in
audio/midi/sounds actions. Each post reader will have different lists, with different objects within
these lists, due to different workflows.

PowerShell comes with two main device information type of cmdlets:

Get-PnpDevice and Get-PnpDeviceProperty

and of course, where there are Get-Name cmdlets, there are (usually) Set-Name cmdlets, but these
cmdlets have instead Disable-PnpDevice and Enable-PnpDevice that (sort of works) when running in
the PowerShell Admin windows. The Get-Names cmdlets are PowerShell user window useable.

Plus there is a third party (not from Microsoft) auto device information type of cmdlets:

AudioDeviceCmdlets

The post reader (if interested) can find the needed AudioDeviceCmdlets.dll at:

https://github.com/frgnca/AudioDeviceCmdlets

The needed dll file link is on the right hand side of the page named Releases.

Download it. Scan it. Place it wherever the post reader wants to place it.

Then in the PowerShell text/code/actions below, be sure to change the poster's
AudioDeviceCmdlets.dll path, into the post reader's AudioDeviceCmdlets.dll path.

The poster will start with displaying what an Every Day studio worker (or EDsw) might use today
to get device information, and then the poster will do the PowerShell text/code/actions way.

Note: All of the PowerShell text/code/actions were created and ran within the Windows PowerShell ISE.

Time for some PowerShell interactive user, copy and paste, PowerShell text/code/actions.

Always have a good idea (understanding) of what any text/code/action will do.

Code: Select all


Start-Process -FilePath devmgmt.msc

Start-Sleep -Milliseconds 500

Start-Process -FilePath mmsys.cpl 

Start-Sleep -Milliseconds 500

Start-Process -FilePath ms-settings:sound

PS returns nothing (and no errors).

But they do open the Device Manager window and the Sound window and the Window's Settings Sound
window which most likely, the post reader will use (by clicking and clicking and clicking) to get
their desired device information.

The poster will now load the AudioDeviceCmdlets.dll into the current PowerShell session (window) to
show how this is done for every other needed/desired dll that can be loaded into the ISE/PowerShell.

Note:In the below PowerShell text/code/actions, $_ and $PSItem are both PowerShell defined
variables that mean the current pipeline object (which remember, also carries all of it's own properties and
methods too).

Code: Select all


$parentPath = "$env:USERPROFILE\Documents\Audio\Apps"
$childPath = "AudioDeviceCmdlets.dll"

$audioDeviceCmdletsPath = Join-Path -Path $parentPath -ChildPath $childPath

Get-Item -Path $audioDeviceCmdletsPath | 
  Format-List -Property Name, 
    @{Name = "Size" 
      Expression = { "{0:n0}" -f $PSItem.Length 
      } # End of Expression = { }.
    }, # End of @{ }.
      @{Name = "DateTime" 
      Expression = { $PSItem.LastWriteTime.DateTime
      } # End of Expression = { }.
        } | # End of @{ }.
            Out-Default

Import-Module -Name $audioDeviceCmdletsPath -PassThru | 
  Out-Default

To correctly keep the PowerShell's outputted format,
the PowerShell output is also placed within a code section too.
(Not code, just the formatted outputted data.)

Code: Select all


Name     : AudioDeviceCmdlets.dll
Size     : 45,056
DateTime : Saturday, May 28, 2022 6:23:40 PM


ModuleType Version    Name                 ExportedCommands
---------- -------    ----                 ----------------
Binary     3.1.0.2    AudioDeviceCmdlets   {Get-AudioDevice, Set-AudioDevice, Write-AudioDevice}

Okay the poster now has access to PowerShell's cmdlets, Get-PnpDevice and Get-PnpDeviceProperty
and the third party's AudioDeviceCmdlets Get-AudioDevice, Set-AudioDevice, and Write-AudioDevice.

First the Get-PnpDevice and Get-PnpDeviceProperty cmdlets usage.

Code: Select all


Get-PnpDevice | 
  Select-Object -First 1 -Last 1 | 
    Out-Default

Get-PnpDevice | 
  Select-Object -Property Class -Unique | 
    Out-Default

To correctly keep the PowerShell's outputted format,
the PowerShell output is also placed within a code section too.
(Not code, just the formatted outputted data.)

Code: Select all


Status     Class           FriendlyName           InstanceId
------     -----           ------------           ----------
Unknown    SoftwareDevice  MIDI                   SWD\MMDE...
OK         Net             WAN Miniport (L2TP)    SWD\MSRR...


Class
-----
SoftwareDevice
System
Volume
MEDIA
PrintQueue
WPD
USB
Net
CDROM
Mouse
HIDClass
DiskDrive
Keyboard
HDC
SCSIAdapter
VolumeSnapshot
Monitor
Computer
DigitalMediaDevices

Display
Image
WSDPrintDevice
Printer
AudioEndpoint
Firmware
Processor

Mmm does everyone have a blank line object too?

Anyway for audio/midi/sounds the post reader will most likely use the classes SoftwareDevice,
MEDIA, DigitalMediaDevices and AudioEndpoint (AudioEndpoint is the most often used one).

Each one of those four classes (and most likely all of them) are a separate Windows rabbit hole
adventures.

But don't worry, be happy.

This is only a useful introduction post starting with the two classes AudioEndpoint and Media.

AudioEndpoint is both the Playback (output) audio device (commonly speakers) and the audio Record
(input) device (commonly the microphone). AudioEndpoint contains the currently (active) selected
devices (usually two of them and only those being currently active/selected).

Now some post readers have many Playback devices and many Record devices, and when these devices
are not the currently active devices (listed in the AudioEndpoint class), they are placed within
the class Media or the class SoftwareDevice or the class DigitalMediaDevices (waiting to be used
again).

Now if the post reader is interested in any of the other device classes (Printer, Display and etc.)
besides these four classes,remember Get-(name here) cmdlets are read only cmdlets.
So sure get/read these other devices too. Go ahead and look at the Display, Mouse or whatever. All
this getting/looking will help with the reading of the returned data (and then search to see what the
returned data really means). And this would be a great adventure for the younger Mixcraft users to
take up. Just start a post in the Tips And Tricks forum and see if any others show up and help.

The poster will now look/read/get the currently active AudioEndpoint class's data.

Code: Select all


Get-PnpDevice -Class AudioEndpoint -PresentOnly | 
  Out-Default


To correctly keep the PowerShell's outputted format,
the PowerShell output is also placed within a code section too.
(Not code, just the formatted outputted data.)

Code: Select all


Status     Class           FriendlyName                             InstanceId
------     -----           ------------                             ----------
OK         AudioEndpoint   Speakers (High Definition Audio Device)  SWD\MMDE...

Mmm only one device, the playback device and nothing else is active for the record device. So the
poster goes ahead and get's the playback device's full data (Select-Object * means everything).

Code: Select all


Get-PnpDevice -Class AudioEndpoint -PresentOnly | 
  Select-Object * | 
    Out-Default

To correctly keep the PowerShell's outputted format,
the PowerShell output is also placed within a code section too.
(Not code, just the formatted outputted data.)

Code: Select all


Class                       : AudioEndpoint
FriendlyName                : Speakers (High Definition Audio Device)
InstanceId                  : SWD\MMDEVAPI\{0.0.0.00000000}.{D9CC2ECF-09B5-401C-86D4-5305BE1A62FF}
Problem                     : CM_PROB_NONE
ConfigManagerErrorCode      : CM_PROB_NONE
ProblemDescription          : 
Caption                     : Speakers (High Definition Audio Device)
Description                 : Audio Endpoint
InstallDate                 : 
Name                        : Speakers (High Definition Audio Device)
Status                      : OK
Availability                : 
ConfigManagerUserConfig     : False
CreationClassName           : Win32_PnPEntity
DeviceID                    : SWD\MMDEVAPI\{0.0.0.00000000}.{D9CC2ECF-09B5-401C-86D4-5305BE1A62FF}
ErrorCleared                : 
ErrorDescription            : 
LastErrorCode               : 
PNPDeviceID                 : SWD\MMDEVAPI\{0.0.0.00000000}.{D9CC2ECF-09B5-401C-86D4-5305BE1A62FF}
PowerManagementCapabilities : 
PowerManagementSupported    : 
StatusInfo                  : 
SystemCreationClassName     : Win32_ComputerSystem
SystemName                  : TOPDOG
ClassGuid                   : {c166523c-fe0c-4a94-a586-f1a80cfbbf3e}
CompatibleID                : {GenericAudioEndpoint, SWD\GenericRaw, SWD\Generic}
HardwareID                  : {MMDEVAPI\AudioEndpoints}
Manufacturer                : Microsoft
PNPClass                    : AudioEndpoint
Present                     : True
Service                     : 
PSComputerName              : 
CimClass                    : ROOT/cimv2:Win32_PnPEntity
CimInstanceProperties       : {Caption, Description, InstallDate, Name...}
CimSystemProperties         : Microsoft.Management.Infrastructure.CimSystemProperties

Notice the InstanceId's (and PNPDeviceID and DeviceID) data?

InstanceId : SWD\MMDEVAPI\{0.0.0.00000000}.{D9CC2ECF-09B5-401C-86D4-5305BE1A62FF}

SWD\MMDEVAPI\{0.0.0.00000000} means AudioEndpoint Playback (output) device and
{D9CC2ECF-09B5-401C-86D4-5305BE1A62FF} is the GUID for the device or object.

By the way the current active Record device would be SWD\MMDEVAPI\{0.0.1.00000000}.{GUID}.

So the poster looked deeper down the Playback device's audio rabbit's hole.

Code: Select all


Get-PnpDevice -FriendlyName "sp*" | 
  Get-PnpDeviceProperty | 
    Out-Default

To correctly keep the PowerShell's outputted format,
the PowerShell output is also placed within a code section too.
(Not code, just the formatted outputted data.)

Code: Select all



InstanceId KeyName                                   Type       Data
---------- -------                                   ----       ----
SWD\MMD... DEVPKEY_Device_DeviceDesc                 String     Audio Endpoint
SWD\MMD... DEVPKEY_Device_HardwareIds                StringList {MMDEVAPI\AudioEndpoints}
SWD\MMD... DEVPKEY_Device_CompatibleIds              StringList {GenericAudioEndpoint, SWD\GenericRaw, SWD\Generic}
SWD\MMD... DEVPKEY_Device_Class                      String     AudioEndpoint
SWD\MMD... DEVPKEY_Device_ClassGuid                  Guid       {C166523C-FE0C-4A94-A586-F1A80CFBBF3E}
SWD\MMD... DEVPKEY_Device_Driver                     String     {c166523c-fe0c-4a94-a586-f1a80cfbbf3e}\0000
SWD\MMD... DEVPKEY_Device_ConfigFlags                UInt32     0
SWD\MMD... DEVPKEY_Device_Manufacturer               String     Microsoft
SWD\MMD... DEVPKEY_Device_FriendlyName               String     Speakers (High Definition Audio Device)
SWD\MMD... DEVPKEY_Device_PDOName                    String     \Device\0000004a
SWD\MMD... DEVPKEY_Device_Capabilities               UInt32     212
SWD\MMD... DEVPKEY_Device_BusTypeGuid                Guid       {06D10322-7DE0-4CEF-8E25-197D0E7442E2}
SWD\MMD... DEVPKEY_Device_LegacyBusType              UInt32     15
SWD\MMD... DEVPKEY_Device_BusNumber                  UInt32     0
SWD\MMD... DEVPKEY_Device_EnumeratorName             String     SWD
SWD\MMD... DEVPKEY_Device_PowerData                  Binary     {56, 0, 0, 0...}
SWD\MMD... DEVPKEY_Device_RemovalPolicy              UInt32     2
SWD\MMD... DEVPKEY_Device_RemovalPolicyDefault       UInt32     2
SWD\MMD... DEVPKEY_Device_InstallState               UInt32     0
SWD\MMD... DEVPKEY_Device_BaseContainerId            Guid       {79BDE0C3-DEA8-5564-8F9A-8DB19B790569}
SWD\MMD... DEVPKEY_NAME                              String     Speakers (High Definition Audio Device)
SWD\MMD... DEVPKEY_Device_InstanceId                 String     SWD\MMDEVAPI\{0.0.0.00000000}.{D9CC2ECF-09B5-401C-86...
SWD\MMD... DEVPKEY_Device_DevNodeStatus              UInt32     25190410
SWD\MMD... DEVPKEY_Device_ProblemCode                UInt32     0
SWD\MMD... DEVPKEY_Device_Parent                     String     HDAUDIO\FUNC_01&VEN_111D&DEV_76F3&SUBSYS_103C2AF7&RE...
SWD\MMD... DEVPKEY_Device_SafeRemovalRequired        Boolean    False
SWD\MMD... DEVPKEY_Device_ContainerId                Guid       {79BDE0C3-DEA8-5564-8F9A-8DB19B790569}
SWD\MMD... DEVPKEY_Device_IsPresent                  Boolean    True
SWD\MMD... DEVPKEY_Device_HasProblem                 Boolean    False
SWD\MMD... {83DA6326-97A6-4088-9453-A1923F573B29} 15 Boolean    True
SWD\MMD... DEVPKEY_Device_IsRebootRequired           Boolean    False
SWD\MMD... DEVPKEY_Device_ReportedDeviceIdsHash      UInt32     1816082587
SWD\MMD... DEVPKEY_Device_InLocalMachineContainer    Boolean    False
SWD\MMD... DEVPKEY_Device_Stack                      StringList {\Driver\SoftwareDevice}
SWD\MMD... {A8B865DD-2E3D-4094-AD97-E593A70C75D6} 26 Boolean    False
SWD\MMD... {1F39EC81-2EDF-49FE-BBBF-862F89E3F5B2} 2  UInt32     2
SWD\MMD... {3464F7A4-2444-40B1-980A-E0903CB6D912} 10 UInt32     3
SWD\MMD... DEVPKEY_Device_BusReportedDeviceDesc      String     Speakers (High Definition Audio Device)
SWD\MMD... DEVPKEY_Device_ConfigurationId            String     audioendpoint.inf:MMDEVAPI\AudioEndpoints,NO_DRV
SWD\MMD... DEVPKEY_DeviceContainer_Category          StringList {Audio}
SWD\MMD... {80497100-8C73-48B9-AAD9-CE387E19C56E} 6  UInt32     0
SWD\MMD... DEVPKEY_Device_FriendlyNameAttributes     UInt32     2
SWD\MMD... {83DA6326-97A6-4088-9453-A1923F573B29} 3  String     audioendpoint.inf:db04a16cc5e2d48f:NO_DRV:10.0.19041...
SWD\MMD... DEVPKEY_Device_SessionId                  UInt32     5
SWD\MMD... {83DA6326-97A6-4088-9453-A1923F573B29} 10 String     HDAUDIO\FUNC_01&VEN_111D&DEV_76F3&SUBSYS_103C2AF7&RE...
SWD\MMD... DEVPKEY_Device_InstallDate                FileTime   11/15/2023 5:31:10 PM
SWD\MMD... DEVPKEY_Device_FirstInstallDate           FileTime   11/15/2023 5:31:10 PM
SWD\MMD... DEVPKEY_Device_LastArrivalDate            FileTime   1/21/2025 9:29:26 AM
SWD\MMD... DEVPKEY_Device_DriverDate                 FileTime   12/5/2019 6:00:00 PM
SWD\MMD... DEVPKEY_Device_DriverVersion              String     10.0.19041.1
SWD\MMD... DEVPKEY_Device_DriverDesc                 String     Audio Endpoint
SWD\MMD... DEVPKEY_Device_DriverInfPath              String     audioendpoint.inf
SWD\MMD... DEVPKEY_Device_DriverInfSection           String     NO_DRV
SWD\MMD... DEVPKEY_Device_MatchingDeviceId           String     MMDEVAPI\AudioEndpoints
SWD\MMD... DEVPKEY_Device_DriverProvider             String     Microsoft
SWD\MMD... DEVPKEY_Device_DriverRank                 UInt32     16711680
SWD\MMD... DEVPKEY_Device_NoConnectSound             Boolean    True
SWD\MMD... DEVPKEY_DrvPkg_Icon                       StringList {%windir%\system32\mmres.dll,-3010}

Ahhh a deeper audio rabbit hole, each of the above, is another twist or turn, in the hole. Start
searching the GUIDs for more information. But the above returned data does provide enough information
to satisfy most post readers.

What if the post reader needs to get some desired information?

Code: Select all


$audioEndpointDevices = Get-PnpDevice -Class AudioEndpoint -PresentOnly

$audioEndpointDevices |
  Format-List -Property Status, Class, FriendlyName, InstanceId | 
    Out-Default
  
$audioEndpointDevices | 
  Get-PnpDeviceProperty -KeyName DEVPKEY_Device_Class, DEVPKEY_NAME, DEVPKEY_Device_DriverDate, 
    DEVPKEY_Device_DriverVersion, DEVPKEY_Device_DriverInfPath  |
      Out-Default

To correctly keep the PowerShell's outputted format,
the PowerShell output is also placed within a code section too.
(Not code, just the formatted outputted data.)

Code: Select all


Status       : OK
Class        : AudioEndpoint
FriendlyName : Speakers (High Definition Audio Device)
InstanceId   : SWD\MMDEVAPI\{0.0.0.00000000}.{D9CC2ECF-09B5-401C-86D4-5305BE1A62FF}


InstanceId KeyName                                   Type       Data
---------- -------                                   ----       ----
SWD\MMD... DEVPKEY_Device_Class                      String     AudioEndpoint
SWD\MMD... DEVPKEY_NAME                              String     Speakers (High Definition Audio Device)
SWD\MMD... DEVPKEY_Device_DriverDate                 FileTime   12/5/2019 6:00:00 PM
SWD\MMD... DEVPKEY_Device_DriverVersion              String     10.0.19041.1
SWD\MMD... DEVPKEY_Device_DriverInfPath              String     audioendpoint.inf

Okay before the post reader checks on where the audio input device is, the poster will try the
third party's cmdlets (that a user wrote to solve a problem that the user had. See what happens
when users work together Mixcraft users?).

Code: Select all


Get-AudioDevice -List | 
  Out-Default

Get-AudioDevice -Playback | 
  Out-Default

Write-Host
Write-Host "What is the Playback device's volume percentage setting? " -NoNewline

$audioDevicePlaybackVolumePercentSetting = Get-AudioDevice -PlaybackVolume 

Write-Host $audioDevicePlaybackVolumePercentSetting -ForegroundColor Cyan

Write-Host
Write-Host "Is the Playback device's mute setting turned on? " -NoNewline

$audioDevicePlaybackMuteSetting = Get-AudioDevice -PlaybackMute

Write-Host $audioDevicePlaybackMuteSetting -ForegroundColor Cyan

Write-Host
Get-AudioDevice -Recording | 
  Out-Default

To correctly keep the PowerShell's outputted format,
the PowerShell output is also placed within a code section too.
(Not code, just the formatted outputted data.)

Code: Select all


Index                : 1
Default              : True
DefaultCommunication : True
Type                 : Playback
Name                 : Speakers (High Definition Audio Device)
ID                   : {0.0.0.00000000}.{d9cc2ecf-09b5-401c-86d4-5305be1a62ff}
Device               : CoreAudioApi.MMDevice


Index                : 1
Default              : True
DefaultCommunication : True
Type                 : Playback
Name                 : Speakers (High Definition Audio Device)
ID                   : {0.0.0.00000000}.{d9cc2ecf-09b5-401c-86d4-5305be1a62ff}
Device               : CoreAudioApi.MMDevice

What is the Playback device's volume percentage setting? 64%

Is the Playback device's mute setting turned on? False

Get-AudioDevice : No recording AudioDevice found with the default role
At line:24 char:1
+ Get-AudioDevice -Recording |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-AudioDevice], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException,AudioDeviceCmdlets.GetAudioDevice


Okay it is time to see where the poster's audio device is stored (sometimes in the Class Media).
And the poster knows the device was a microphone so...

Code: Select all


Get-PnpDevice | 
  Where-Object -Property "FriendlyName" -match "mic" | 
    Out-Default

To correctly keep the PowerShell's outputted format,
the PowerShell output is also placed within a code section too.
(Not code, just the formatted outputted data.)

Code: Select all


Status     Class           FriendlyName                                                    InstanceId
------     -----           ------------                                                    ----------
Unknown    MEDIA           Microsoft Streaming Service Proxy                               SW\{96E0...
OK         System          Microsoft Basic Display Driver                                  ROOT\BAS...
OK         SoftwareDevice  Microsoft RRAS Root Enumerator                                  SWD\MSRR...
OK         System          Microsoft Windows Management Interface for ACPI                 ACPI\PNP...
OK         System          Microsoft Hyper-V Virtualization Infrastructure Driver          ROOT\VID...
OK         System          Microsoft Virtual Drive Enumerator                              ROOT\VDR...
OK         SCSIAdapter     Microsoft Storage Spaces Controller                             ROOT\SPA...
OK         Net             Microsoft Kernel Debug Network Adapter                          ROOT\KDN...
OK         PrintQueue      Microsoft XPS Document Writer                                   SWD\PRIN...
OK         SoftwareDevice  Microsoft Radio Device Enumeration Bus                          SWD\RADI...
Unknown    MEDIA           DYNEX USB MIC Device                                            USB\VID_...
OK         SoftwareDevice  Microsoft Device Association Root Enumerator                    SWD\MSDA...
OK         System          Microsoft ACPI-Compliant System                                 ACPI_HAL...
OK         System          Microsoft Basic Render Driver                                   ROOT\BAS...
OK         PrintQueue      Microsoft Print to PDF                                          SWD\PRIN...
OK         System          Microsoft UEFI-Compliant System                                 ACPI_HAL...
Unknown    MEDIA           Microsoft Trusted Audio Drivers                                 SW\{EEC1...
OK         Net             Microsoft Wi-Fi Direct Virtual Adapter #4                       {5D624F9...
OK         Net             Microsoft Wi-Fi Direct Virtual Adapter                          {5D624F9...
OK         SoftwareDevice  Microsoft GS Wavetable Synth                                    SWD\MMDE...
Unknown    AudioEndpoint   Microphone (DYNEX USB MIC Device)                               SWD\MMDE...
OK         USB             Intel(R) USB 3.0 eXtensible Host Controller - 1.0 (Microsoft)   PCI\VEN_...
OK         System          Microsoft System Management BIOS Driver                         ROOT\MSS...

The poster noticed
Unknown AudioEndpoint Microphone (DYNEX USB MIC Device)
Unknown MEDIA DYNEX USB MIC Device

Mmmm within AudioEndpoint and Media.

Code: Select all


Get-PnpDevice -Class Media -FriendlyName "dy*" | 
  Select-Object * | 
    Out-Default

Get-PnpDevice -Class Media -FriendlyName "dy*" | 
  Get-PnpDeviceProperty | 
    Out-Default

To correctly keep the PowerShell's outputted format,
the PowerShell output is also placed within a code section too.
(Not code, just the formatted outputted data.)

Code: Select all


Class                       : MEDIA
FriendlyName                : DYNEX USB MIC Device
InstanceId                  : USB\VID_A012&PID_B012&MI_00\6&101B0C35&7&0000
Problem                     : CM_PROB_PHANTOM
ConfigManagerErrorCode      : CM_PROB_PHANTOM
ProblemDescription          :
Caption                     : DYNEX USB MIC Device
Description                 : USB Audio Device
InstallDate                 :
Name                        : DYNEX USB MIC Device
Status                      : Unknown
Availability                :
ConfigManagerUserConfig     : False
CreationClassName           : Win32_PnPEntity
DeviceID                    : USB\VID_A012&PID_B012&MI_00\6&101B0C35&7&0000
ErrorCleared                :
ErrorDescription            :
LastErrorCode               :
PNPDeviceID                 : USB\VID_A012&PID_B012&MI_00\6&101B0C35&7&0000
PowerManagementCapabilities :
PowerManagementSupported    :
StatusInfo                  :
SystemCreationClassName     : Win32_ComputerSystem
SystemName                  : TOPDOG
ClassGuid                   : {4d36e96c-e325-11ce-bfc1-08002be10318}
CompatibleID                : {USB\Class_01&SubClass_01&Prot_00, USB\Class_01&SubClass_01, USB\Class_01}
HardwareID                  : {USB\VID_A012&PID_B012&REV_0100&MI_00, USB\VID_A012&PID_B012&MI_00}
Manufacturer                : (Generic USB Audio)
PNPClass                    : MEDIA
Present                     : False
Service                     : usbaudio
PSComputerName              :
CimClass                    : ROOT/cimv2:Win32_PnPEntity
CimInstanceProperties       : {Caption, Description, InstallDate, Name...}
CimSystemProperties         : Microsoft.Management.Infrastructure.CimSystemProperties


InstanceId KeyName                                   Type       Data
---------- -------                                   ----       ----
USB\VID... DEVPKEY_Device_DeviceDesc                 String     USB Audio Device
USB\VID... DEVPKEY_Device_HardwareIds                StringList {USB\VID_A012&PID_B012&REV_0100&MI_00, USB\VID_A012&...
USB\VID... DEVPKEY_Device_CompatibleIds              StringList {USB\Class_01&SubClass_01&Prot_00, USB\Class_01&SubC...
USB\VID... DEVPKEY_Device_Service                    String     usbaudio
USB\VID... DEVPKEY_Device_Class                      String     MEDIA
USB\VID... DEVPKEY_Device_ClassGuid                  Guid       {4D36E96C-E325-11CE-BFC1-08002BE10318}
USB\VID... DEVPKEY_Device_Driver                     String     {4d36e96c-e325-11ce-bfc1-08002be10318}\0001
USB\VID... DEVPKEY_Device_ConfigFlags                UInt32     0
USB\VID... DEVPKEY_Device_Manufacturer               String     (Generic USB Audio)
USB\VID... DEVPKEY_Device_FriendlyName               String     DYNEX USB MIC Device
USB\VID... DEVPKEY_Device_LocationInfo               String     0000.0014.0000.012.000.000.000.000.000
USB\VID... DEVPKEY_Device_Capabilities               UInt32     160
USB\VID... DEVPKEY_Device_EnumeratorName             String     USB
USB\VID... DEVPKEY_Device_Address                    UInt32     12
USB\VID... DEVPKEY_Device_BaseContainerId            Guid       {30A119B7-4955-5FEE-BCFF-3669AE45004F}
USB\VID... DEVPKEY_NAME                              String     DYNEX USB MIC Device
USB\VID... DEVPKEY_Device_InstanceId                 String     USB\VID_A012&PID_B012&MI_00\6&101B0C35&7&0000
USB\VID... DEVPKEY_Device_Parent                     String     USB\VID_A012&PID_B012\12000002
USB\VID... DEVPKEY_Device_SafeRemovalRequired        Boolean    False
USB\VID... DEVPKEY_Device_ContainerId                Guid       {30A119B7-4955-5FEE-BCFF-3669AE45004F}
USB\VID... DEVPKEY_Device_IsPresent                  Boolean    False
USB\VID... DEVPKEY_Device_HasProblem                 Boolean    False
USB\VID... {83DA6326-97A6-4088-9453-A1923F573B29} 15 Boolean    False
USB\VID... DEVPKEY_Device_IsRebootRequired           Boolean    False
USB\VID... DEVPKEY_Device_InLocalMachineContainer    Boolean    False
USB\VID... {A8B865DD-2E3D-4094-AD97-E593A70C75D6} 26 Boolean    False
USB\VID... {3464F7A4-2444-40B1-980A-E0903CB6D912} 10 UInt32     3
USB\VID... DEVPKEY_Device_BusReportedDeviceDesc      String     DYNEX USB MIC Device
USB\VID... DEVPKEY_Device_ConfigurationId            String     wdma_usb.inf:USB\Class_01,USBAudio
USB\VID... {80497100-8C73-48B9-AAD9-CE387E19C56E} 6  UInt32     0
USB\VID... {80497100-8C73-48B9-AAD9-CE387E19C56E} 7  UInt64     0
USB\VID... {83DA6326-97A6-4088-9453-A1923F573B29} 3  String     wdma_usb.inf:ed86ca114a9cb1b5:USBAudio:10.0.19041.53...
USB\VID... {83DA6326-97A6-4088-9453-A1923F573B29} 10 String     USB\VID_A012&PID_B012\12000002
USB\VID... DEVPKEY_Device_InstallDate                FileTime   5/23/2021 1:30:12 PM
USB\VID... DEVPKEY_Device_FirstInstallDate           FileTime   5/23/2021 1:30:12 PM
USB\VID... DEVPKEY_Device_LastArrivalDate            FileTime   5/28/2023 11:31:48 AM
USB\VID... DEVPKEY_Device_LastRemovalDate            FileTime   5/28/2023 12:58:45 PM
USB\VID... DEVPKEY_Device_LocationPaths              StringList {PCIROOT(0)#PCI(1400)#USBROOT(0)#USB(12)#USBMI(0), P...
USB\VID... DEVPKEY_Device_DriverDate                 FileTime   1/2/2025 6:00:00 PM
USB\VID... DEVPKEY_Device_DriverVersion              String     10.0.19041.5369
USB\VID... DEVPKEY_Device_DriverDesc                 String     USB Audio Device
USB\VID... DEVPKEY_Device_DriverInfPath              String     wdma_usb.inf
USB\VID... DEVPKEY_Device_DriverInfSection           String     USBAudio
USB\VID... DEVPKEY_Device_MatchingDeviceId           String     USB\Class_01
USB\VID... DEVPKEY_Device_DriverProvider             String     Microsoft
USB\VID... DEVPKEY_Device_DriverRank                 UInt32     16719874
USB\VID... {A8B865DD-2E3D-4094-AD97-E593A70C75D6} 16 StringList {ks.inf, wdmaudio.inf}
USB\VID... DEVPKEY_Device_GenericDriverInstalled     Boolean    True
USB\VID... {B3F8FA53-0004-438E-9003-51A46E139BFC} 7  UInt32     0
USB\VID... {D1885396-39D8-4777-BCFF-5E3241483416} 0  UInt32     2

Notice last usage time? SWD\MMD... DEVPKEY_Device_LastRemovalDate FileTime 5/28/2023 12:58:45 PM

And the below data?

Class : MEDIA
FriendlyName : DYNEX USB MIC Device
Problem : CM_PROB_PHANTOM

So the poster get's by with a little help from the poster's friends, PowerShell, Bing and Edge...

Code: Select all


Start-Process -FilePath "https://www.bing.com/search?q=CM_PROB_PHANTOM"

One of the links came back with:

Code 45 - CM_PROB_PHANTOM
Article 03/13/2023

This Device Manager error message indicates that the device is not present.

Error Code
45

Display Message
"Currently, this hardware device is not connected to the computer. (Code 45)"

"To fix this problem, reconnect this hardware device to the computer."

Well that's easy to find the error and to fix it.

Well this is enough for this post, so play with these Get-actions and let others know how they work
for you, as another tool within the PowerShell ISE Music Data Controller.
jwmix
Posts: 39
Joined: Mon Apr 30, 2018 12:06 pm

Re: It is Mixcraft time

Post by jwmix »

Note: Some people consider Windows Registry actions as an advanced user action.

So the poster will do some advanced user PowerShell text/code/actions, as
another tool, for the Windows PowerShell ISE, when the ISE is being used as a music data controller.

A Mixcraft user asked if there was a default midi velocity setting located in some Mixcraft file.

The poster doesn't know about a file but...

The user was also interested in seeing what the default midi velocity setting was set to
and if the user could set the default midi velocity setting without running Mixcraft.

Well yes, the user can obtain and even set a new default midi velocity setting without ever running
Mixcraft by accessing the Windows Mixcraft registry hives (which some people consider to be user
advanced actions).

But first some PowerShell information.

The PowerShell creators created PSDrives:

A PowerShell drive is a data store location that you can access like a filesystem drive in PowerShell.
The PowerShell providers create some drives for you, such as the file system drives (including C: and
D:), the registry drives (HKCU: and HKLM:), and the certificate drive (Cert:), and you can create your
own PowerShell drives. These drives are useful, but they're available only within PowerShell. You can't
access them using other Windows tools, such as File Explorer or Cmd.exe.
So simply put:

When an Every Day studio worker (or EDsw) accesses (via PowerShell) any of the above PSDrive objects,
like files or registry data (or the other objects) via any PowerShell text/code/actions, the PSDrive
actions take over (without the user needing to do any other work) to return/change/create the user's
data needs.

For example:

Windows file objects use directories and paths and properties.
Windows registry objects use hives and keys and values.

PowerShell handles the above two objects differences (plus other objects besides these two)
for the PowerShell user. Which means the exact same PowerShell cmdlets (think commands) can
be used for both the file's properties and for the registry's values.

Note: Some people suggest backing up the Windows registry before doing any
actions with the Windows Registry. So if the user is interested in backing up the Windows registry,
before using it, there are many ways to do this backup actions (including via PowerShell) all
over the Internet (once again, these are after all, simple DawPsDemo examples).

Note: All of the PowerShell text/code/actions were created and ran within the Windows PowerShell ISE.

Time for some PowerShell interactive user, copy and paste, PowerShell text/code/actions.

Always have a good idea (understanding) of what any text/code/action will do.

Code: Select all


$filePath = "$env:windir\Media\Alarm01.wav"
$fileProperty = "length"

Write-Host
Write-Host "The " -NoNewline
Write-Host "$fileProperty " -NoNewline -ForegroundColor Cyan
Write-Host "of the file: " -NoNewline
Write-Host "$filePath " -NoNewline -ForegroundColor Yellow
Write-Host "is " -NoNewline

$data = Get-ItemPropertyValue -Path $filePath -Name $fileProperty

$formattedNumber = "{0:n0}" -f $data

Write-Host "$formattedNumber " -NoNewline -ForegroundColor Cyan
Write-Host "bytes."

$registryPath = "HKCU:\SOFTWARE\Acoustica\VST"
$registryProperty = "NumVstFolders"

Write-Host
Write-Host "The " -NoNewline
Write-Host "$registryProperty " -NoNewline -ForegroundColor Cyan
Write-Host "in the registry location: " -NoNewline
Write-Host "$registryPath " -NoNewline -ForegroundColor Yellow
Write-Host "is " -NoNewline

$data = Get-ItemPropertyValue -Path $registryPath -Name $registryProperty

Write-Host $data -NoNewline -ForegroundColor Cyan
Write-Host "."

PS returns (and no errors).

The length of the file: C:\WINDOWS\Media\Alarm01.wav is 491,516 bytes.

The NumVstFolders in the registry location: HKCU:\SOFTWARE\Acoustica\VST is 6.

Wow, the same PowerShell cmdlet used for both the file system's data and the registry system's data.

Now moving on to obtain the current Mixcraft default midi velocity setting's value, which is obtained
by reading (using a PowerShell Get-Name cmdlet) the defaultMidi key located within the Windows
Mixcraft registry hive(s) (sections).

Likewise, to set the current Mixcraft default midi velocity setting's value, write (using a PowerShell
Set-Name cmdlet) the new value to the defaultMidi key, located within the Windows Mixcraft registry
hive(s).

Note: The poster does not check for bad input data. These are after all, simple
DawPsDemo examples (but maybe always test for bad input data in any production usage).

Now if the post reader is not interested in reading (let alone writing to) the Windows Mixcraft
registry settings, that is okay. That post reader can always set and change the default midi
velocity setting within Mixcraft itself.

Note: Some people suggest backing up the Windows registry before doing any
actions with the Windows Registry. So if the user is interested in backing up the Windows registry,
before using it, there are many ways to do this backup actions (including via PowerShell) all
over the Internet (once again, these are after all, simple DawPsDemo examples).

Note: All of the PowerShell text/code/actions were created and ran within the Windows PowerShell ISE.

Time for some PowerShell interactive user, copy and paste, PowerShell text/code/actions.

Always have a good idea (understanding) of what any text/code/action will do.

Code: Select all


$daw = "Mixcraft"

Write-Host
Write-Host "Ready " -NoNewline
Write-Host "to read " -NoNewline -ForegroundColor Green
Write-Host "the Windows $daw registry's current midi velocity setting?"
 
Write-Host
Write-Host "Press Ctrl+C to quit or"
pause

$registryPath = "HKCU:\SOFTWARE\Acoustica\Mixcraft10"

$currentDefaultVelocity = Get-ItemPropertyValue -Path $registryPath -Name "defaultVelocity"

Write-Host
Write-Host "The $daw registry's current midi velocity setting is " -NoNewline
Write-Host $currentDefaultVelocity -NoNewline -ForegroundColor Cyan
Write-Host "."

Write-Host
Write-Host "Ready to move on " -NoNewline
Write-Host "to set " -NoNewline -ForegroundColor Green
Write-Host "the $daw registry's current midi velocity setting to " -NoNewline

If($currentDefaultVelocity -le 70) { 
  $newDefaultVelocitySetting = Get-Random -Minimum $currentDefaultVelocity -Maximum 120
} # End of If($currentDefaultVelocity -le 70) { }.
ElseIf($currentDefaultVelocity -gt 70) { 
  $newDefaultVelocitySetting = Get-Random -Minimum 50 -Maximum 100
} # End of ElseIf(($currentDefaultVelocity -gt 70) { }. 

Write-Host $newDefaultVelocitySetting -NoNewline -ForegroundColor Cyan
Write-Host "?"

Write-Host
Write-Host "Press Ctrl+C to quit or"
pause

Write-Host
Write-Host "Setting the $daw registry's current midi velocity setting to a new value of " -NoNewline
Write-Host $newDefaultVelocitySetting -NoNewline -ForegroundColor Cyan
Write-Host "."

Set-ItemProperty -Path $registryPath -Name defaultVelocity -Value $newDefaultVelocitySetting

Start-Sleep -Milliseconds 100

Write-Host
Write-Host "Reading the $daw current midi velocity setting which is now set to " -NoNewline

$currentMidiVelocity = Get-ItemPropertyValue -Path $registryPath -Name "defaultVelocity"

Write-Host $currentMidiVelocity -NoNewline -ForegroundColor Cyan
Write-Host "."

Write-Host
Write-Host "To check the setting(s), ready " -NoNewline
Write-Host "to auto start " -NoNewline -ForegroundColor Green
Write-Host "$daw playing it's sounds via the below $daw project?"

$lastClosedProjectPath = Get-ItemPropertyValue -Path $registryPath -Name "mru.1"

Write-Host $lastClosedProjectPath -ForegroundColor Yellow

Write-Host
Write-Host "Press Ctrl+C to quit or"
pause

Start-Process -FilePath $lastClosedProjectPath	

Write-Host	
Write-Host "Started the above " -NoNewline
Write-Host "(" -NoNewline
	
$sleepSeconds = 45
	
Write-Host "now an on line access object" -NoNewline -ForegroundColor Green	
Write-Host ") $daw project,"	
Write-Host "that (" -NoNewline	
Write-Host "usually" -NoNewline -ForegroundColor Cyan	
Write-Host ") takes less than $sleepSeconds seconds. So wait for it..."	

Start-Sleep -Seconds $sleepSeconds	

Add-Type -AssemblyName System.Windows.Forms	

Start-Sleep -Milliseconds 100

[System.Windows.Forms.SendKeys]::SendWait(" ")	

Write-Host	
Write-Host "Hopefully, the $daw's sounds are playing."	

PS returns (and no errors).

Ready to read the Windows Mixcraft registry's current midi velocity setting?

Press Ctrl+C to quit or
Press Enter to continue...:

And after pressing Enter to continue...

The Mixcraft registry's current midi velocity setting is 70.

Ready to move on to set the Mixcraft registry's current midi velocity setting to ]85?

Press Ctrl+C to quit or
Press Enter to continue...:

And after pressing Enter to continue...

Setting the Mixcraft registry's current midi velocity setting to a new value of 85.

Reading the Mixcraft current midi velocity setting which is now set to 85.

To check the setting(s), ready to auto start Mixcraft playing it's sounds via the below Mixcraft project?
C:\Users\UserId\Documents\DawPsDemo\Acoustica\Mixcraft Test Projects\Country Rock Bass.mx10

Press Ctrl+C to quit or
Press Enter to continue...:

And after pressing Enter to continue...

Started the above (now an on line access object) Mixcraft project,
that (usually) takes less than 45 seconds. So wait for it...

Hopefully, the Mixcraft's sounds are playing.

Remember, there are a lot of settings that the Every Day studio worker (or EDsw) can set (to what
the post reader desires/needs) in both the Windows Mixcraft registry sections, as well as in various
Mixcraft files, before ever starting Mixcraft, when using the Windows Powershell ISE as one's own
music data controller.
jwmix
Posts: 39
Joined: Mon Apr 30, 2018 12:06 pm

Re: It is Mixcraft time

Post by jwmix »

Note: Some people consider Windows Registry actions as an advanced user action.

So the poster will do some advanced user PowerShell text/code/actions, as
another tool, for the Windows PowerShell ISE, when the ISE is being used as a music data controller.

DPI (or Dots Per Inch) is the making of characters larger or smaller and is used very little by the
poster, whereas other post readers seem to play with DPI a lot. The poster might not do a lot of DPI
usage, but the poster does read a lot about what other music people find interesting. And so while
reading, the poster always looks for a way that PowerShell could be used, in any way, to help with
usage of the read about topic (here DPI) for those post readers using DPI. So those post readers
using DPI will have to play with the below PowerShell text/code/actions and see if those actions
helps those post readers.

Start by reading the below articles.

Read this post for some general DPI information.
https://learn.microsoft.com/en-us/windo ... on-windows

Read this post for monitor(s) DPI/Scale issues (with pictures too).
https://blogs.windows.com/windowsdevelo ... ktop-apps/

DPI-related APIs and registry settings.
https://learn.microsoft.com/en-us/windo ... y-settings

Plus any posts that the post reader finds.

Then after reading the articles here are some Windows OS registry PowerShell text/code/actions, since
DPI starts first with the Windows OS DPI registry settings. After this Windows OS registry area of
this post, will come the Windows Mixcraft registry DPI PowerShell text/code/actions.

Note: The poster does not provide PowerShell text/code/actions that the poster
does not run (meaning no Set-WhateverName cmdlets for Windows OS registry changes). Remember, the
poster is not at all involved with DPI, unlike those who are heavy DPI users.

Anyway, after reading and working with the above article's data within the Windows PowerShell ISE,
as a music data controller, the active DPI post readers might stop doing:

Double clicking on the Mixcraft desktop shortcut icon (and since Mixcraft is now an online app,
this usually takes less than 45 seconds).

Then in Mixcraft do File -> Preferences -> Display and either click on / or unclick the setting
named Disable Per-Monitor DPI Awareness.

Then in Mixcraft do File -> Preferences -> Display and either keep the 100 or choose another
number in the dropbox named Scale.

Then close Mixcraft (via File -> Exit or by clicking on the top right corner's red X).

Then finally, once again, double click on the Mixcraft desktop shortcut icon (and since Mixcraft
is now an online app, this usually takes less than 45 seconds). Then select a project to use and
then go to work.

Now the music data controller active DPI poster readers can, instead of doing all the above:

Read the Windows Mixcraft registry's settings for DPI and Scale, and if needed, changes them,
and then auto start Mixcraft, usually with the last closed project's path, which is also in the
Mixcraft registry too (In fact now, the last 20 or so project paths are in the registry).

And then there is only one Mixcraft start, then back to work.

Note: Mixcraft plugin DPI is done within a XML file. These also can be set before starting the Daw
Mixcraft app too. It looks like there are various DPI file plugin settings:
from not set
to set but not yet Mixcraft used
and to set and Mixcraft used

But this Mixcraft plugin DPI XML reading/changing is a whole other post.

Moving on to Windows registry DPI settings (as mentioned in the above posts).

Now if the post reader is not interested in reading (let alone writing to) the Windows registry
settings, that is okay. That post reader can always set and change the Windows DPI settings via
various Windows settings pages.

Here are some (article mentioned) Windows OS reading (Get-) DPI PowerShell text/code/actions ran on
this simple and old DawPsDemo example's computer. Yep a computer, like a starting out Every Day
studio worker (or EDsw) might have/or use, and like Windows 95 computers and beyond (except for code),
this Windows 10 computer will have to be replaced soon too. Which will finally mean, that a starting
out EDsw will have to use Windows 11 and that's a very good thing, for all of us, too.

Note: Some people suggest backing up the Windows registry before doing any
actions with the Windows Registry. So if the user is interested in backing up the Windows registry,
before using it, there are many ways to do this backup actions (including via PowerShell) all
over the Internet (once again, these are after all, simple DawPsDemo examples).

Note: All of the PowerShell text/code/actions were created and ran within the Windows PowerShell ISE.

Time for some PowerShell interactive user, copy and paste, PowerShell text/code/actions.

Always have a good idea (understanding) of what any text/code/action will do.

Code: Select all


Get-ItemPropertyValue -Path "$env:windir\Media\town.mid" -Name Length | 
  Out-Default

Get-ItemPropertyValue -Path "HKCU:\Control Panel\Desktop" -Name Win8DpiScaling | 
  Out-Default

Get-ItemPropertyValue -Path "HKCU:\Control Panel\Desktop" -Name DpiScalingVer | 
  Out-Default

PS returns (and no errors).

22097 (the property Length of the midi file)
0 (the zero means one plain old DPI 96 monitor)
4096 (this is the Windows OS version's 10 DPI usage information)

Don't quote the poster on the above "facts", after all, it is a Windows DPI rabbit hole too, done
by version to version usage (and changes).

Notice that the poster did not have the registry setting for DesktopDPIOverride or LogPixels as
mentioned in the above articles. So what happens if the poster checks anyway?

Code: Select all


$registryPath = "HKCU:\Control Panel\Desktop"
 
Write-Host
Write-Host "Test or depending upon one's needed returned data usage:"

Write-Host
Write-Host "Looking for registry Logpixels data:"

Get-ItemPropertyValue -Path $registryPath -Name Logpixels | 
  Out-Default

Write-Host
Write-Host "Looking for registry Win8DpiScaling data:"

Get-ItemPropertyValue -Path $registryPath -Name Win8DpiScaling | 
  Out-Default

Write-Host
Write-Host "Looking for registry DesktopDPIOverride data:"

Get-ItemPropertyValue -Path $registryPath -Name DesktopDPIOverride | 
  Out-Default

PS returns (and no errors).

Test or depending upon one's needed returned data usage:

Looking for registry Logpixels data:
Get-ItemPropertyValue : Property Logpixels does not exist at path HKEY_CURRENT_USER\Control Panel\Desktop.
At line:9 char:1
+ Get-ItemPropertyValue -Path "HKCU:\Control Panel\Desktop" -Name Logpi ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-ItemPropertyValue], PSArgumentException
+ FullyQualifiedErrorId : Argument,Microsoft.PowerShell.Commands.GetItemPropertyValueCommand



Looking for registry Win8DpiScaling data:
0

Looking for registry DesktopDPIOverride data:
Get-ItemPropertyValue : Property DesktopDPIOverride does not exist at path HKEY_CURRENT_USER\Control Panel\Desktop.
At line:21 char:1
+ Get-ItemPropertyValue -Path "HKCU:\Control Panel\Desktop" -Name Deskt ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-ItemPropertyValue], PSArgumentException
+ FullyQualifiedErrorId : Argument,Microsoft.PowerShell.Commands.GetItemPropertyValueCommand


The calls for Logpixels and DesktopDPIOverride failed but the error did not stop PowerShell from
moving on to get the zero ( 0 ) returned from Win8DpiScaling.

Now to change the Windows keys values at HKCU:\Control Panel\Desktop the post reader would use the
PowerShell cmdlet Set-ItemProperty cmdlet (which will be used next in the Mixcraft registry code
sections). If the post reader changes any Windows settings (usually) the post reader would need to
restart Windows for those changes to take effect.

Note: Windows always changes these and a lot of other items, all of the time. So keep up on reading
about DPI registry settings when issues pop up (and they will). So since the poster never did any
Windows OS registry changes (the poster doesn't use much DPI), it's Mixcraft DPI/Scale actions time.

Currently Mixcraft has two DPI registry settings bDisableDPIAwareness and Mixcraft Scale. Also
notice the usage of a cmdlet's parameters splatting hash for shorter forum post lines.

Note: All of the PowerShell text/code/actions were created and ran within the Windows PowerShell ISE.

Time for some PowerShell interactive user, copy and paste, PowerShell text/code/actions.

Always have a good idea (understanding) of what any text/code/action will do.

Code: Select all


Write-Host
Write-Host "Mixcraft 10's current DPI setting is " -NoNewline

$mixcraftSplattingDpiParametersHash = @{ 
  Path = "HKCU:\SOFTWARE\Acoustica\Mixcraft10"
  Name = "bDisableDPIAwareness"
} # End of $splattingParametersHash = { }.

$dataDPI = Get-ItemPropertyValue @mixcraftSplattingDpiParametersHash

If($dataDPI) {
  Write-Host $dataDPI -NoNewline -ForegroundColor Cyan
  Write-Host " - Mixcraft's DPI Awareness is turned " -NoNewline
  Write-Host "off" -NoNewline -ForegroundColor Red
  Write-Host "."
}
Else {
  Write-Host $dataDPI -NoNewline -ForegroundColor Cyan
  Write-Host " - Mixcraft's DPI Awareness is turned " -NoNewline
  Write-Host "on" -NoNewline -ForegroundColor Green
  Write-Host "."
}

Write-Host
Write-Host "Mixcraft 10's current Scale setting is " -NoNewline

$mixcraftSplattingScaleParametersHash = @{ 
  Path = "HKCU:\SOFTWARE\Acoustica\Mixcraft10"
  Name = "Mixcraft Scale"
} # End of $splattingParametersHash = { }.

$currentMixcraftScale = Get-ItemPropertyValue @mixcraftSplattingScaleParametersHash

Write-Host $currentMixcraftScale -NoNewline -ForegroundColor Cyan
write-Host "."

PS returns (and no errors).

Mixcraft 10's current DPI setting is 0 - Mixcraft's DPI Awareness is turned on.

Mixcraft 10's current Scale setting is 100.

Note: Some people suggest backing up the Windows registry before doing any
actions with the Windows Registry. So if the user is interested in backing up the Windows registry,
before using it, there are many ways to do this backup actions (including via PowerShell) all
over the Internet (once again, these are after all, simple DawPsDemo examples).

Note: The poster does not check for bad input data. These are after all, simple
DawPsDemo examples (but maybe always test for bad input data in any production usage).

Now the poster will change (Set-) the two Mixcraft registry setting bDisableDPIAwareness and the
Mixcraft registry setting named "Mixcraft Scale".

Code: Select all


Write-Host
Write-Host "Ready " -NoNewline
Write-Host "to set " -NoNewline -ForegroundColor Green
Write-Host "Mixcraft 10's DPI setting to " -NoNewline
Write-Host "1 " -NoNewline -ForegroundColor Cyan
Write-Host "and then " -NoNewline
Write-Host "to set " -NoNewline -ForegroundColor Green
Write-Host "Mixcraft 10's Scale setting to " -NoNewline
Write-Host "125" -NoNewline -ForegroundColor Cyan
Write-Host "?"

Write-Host
Write-Host "Press Ctrl+C to quit or"
Pause

Write-Host
Write-Host "Setting Mixcraft's registry setting " -NoNewline
Write-Host 'bDisableDPIAwareness ' -NoNewline -ForegroundColor Cyan
Write-Host "to " -NoNewline
Write-Host "1" -NoNewline -ForegroundColor Cyan
Write-Host "."

$registryPath = $mixcraftSplattingDpiParametersHash.Path

Set-ItemProperty -Path $registryPath -Name "bDisableDPIAwareness" -Value 1

Write-Host
Write-Host "Getting Mixcraft 10's DPI change, the current DPI setting is " -NoNewline

$answer = Get-ItemPropertyValue @mixcraftSplattingDpiParametersHash

If($answer) {
  Write-Host $answer -NoNewline -ForegroundColor Cyan
  Write-Host " - Mixcraft's DPI Awareness is turned " -NoNewline
  Write-Host "off" -NoNewline -ForegroundColor Red
  Write-Host "."
}
Else {
  Write-Host $answer -NoNewline -ForegroundColor Cyan
  Write-Host " - Mixcraft's DPI Awareness is turned " -NoNewline
  Write-Host "on" -NoNewline -ForegroundColor Green
  Write-Host "."
}

Write-Host
Write-Host "Setting Mixcraft's registry setting " -NoNewline
Write-Host 'Mixcraft Scale ' -NoNewline -ForegroundColor Green
Write-Host "to " -NoNewline
Write-Host "125" -NoNewline -ForegroundColor Cyan
Write-Host "."

Set-ItemProperty -Path $registryPath -Name "Mixcraft Scale" -Value 125

Write-Host
Write-Host "Getting Mixcraft 10's Scale change, the current Scale setting is " -NoNewline

$currentMixcraftScale = Get-ItemPropertyValue @mixcraftSplattingScaleParametersHash

Write-Host $currentMixcraftScale -NoNewline -ForegroundColor Cyan
write-Host "."

Write-Host
Write-Host "Ready " -NoNewline
Write-Host "to set " -NoNewline -ForegroundColor Green
Write-Host "Mixcraft 10's DPI setting back to " -NoNewline
Write-Host "0 " -NoNewline -ForegroundColor Cyan 
Write-Host "and then " -NoNewline
Write-Host "to set " -NoNewline -ForegroundColor Green
Write-Host "Mixcraft 10's Scale setting back to " -NoNewline
Write-Host "100" -NoNewline -ForegroundColor Cyan
Write-Host "?"

Write-Host
Write-Host "Press Ctrl+C to quit or"
Pause

Set-ItemProperty -Path $registryPath -Name "bDisableDPIAwareness" -Value 0
Set-ItemProperty -Path $registryPath -Name "Mixcraft Scale" -Value 100

Write-Host
Write-Host "Getting Mixcraft 10's DPI change, the current DPI setting is " -NoNewline

$answer = Get-ItemPropertyValue @mixcraftSplattingDpiParametersHash
If($answer) {
  Write-Host $answer -NoNewline -ForegroundColor Cyan
  Write-Host " - Mixcraft's DPI Awareness is turned " -NoNewline
  Write-Host "off" -NoNewline -ForegroundColor Red
  Write-Host "."
}
Else {
  Write-Host $answer -NoNewline -ForegroundColor Cyan
  Write-Host " - Mixcraft's DPI Awareness is turned " -NoNewline
  Write-Host "on" -NoNewline -ForegroundColor Green
  Write-Host "."
}

Write-Host
Write-Host "Getting Mixcraft 10's Scale change, the current Scale setting is " -NoNewline

$currentMixcraftScale = Get-ItemPropertyValue @mixcraftSplattingScaleParametersHash

Write-Host $currentMixcraftScale -NoNewline -ForegroundColor Cyan
write-Host "."

PS returns (and no errors).

Ready to set Mixcraft 10's DPI setting to 1 and then to set Mixcraft 10's Scale setting to 125?

Press Ctrl+C to quit or
Press Enter to continue...:

And after pressing Enter to continue...

Setting Mixcraft's registry setting bDisableDPIAwareness to 1.

Getting Mixcraft 10's DPI change, the current DPI setting is 1 - Mixcraft's DPI Awareness is turned off.

Setting Mixcraft's registry setting Mixcraft Scale to 125.

Getting Mixcraft 10's Scale change, the current Scale setting is 125.

Ready to set Mixcraft 10's DPI setting back to 0 and then to set Mixcraft 10's Scale setting back to 100?

Press Ctrl+C to quit or
Press Enter to continue...:

And after pressing Enter to continue...

Getting Mixcraft 10's DPI change, the current DPI setting is 0 - Mixcraft's DPI Awareness is turned on.

Getting Mixcraft 10's Scale change, the current Scale setting is 100.

And don't forget, the poster has already shown a few ways to have PowerShell auto start the Daw app
Mixcraft with any project file's path (usually with the last closed project's path) and this action
makes a great way to end the above DPI settings actions too.

That's it for now, but notice that the post reader can start Mixcraft while in any PowerShell

Press Ctrl+C to quit or
Press Enter to continue...:

decision/pause action (by clicking on the Mixcraft icon or auto starting within another PowerShell
window or even within another ISE new PowerShell tab) to see what Mixcraft shows in

File -> Preferences -> Display -> Disable Per-Monitor DPI Awareness checkbox

and in the

File -> Preferences -> Display -> the dropbox named Scale.

But then, do not change any settings and be sure to close down Mixcraft before doing the Press Enter
to continue...: action.

Okay now all post readers can relax and and then let others know (through other posts) just how these
actions worked out for the post readers, and don't worry, be happy.

This was only a useful, advanced introduction for those post readers working with DPI issues. The
poster will soon get back to PowerShell text/code/actions (or tools) that any post reader can use
within the Windows PowerShell ISE, when the ISE is used as a music data controller.
jwmix
Posts: 39
Joined: Mon Apr 30, 2018 12:06 pm

Re: It is Mixcraft time

Post by jwmix »

There was a request for making a notepad lyrics's window into the current Windows top most window.

This can be done as a tool within the Windows PowerShell ISE, when the ISE is being used as a music
data controller.

Note: All of the PowerShell text/code/actions were created and ran within the Windows PowerShell ISE.

Time for some PowerShell interactive user, copy and paste, PowerShell text/code/actions.

Always have a good idea (understanding) of what any text/code/action will do.

Code: Select all


$lyricsFilePath = "$env:ProgramData\Acoustica\Mixcraft\drum-maps\cr-78.txt"

Get-ChildItem -Path $lyricsFilePath | 
  Out-Default

Write-Host
Write-Host "The " -NoNewline
Write-Host "lyrics " -NoNewline -ForegroundColor Cyan
Write-Host "are shown below:"

Write-Host
Get-Content -Path $lyricsFilePath |  
  Out-Default

Write-Host
Write-Host "Scroll " -NoNewline -ForegroundColor Yellow
Write-Host "up " -NoNewline -ForegroundColor Green
Write-Host "and " -NoNewline -ForegroundColor Yellow
Write-Host "down" -NoNewline -ForegroundColor Green
Write-Host ", to " -NoNewline -ForegroundColor Yellow
Write-Host "see all " -NoNewline -ForegroundColor Green
Write-Host "of the " -NoNewline -ForegroundColor Yellow
Write-Host "data" -NoNewline -ForegroundColor Green
Write-Host "." -ForegroundColor Yellow

To correctly keep the PowerShell's outputted format,
the PowerShell output is also placed within a code section too.
(Not code, just the formatted outputted data.)

Code: Select all



    Directory: C:\ProgramData\Acoustica\Mixcraft\drum-maps


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         3/4/2024   3:32 PM            205 cr-78.txt

PS returns (and no errors).

The lyrics are shown below:

36 Kick
37 Rim Shot
38 Snare
39 Claves
40 Accent
41 Low Conga
42 Hi-Hat
43 Low Bongo
44 Metal Beat
45 High Bongo
46 Tambourine
47
48 Low Guiro
49 Cymbal
50 High Guiro
51 Maracas
52 Cowbell

Scroll up and down,
to
see all of the data.

Wow. What heart warmin' lyrics, ya'll crying too?

The poster will move that active Mixcraft drum map's data into a notepad app and then make that
notepad's window, the current Windows top most window.

To do the top most action, the poster will use the below Win32 library call (that like thousands of
other Windows actions, is sitting in the post reader's computer, just waiting to be used):

bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

The notepad's main window handle is the hWnd parameter.

A PowerShell user created variable, named $hwndTopMost, will be set to -1 for the hWndInsertAfter
parameter.

The four parameters' ints X,Y,cx,cy are all set to 0, meaning keep the window size/position as it is.

And in the soon to be shown, PowerShell text/code/actions (in the forum's code section below), the
post reader will see the chosen uFlags settings.

Look up Microsoft's Windows SetWindowPos to see all of the uFlags, ints, hWndInsertAfter, hWnd data.

https://learn.microsoft.com/en-us/windo ... twindowpos

Note: Because the poster used the lyrics notepad's main window handle, the
notepad's window does not need to be the current Windows active window, at the time the poster set's
notepad to be the top most window.

Note: PowerShell remembers all done within it's current session (until the PowerShell window closes),
so all of the above lyric's notepad defined data, is still available to use.

Now the poster is moving on to move the active Mixcraft drum map data into a notepad app's window
(by starting the app notepad via the lyrics text file's path), and then the poster will make that
notepad lyrics window, the current Windows top most window.

Note: The poster uses a PowerShell Here-String object ( @" lines of text "@ )
to define the programming SetWindowPos definition and a PowerShell splatting pararmeter hash object
( @{ name = setting } ) for smaller forum post lines.

Code: Select all


notepad $lyricsFilePath

$signature = @"
[DllImport("user32.dll")]public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
"@

$addTypeSplattingParamaters = @{ 
  MemberDefinition = $signature
  Name = "Win32SetWindowPos"
  Namespace = "Win32Functions"
  PassThru = $true
} # End of $addTypeSplattingParamaters = @{ }.

$setWindowPos = Add-Type @addTypeSplattingParamaters

$swpNoSize = 1
$swpNoMove = 2
$swpNoActivate = 16
$swpShowWindow = 64

$useFlags = $swpNoSize + $swpNoMove + $swpNoActivate + $swpShowWindow

$hwndTopMost = -1

$notepadProcessHandle = Get-Process | 
  Where-Object -Property MainWindowTitle -Match "cr-78" | 
    Select-Object -ExpandProperty MainWindowHandle

$setWindowPos::SetWindowPos($notepadProcessHandle, $hwndTopMost, 0, 0, 0, 0, $useFlags) | 
  Out-Null

PS returns nothing (and no errors).

But Bingo, up pops notepad with the active Mixcraft drum map data (that is used as the lyrics) and
that same notepad object is the current Windows top most window. And that notepad can be moved around,
change it's size or minimize it or maximize it and bring it back up or down to it's original size.

And to get rid of the notepad app, just close/exit it.

Note: Since this is an active Mixcraft drum map's data, if on the notepad's
close/exit action, if the notepad asks to save the file, because the post reader might have made
changes to it either by accident/mistake (or plain old age forgetfulness), maybe (almost certainly)
pick Don't Save.

Note: At any time, there can only be one current Windows top most window.

How do I create a topmost window that is never covered by other topmost windows?
https://devblogs.microsoft.com/oldnewth ... 0/?p=11253

Mmmm, after reading the above link, maybe ask every system/Daw app creator, in the post reader's
computer, if they have any current Windows top most windows. Plus this post also shows that not
everything needs to be done, by the Daw app's programmers.

Mmmm, since there are business PowerShell posts, all over the Internet, that can be changed for any
similar audio/midi/sounds actions, maybe it is time for any post reader to post their tool(s) for
the Windows PowerShell ISE, when the ISE is used as a music data controller.
Post Reply