Play a MIDI voice (Dev C++ console program)

Please support our C++ advertiser: Intel Parallel Studio Home
vegaseat vegaseat is offline Offline Nov 22nd, 2004, 2:13 am |
2
You can access the sound chip to play midi voices using winmm.lib, or in case of Dev C++ the libwinmm.a library. There are 128 midi voices to pick from, anything from the Acoustic Grand Piano = 0 to the Gunshot = 127.
Quick reply to this message  
C++ Syntax
  1. // sound a tugboat toot using a midi voice from the winmm.lib
  2. // in case of Dev C++ link with libwinmm.a via
  3. // Project>>Project Options>>Parameters>>Add Lib>>libwinmm.a
  4. // BCX generated C code painstakingly modified for Dev C++
  5. //
  6. // Sound(Frequency,Duration[,Volume,Voice,Tempo])
  7. // Volume = 0 to 127 (off to loudest)
  8. // Voice = 0 to 127 (Shanai = 111, Tuba = 58, Accordion = 21)
  9. // more midi voices:
  10. // Rock Organ = 18, Marimba = 12, Steel String Guitar = 25
  11. // Choir Aahs = 52, Alto Sax = 65, Bird Tweet = 123, Sitar = 104
  12. // FX 8 (sci-fi) = 103, FX 3 (crystal) = 98, Glockenspiel = 9
  13. //
  14. // a Dev-C++ tested Console Application by vegaseat 21nov2004
  15.  
  16. #include <cmath>
  17. #include <windows.h>
  18. #include <mmsystem.h>
  19.  
  20. using namespace std;
  21.  
  22. #define SNDQUE 10000
  23.  
  24. typedef struct _soundtype
  25. {
  26. double Freq;
  27. int Dura;
  28. int Vol;
  29. int Voice;
  30. double Tempo;
  31. int sndTid;
  32. } soundtype, *LPSOUNDTYPE;
  33.  
  34. static soundtype SndPmtr[SNDQUE+1];
  35. static int gTenter;
  36. static int gTwait;
  37. static int gTexit;
  38. static int gTarray;
  39. static BOOL gTsig;
  40. static HANDLE gSThread = NULL;
  41.  
  42. double Round (double,int);
  43. double Abs (double);
  44. int Sound (float,int=0,int=127,int=0,float=1);
  45. // changed this from int PlaySnd(void) to:
  46. DWORD WINAPI PlaySnd (LPVOID);
  47.  
  48.  
  49. int main()
  50. {
  51. // Tugboat whistle sound 95 hertz, 2000ms, 127 = loud, 111 = Shanai
  52. // experiment with your own sounds, it's fun ...
  53. Sound(95,2000,127,111); // 2 second blast
  54. Sound( 1,1000, 0,111); // 1 second of silence
  55. Sound(95,2000,127,111); // 2 second blast
  56. Sound( 1,1000, 0,111); // 1 second of silence
  57. Sound(95,2000,127,111); // 2 second blast
  58.  
  59. // wait till que is empty
  60. while(Sound(0) != 0)
  61. {
  62. Sleep(10);
  63. }
  64.  
  65. return 0;
  66. }
  67.  
  68.  
  69. double Round (double n, int d)
  70. {
  71. return (floor((n)*pow(10.0,(d))+0.5)/pow(10.0,(d)));
  72. }
  73.  
  74.  
  75. double Abs (double a)
  76. {
  77. if (a < 0) return -a;
  78. return a;
  79. }
  80.  
  81.  
  82. int Sound (float Freq,int Dura,int Vol,int Voice,float Tempo)
  83. {
  84. DWORD dwThreadId;
  85.  
  86. if (Freq == 0 && Dura < 1) return gTenter-gTexit;
  87. // silence
  88. if (Freq == 0) Vol = 0;
  89. if (Dura < 5) Dura = 5;
  90. gTenter++;
  91. gTsig = FALSE;
  92. if (gTenter >= SNDQUE)
  93. {
  94. gTarray = gTenter % SNDQUE+1;
  95. }
  96. else
  97. {
  98. gTarray=gTenter;
  99. }
  100. SndPmtr[gTarray].Freq = Freq;
  101. SndPmtr[gTarray].Dura = Dura;
  102. SndPmtr[gTarray].Tempo = Tempo;
  103. SndPmtr[gTarray].Vol = Vol;
  104. SndPmtr[gTarray].Voice = Voice;
  105. SndPmtr[gTarray].sndTid = gTenter;
  106. if (gSThread == NULL && (Freq == Abs(Freq) || Freq == 0))
  107. {
  108. // "PlaySnd" needs casting (void *)
  109. gSThread = CreateThread(NULL,0,PlaySnd,(void *)"PlaySnd",0,&dwThreadId);
  110. Sleep(1);
  111. return 0;
  112. }
  113. if (Freq != Abs(Freq))
  114. {
  115. if (Freq == -1)
  116. {
  117. Freq = 0;
  118. SndPmtr[gTarray].Vol=0;
  119. }
  120. SndPmtr[gTarray].Freq=Abs(Freq);
  121. gTsig=TRUE;
  122. while(gSThread!=NULL)
  123. {
  124. Sleep(10);
  125. }
  126. gTexit = gTenter-1;
  127. gTwait = gTenter-1;
  128. gTsig = FALSE;
  129. return PlaySnd(0); // needs some kind of argument
  130. }
  131. return 0;
  132. }
  133.  
  134.  
  135. DWORD WINAPI PlaySnd (LPVOID)
  136. {
  137. soundtype LocSndPar;
  138. int lTarray;
  139.  
  140. while(gTenter > gTexit && gTsig == FALSE)
  141. {
  142. gTwait++;
  143. if (gTwait >= SNDQUE)
  144. lTarray = gTwait % SNDQUE+1;
  145. else
  146. lTarray = gTwait;
  147. LocSndPar = SndPmtr[lTarray];
  148. int Note = 0;
  149. int Phrase = 0;
  150. HMIDIOUT hMidi;
  151. midiOutOpen(&hMidi,(UINT)-1,0,0,CALLBACK_NULL);
  152. midiOutShortMsg(hMidi,(256*LocSndPar.Voice)+192);
  153. // convert frequency to midi note
  154. Note = (int)Round((log(LocSndPar.Freq)-log(440.0))/log(2.0)*12+69,0);
  155. Phrase = (LocSndPar.Vol*256+Note)*256+144;
  156. midiOutShortMsg(hMidi,Phrase);
  157. Sleep((int)(LocSndPar.Dura*(1/LocSndPar.Tempo+0.0001)));
  158. Phrase = (LocSndPar.Vol*256+Note)*256+128;
  159. midiOutShortMsg(hMidi,Phrase);
  160. midiOutClose(hMidi);
  161. gTexit++;
  162. }
  163. CloseHandle(gSThread);
  164. gSThread = NULL;
  165. return 0;
  166. }
  167.  
0
vegaseat vegaseat is offline Offline | Jan 31st, 2005
Replaced Mr. Bloat header iostream with the correct cmath header. This brought the exe file size down from 400k to 19k. Sorry about any discommode!
 
0
Tales Tales is offline Offline | Mar 9th, 2007
The code works perfect in DEV C++, but it does not for VC++ (I am running Visual Studio 2005).
 
0
bugmenot bugmenot is offline Offline | Nov 24th, 2007
To compile in Visual Studio, add
  1. #pragma comment(lib, "winmm.lib")
 
0
t3ch|\/|4n t3ch|\/|4n is offline Offline | Sep 1st, 2008
This is good code, but I am trying to turn my keyboard into a piano for a fun console app (u dont know how boring cubicles are until u live in one). I do graphics (mostly) and have no experience in sound beyond system bells. Can someone provide some simple musical note code?
 
0
Pepperonio Pepperonio is offline Offline | Sep 30th, 2009
Thanks for the code, but when I tried to run it (in Dev C++ and Codeblocks) it was having problem with midiOutOpen()

Did I miss something?
 
-2
marco93 marco93 is offline Offline | Sep 30th, 2009
Use Petzold code instead, 10 x better.
 
0
yonghc yonghc is offline Offline | Oct 1st, 2009
Dear Vegaseat,

I am interested to hear music or sound from your midi program using Dev-C++. And I did the following as well:

Project>>Project Options>>Parameters>>Add Lib>>libwinmm.a

I created a console application. In Main.cpp, I pasted your whole program. Managed to compile successfully.

When I executed the compiled program, I got a blank screen with a blinking cursor on the top right hand corner, but no sound output.

What could I have done incorrectly?

Regards,
 
0
vb6exp32 vb6exp32 is offline Offline | 12 Days Ago
thank you vegaseat your snippet up above worked perfectly in my dev c++. I've gone to the "add to reputation" page where I've left you a nod. thanks again. though ... I was wondering about this BCX that was talked about on an other page I looked at. I've been building things in classic vb6 since 1999 now & was curious to know if this BCX could translate its code to compile some working C/C++ apps. otherwise i might have to migrate over to quick basic if BCX might be finicky about what type of basic code it can translate. I've done some audio work with vb6 and have a certain project where I've "installed" a directx 8 reference and built a sound generator. It sounds pretty nice, the blending of the multi-oscillator output is very sweet, plus i have added an additional feature that could render a singular *.wav sound. though with all that could be in C/C++ or vb6 programming, I would seriously love to develop VST synth plugins with C/C++. I suppose that would take some time doing, but in any case thanks so much for your midi tutorial I've learned much from it in the time that I've studied it.
 
0
vb6exp32 vb6exp32 is offline Offline | 12 Days Ago
though if i could ask for one small favor possibly ? any chance i could find a snippet to allow a windows frame accompanied with buttons to play separate sounds ? and then possibly a selector where different MIDI fonts could be chosen at runtime ? i'm always trying to enhance what i could learn about audio programming. i've built some fairly decent VST plugins in max/msp. (www.cycling74.com)
max/msp has helped me to learn much of a different type of visual programming. it is a visual OOP environment, though, it does have its drawbacks/shortcomings to a slight extent. please pardon my sounding a bit greedy for information, i wasnt trying to be,... though i would love to know as much as i can about EVERYTHING audio where vb6/C/C++ is concerned. and i thank you ever so much for your showing the snippet.
Last edited by vb6exp32; 12 Days Ago at 11:41 pm.
 
 

Message:


Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC