Solved

Sending MIDI notes to built-in soundcard

Posted on 2014-11-15
4
374 Views
Last Modified: 2014-11-19
Newbie question:
I'm trying to get Excel 2013 to send a MIDI note (say 64) to play on the built-in device on my Windows 8 laptop.

Can someone please give me a 101 ? (as a starting point for a little more challenging project)
Thanks
0
Comment
Question by:hindersaliva
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
4 Comments
 
LVL 40

Expert Comment

by:als315
ID: 40445409
It is relatively simple to send midi file. Look at sample (place sample midi file to any folder and correct path to file in sub)
PlayMidi.xlsm
0
 

Author Comment

by:hindersaliva
ID: 40445584
als315, I need to play ONE note, for example when a shape is clicked, rather than triggering the the playing of a MIDI file.

There's an example here - Duelling Banjos by John Walkenbach.
http://j-walkblog.com/index.php?/weblog/posts/dueling_banjos_in_excel/ 

But it doesn't work on my Excel 2013/Win8.

Here's his code

Option Explicit
Private Declare Function midiOutOpen Lib "winmm.dll" _
    (lphMidiOut As Long, _
    ByVal uDeviceID As Long, _
    ByVal dwCallback As Long, _
    ByVal dwInstance As Long, _
    ByVal dwFlags As Long) As Long
 
Private Declare Function midiOutClose Lib "winmm.dll" _
    (ByVal hMidiOut As Long) As Long

Private Declare Function midiOutShortMsg Lib "winmm.dll" _
    (ByVal hMidiOut As Long, _
    ByVal dwMsg As Long) As Long
 
Private Declare Sub Sleep Lib "Kernel32" (ByVal dwMilliseconds As Long)
Dim hMidiOut As Long
Public lanote As Long
 
Sub PlayMIDI(voiceNum, noteNum, Duration)
    Dim Note As Long
    On Error Resume Next
    midiOutClose hMidiOut
    midiOutOpen hMidiOut, 0, 0, 0, 0
    midiOutShortMsg hMidiOut, RGB(192, voiceNum - 1, 127)
    lanote = 12 + CLng(noteNum)
    Note = RGB(144, lanote, 127)
    midiOutShortMsg hMidiOut, Note
    Sleep (Duration)
    midiOutClose hMidiOut
 End Sub

Sub PlayWorksheetNotes()
    Dim r As Long
    'ActiveSheet.Calculate
    For r = 2 To Application.CountA(Range("A:A"))
        Cells(r, 4).Select
        Call PlayMIDI(Cells(r, 1), Cells(r, 2), Cells(r, 3))
    Next r
 End Sub

Open in new window

0
 
LVL 70

Accepted Solution

by:
Qlemo earned 500 total points
ID: 40445679
The issue is that the code is too simple, and the device calls to slow, to get something useful. You can try out by multiplying the Duration in line 29 with 10 - you should here sounds (if MIDI works at all). The original Duelling Banjos sample does produce sound only in a reasonable way if I double the duration. This even applies for playing one single note.

You might also have to set up the volume for Excel (or MS VBA) in your Mixer application first.

Please try with this slightly improved code, which gives better results:
Option Explicit
Private Declare Function midiOutOpen Lib "winmm.dll" _
    (lphMidiOut As Long, _
    ByVal uDeviceID As Long, _
    ByVal dwCallback As Long, _
    ByVal dwInstance As Long, _
    ByVal dwFlags As Long) As Long
 
Private Declare Function midiOutClose Lib "winmm.dll" _
    (ByVal hMidiOut As Long) As Long

Private Declare Function midiOutShortMsg Lib "winmm.dll" _
    (ByVal hMidiOut As Long, _
    ByVal dwMsg As Long) As Long
 
Private Declare Sub Sleep Lib "Kernel32" (ByVal dwMilliseconds As Long)
Dim hMidiOut As Long
Public lanote As Long

Sub PlayMIDI(voiceNum, noteNum, Duration)
    Dim Note As Long
    On Error Resume Next
    midiOutShortMsg hMidiOut, RGB(192, voiceNum - 1, 127)
    lanote = 12 + CLng(noteNum)
    midiOutShortMsg hMidiOut, RGB(144, lanote, 127)
    Sleep (Duration)
    midiOutShortMsg hMidiOut, RGB(128, lanote, 127)
 End Sub

Sub PlayWorksheetNotes()
    Dim r As Long
    'ActiveSheet.Calculate
    midiOutOpen hMidiOut, 0, 0, 0, 0
    For r = 2 To Application.CountA(Range("A:A"))
        Cells(r, 4).Select
        Call PlayMIDI(Cells(r, 1), Cells(r, 2), Cells(r, 3))
    Next r
    midiOutClose hMidiOut
 End Sub
 

Open in new window

The improvement is that the MIDI device is not reopened and closed which each note, but only once. And the duration is implemented by Note On, Wait, Note Off now.
0
 

Author Comment

by:hindersaliva
ID: 40451812
Qlemo, yes it now works as it should. Thank you.
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In Part II of this series, I will discuss how to identify all open instances of Excel and enumerate the workbooks, spreadsheets, and named ranges within each of those instances.
This article describes how you can use Custom Document Properties to store settings and other information in your workbook so that they will be available the next time you open the workbook.
The viewer will learn how to create a normally distributed random variable in Excel, use a normal distribution to simulate the return on an investment over a period of years, Create a Monte Carlo simulation using a normal random variable, and calcul…
This Micro Tutorial demonstrates in Microsoft Excel how to consolidate your marketing data by creating an interactive charts using form controls. This creates cool drop-downs for viewers of your chart to choose from.

695 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question