locked
VB .net (2010) How to play Midi from Add Resource with mciSendString RRS feed

  • Question

  • Please little help source code!


    Public Class Form1
        'The Main API call that will be used for the playback.
        Private Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" _
        (ByVal lpstrCommand As String, ByVal lpstrReturnString As Integer, ByVal uReturnLength As _
        Integer, ByVal hwndCallback As Integer) As Integer
        Private Declare Function GetShortPathName Lib "kernel32" Alias "GetShortPathNameA" (ByVal lpszLongPath As String, ByVal lpszShortPath As String, ByVal cchBuffer As Integer) As Integer

        Private Sub Form1_Load()
            Me.Show()
        End Sub
        Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
            'Will hold the path to the movie file.
            'Dim filename As String
            'Dim filename As String
            'Holds the return value of mciSendstring. Not used for anything in this article though.
            Dim lRet As Long
            'The path to the movie or video to play.
            'filename = "C:\Hohohohorgasz.mid"
            'filename = My.Resources.Hohohohorgasz
            'Now add the quotes around the path.
            'filename = Chr(34) & filename & Chr(34)
            'Const Path As String = """C:\Hohohohorgasz.mid"""
            Dim musicPath As String = My.Resources.ResourceManager.GetObject("Hohohohorgasz.mid")

            lRet = mciSendString("open ", musicPath, Microsoft.VisualBasic.AscW(" type sequencer alias Hohohohorgasz"), 0)

            lRet = mciSendString("play hohohohorgasz", 0, 0, 0)
            'lRet = mciSendString("close all", "", 0, 0)
        End Sub
    End Class

    Sunday, May 29, 2016 3:57 PM

Answers

  •  This example works fine on my machine.  There are minimal changes as to what the code does compared to what you are showing.  However,  i did add the correct Vb.Net signature for the mciSendString function and used the ApplicationData folder to write the midi file to.

     If this does not work then you should acquire a few midi files that are known to be good and try it with them.  If you have tried a few other midi files and know that they are good,  then perhaps you need some codec(s) installed as Monkeyboy was saying.  I install the K-Lite Codec Pack on all my machines so,  perhaps it installs some codec that is needed...???

    Imports System.Runtime.InteropServices
    
    Public Class Form1
        <DllImport("winmm.dll", EntryPoint:="mciSendStringW")>
        Private Shared Function mciSendStringW(<MarshalAs(UnmanagedType.LPTStr)> ByVal lpszCommand As String, <MarshalAs(UnmanagedType.LPWStr)> ByVal lpszReturnString As System.Text.StringBuilder, ByVal cchReturn As UInteger, ByVal hwndCallback As IntPtr) As Integer
        End Function
    
        Private MidiFolder As String = IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), My.Application.Info.AssemblyName)
        Private MidiFile As String = IO.Path.Combine(MidiFolder, "Midi_01.mid")
        Private Playing As Boolean = False
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            If Not IO.Directory.Exists(MidiFolder) Then IO.Directory.CreateDirectory(MidiFolder) 'if our folder does not exist in the AppData folder, then create it
            If Not IO.File.Exists(MidiFile) Then IO.File.WriteAllBytes(MidiFile, My.Resources.Midi_01) 'if the midi file does not exist, then write it to the hard drive
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            If Not Playing Then
                If mciSendStringW("open " & Chr(34) & MidiFile & Chr(34) & " alias Midi_1", Nothing, 0, IntPtr.Zero) = 0 Then
                    Playing = (mciSendStringW("play Midi_1", Nothing, 0, IntPtr.Zero) = 0)
                Else
                    MessageBox.Show("Error opening the following file:" & vbNewLine & MidiFile)
                End If
            End If
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            If Playing Then
                mciSendStringW("stop Midi_1", Nothing, 0, IntPtr.Zero)
                mciSendStringW("close Midi_1", Nothing, 0, IntPtr.Zero)
                Playing = False
            End If
        End Sub
    End Class
    


    If you say it can`t be done then i`ll try it

    Wednesday, June 1, 2016 10:50 PM

All replies

  • When you store the MIDI file in the Resources you get a Byte array containing the file data, so My.Resources.ResourceManager.GetObject("Hohohohorgasz.mid") returns a byte array not a string path.

    Instead of storing the MIDI file in the resources, just add it as a file to the project and set its Copy to Output Directory property to True.

    Then add references to your project for PresentationCore and WindowsBase.

    Now you can create an instance of MediaPlayer and have it play your MIDI file:

    Dim mp = New Windows.Media.MediaPlayer
    mp.Open(New Uri("Hohohohorgasz.mid"))
    mp.Play()
    


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Sunday, May 29, 2016 5:59 PM
  • If you are looking for a solution which uses a stream to play the resource then MCI send string and Media Player or Windows Media Player and various others will not work but possibly DirectSound or whatever it's called may or possibly NAudio if it supports Midi.

    Option Strict On
    
    Imports System.Text
    Imports System.Runtime.InteropServices
    Imports System.IO
    
    Public Class Form1
    
        <DllImport("winmm.dll")> _
        Private Shared Function mciSendString(command As String, returnValue As StringBuilder, returnLength As Integer, winHandle As IntPtr) As Integer
        End Function
    
        Dim PathToUse As String = ""
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Me.Location = New Point(CInt((Screen.PrimaryScreen.WorkingArea.Width / 2) - (Me.Width / 2)), CInt((Screen.PrimaryScreen.WorkingArea.Height / 2) - (Me.Height / 2)))
            PathToUse = IO.Path.GetTempPath
            PathToUse = IO.Path.Combine(PathToUse, "Top Gun.Mid")
            My.Computer.FileSystem.WriteAllBytes(PathToUse, My.Resources.Top_Gun.ToArray, False)
        End Sub
    
        Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
            Try
                MciString("close crooner")
            Catch ex As Exception
            End Try
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            MciString("open " & ChrW(34) & PathToUse & ChrW(34) & " alias music")
            MciString("play music")
            MciString("close crooner")
        End Sub
    
        Private Sub MciString(Cmd As String)
            Dim reply As New StringBuilder(256)
            mciSendString(Cmd, reply, 256, IntPtr.Zero)
        End Sub
    
    End Class


    La vida loca

    Monday, May 30, 2016 12:09 AM
  • Thanks Answer for my Question.

    Little problem, no Errors, NO MUSIC. Please read!

    Option Strict On
    Imports System.Text
    Imports System.Runtime.InteropServices
    Imports System.IO
    Public Class Form1
        <DllImport("winmm.dll")> _
        Private Shared Function mciSendString(ByVal command As String, ByVal returnValue As StringBuilder, ByVal returnLength As Integer, ByVal winHandle As IntPtr) As Integer
        End Function
        Dim PathToUse As String = ""
        Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs)
            Me.Location = New Point(CInt((Screen.PrimaryScreen.WorkingArea.Width / 2) - (Me.Width / 2)), CInt((Screen.PrimaryScreen.WorkingArea.Height / 2) - (Me.Height / 2)))
            PathToUse = IO.Path.GetTempPath
            PathToUse = IO.Path.Combine(PathToUse, "Hohohohorgasz.mid")
            My.Computer.FileSystem.WriteAllBytes(PathToUse, My.Resources.Resource1.Hohohohorgasz, False)
        End Sub
        Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs)
            Try
                MciString("close crooner")
            Catch ex As Exception
            End Try
        End Sub
        Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
            MciString("open " & ChrW(34) & PathToUse & ChrW(34) & " alias Hohohohorgasz")
            MciString("play Hohohohorgasz")
            MciString("close crooner")
        End Sub
        Private Sub MciString(ByVal Cmd As String)
            Dim reply As New StringBuilder(256)
            mciSendString(Cmd, reply, 256, IntPtr.Zero)
        End Sub
    End Class

    Wednesday, June 1, 2016 6:02 PM
  • Thanks Answer for my Question.

    Little problem, no Errors, NO MUSIC. Please read!

    Option Strict On
    Imports System.Text
    Imports System.Runtime.InteropServices
    Imports System.IO
    Public Class Form1
        <DllImport("winmm.dll")> _
        Private Shared Function mciSendString(ByVal command As String, ByVal returnValue As StringBuilder, ByVal returnLength As Integer, ByVal winHandle As IntPtr) As Integer
        End Function
        Dim PathToUse As String = ""
        Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs)
            Me.Location = New Point(CInt((Screen.PrimaryScreen.WorkingArea.Width / 2) - (Me.Width / 2)), CInt((Screen.PrimaryScreen.WorkingArea.Height / 2) - (Me.Height / 2)))
            PathToUse = IO.Path.GetTempPath
            PathToUse = IO.Path.Combine(PathToUse, "Hohohohorgasz.mid")
            My.Computer.FileSystem.WriteAllBytes(PathToUse, My.Resources.Resource1.Hohohohorgasz, False)
        End Sub
        Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs)
            Try
                MciString("close crooner")
            Catch ex As Exception
            End Try
        End Sub
        Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
            MciString("open " & ChrW(34) & PathToUse & ChrW(34) & " alias Hohohohorgasz")
            MciString("play Hohohohorgasz")
            MciString("close crooner")
        End Sub
        Private Sub MciString(ByVal Cmd As String)
            Dim reply As New StringBuilder(256)
            mciSendString(Cmd, reply, 256, IntPtr.Zero)
        End Sub
    End Class

    Does the Midi file play in Windows Media Player O.K.? I had a Midi file that would not play in Windows Media Player even though I have a codec installed for Midi files. So I went to some website and downloaded a Midi file which did play. Apparently the original Midi I tried to play is different in some fashion from the Midi file that did play.

    Do you have Codec(s) installed to play Midi files? If your Midi won't play in Windows Media Player then MCI SendString can't play it either I'm fairly certain and I didn't provide code to catch the error.

    Regardless you need to validate that some other program can play the file in question.

    There's some website that has a Codec pack I downloaded once a while back. I'm not certain a Midi Codec comes with Windows and I've no idea what your system is either. I have Win7 64 bit and that Codec pack worked on my system.

    I suppose Windows Media Player is x64 on my system, the normal one I use, and maybe there's x86 version too in SysWow64 location but I haven't checked.

    I'll update this post with the link to the Codec download site when I find the previous thread I posted it in. Take a few minutes.

    When you call this function "mciSendString" it returns an integer of probably 0 or 1 I suppose depending on if it can play the file or not maybe. So if your code called "mciSendString" like below you could see the result. You would need to add a Label to your Form and alter the code in the MciString sub like below.

    Label1.Text = mciSendString(Cmd, reply, 256, IntPtr.Zero).ToString
    
    or maybe
    
    Label1.Text = Cstr(mciSendString(Cmd, reply, 256, IntPtr.Zero))

    Update: You should read this thread since I've no idea what OS you have or whether it is x86 or x64 either. I may update this post again in a few minutes with some other info. Also I believe Win7 comes with Midi Codec installed. Link - What happened to MIDI Mapper on Windows 8 (and later)?

    This link you can download Codecs but I can't guarantee the link or that the download is non-viral even though I used it awhile back and no viruses have been detected on my system. Use at your own risk.

    Media Player Codec Pack


    La vida loca

    Wednesday, June 1, 2016 8:53 PM
  • @BodeHabib

    On another note that Midi file that Windows Media Player will not play causes this issue with Windows Media Player (that Midi is called "mouseinputdata.mid", see image below. Other Midi file I downloaded from some website ("Top Gun Midi file") works fine though.


    La vida loca

    Wednesday, June 1, 2016 9:16 PM
  •  This example works fine on my machine.  There are minimal changes as to what the code does compared to what you are showing.  However,  i did add the correct Vb.Net signature for the mciSendString function and used the ApplicationData folder to write the midi file to.

     If this does not work then you should acquire a few midi files that are known to be good and try it with them.  If you have tried a few other midi files and know that they are good,  then perhaps you need some codec(s) installed as Monkeyboy was saying.  I install the K-Lite Codec Pack on all my machines so,  perhaps it installs some codec that is needed...???

    Imports System.Runtime.InteropServices
    
    Public Class Form1
        <DllImport("winmm.dll", EntryPoint:="mciSendStringW")>
        Private Shared Function mciSendStringW(<MarshalAs(UnmanagedType.LPTStr)> ByVal lpszCommand As String, <MarshalAs(UnmanagedType.LPWStr)> ByVal lpszReturnString As System.Text.StringBuilder, ByVal cchReturn As UInteger, ByVal hwndCallback As IntPtr) As Integer
        End Function
    
        Private MidiFolder As String = IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), My.Application.Info.AssemblyName)
        Private MidiFile As String = IO.Path.Combine(MidiFolder, "Midi_01.mid")
        Private Playing As Boolean = False
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            If Not IO.Directory.Exists(MidiFolder) Then IO.Directory.CreateDirectory(MidiFolder) 'if our folder does not exist in the AppData folder, then create it
            If Not IO.File.Exists(MidiFile) Then IO.File.WriteAllBytes(MidiFile, My.Resources.Midi_01) 'if the midi file does not exist, then write it to the hard drive
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            If Not Playing Then
                If mciSendStringW("open " & Chr(34) & MidiFile & Chr(34) & " alias Midi_1", Nothing, 0, IntPtr.Zero) = 0 Then
                    Playing = (mciSendStringW("play Midi_1", Nothing, 0, IntPtr.Zero) = 0)
                Else
                    MessageBox.Show("Error opening the following file:" & vbNewLine & MidiFile)
                End If
            End If
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            If Playing Then
                mciSendStringW("stop Midi_1", Nothing, 0, IntPtr.Zero)
                mciSendStringW("close Midi_1", Nothing, 0, IntPtr.Zero)
                Playing = False
            End If
        End Sub
    End Class
    


    If you say it can`t be done then i`ll try it

    Wednesday, June 1, 2016 10:50 PM
  • I probing, not work, write the error opening Massage. Not generated the midi out (ApplicationData).

    Probing resource build action: None, Embedded resource.

    Windows 10 the System, and Malwarebytes, and Ad-aware.

    Saturday, June 4, 2016 12:35 PM
  • I probing, not work, write the error opening Massage. Not generated the midi out (ApplicationData).

    Probing resource build action: None, Embedded resource.

    Windows 10 the System, and Malwarebytes, and Ad-aware.


    O.K.

    La vida loca

    Saturday, June 4, 2016 2:09 PM
  • I probing, not work, write the error opening Massage. Not generated the midi out (ApplicationData).

    Probing resource build action: None, Embedded resource.

    Windows 10 the System, and Malwarebytes, and Ad-aware.

     Hmmm....  I am not sure what you are saying or asking in that reply.

     

     @ Monkeyboy,

     OT - Good pistachios.  Finally checked emails too.  8)


    If you say it can`t be done then i`ll try it

    Saturday, June 4, 2016 6:16 PM