Piano Key Distribution
Piano has a total of 88 keys, 52 white keys, and 36 black keys.
It is divided
Bass: incomplete big-two-character group, big-character group, and big-character group;
Central audio area: Small character group, small character group, and small character group;
Tweeting area: three groups of small characters, four groups of small words, and incomplete five groups of small words.
Except for Group A, Group # A, and group B, group C only has one voice.
The other groups have 12 audios: C, # C, D, # D, E, F, # F, G, # G, A, # A, and B.
Flash piano games
There is a flash game on the Internet.KeyboardBulletPiano, Match the keys on the keyboard with the piano, for example:
Game site: http://www.hao352.com/tangangqin.htm
The starting point of this game is to make the piano popular and simple. The principle is as follows:/// // <Br/> // low Section <br/> // 1_2_3_4_5_6_7 _ <br/> // abcdefg </P> <p> // middle section <br/>/ /1-2-3-4-5-6-7-<br/> // hijklmn </P> <p> // high section <br/> // 1'2' 4 '5' 7' <br/> // opqrstu <br/> ////////////// ////////////////////
AboveConversion table, There are three numeric suffixes:
- '_'Indicates the bass segment
- '-'Indicates the audio segment
- '`'Indicates the treble
A score based on this encoding is as follows:
Blue and white porcelain flash keyboard piano score </P> <p> LLJ ijf ijlj I <br/> LLJ ije ijli H <br/> hijlmlj ljji I <br/> HIH IHI ijlj <br/> LLJ ijf ijlji <br/> LLJ ije ijlih <br/> hij lmlj ljjii ejiih <br/>
Players canEncoding, Press the corresponding button to play a song ~
Principle Analysis
First, to make such a game, we need a MIDI voice engine:CodeprojectWe found a good open-source MIDI engine: midiwrapper.
URL: http://www.codeproject.com/kb/audio-video/midiwrapper.aspx. The author implements a standard piano keyboard.
Then, the music score is converted into corresponding notes. Music score is a string of characters.Conversion table, Which is converted to a bass, median, or tweeter note. How can this problem be implemented in the code?
Cmidiwrapper defines 12 basic sounds in the piano,
Enum note_id {C, c_sharp, D, d_sharp, E, F, f_sharp, G, g_sharp, A, <br/> a_sharp, B}; <br/>
Sharp represents a high half tone, but we usually use seven notes:1, 2, 3, 4, 5, 6, 7 <=> C, D, E, F, G, a B.
Note_per_octave = 12, // a group of 12 voices
Low_note = 36 // The start value of the low note.
Noteid = (octave) * note_per_octave + low_note;
Ave ave indicates the number of audio groups. There are five groups from 0 to 4. There are five levels from the bass to the top, and note_per_octave is an offset.We are concerned with the extraction of C, D, E, F, G, A, and B in each audio group.
Code:
# Include "stdafx. H "</P> <p> # include <iostream> <br/> # include <sstream> <br/> # include <fstream> <br/> # include <string> <br/> # include <vector> <br/> # include <map> <br/> # include <ctime> <br/> # include <xutility> <br/> # include <algorithm> <br/> # include <windows. h> </P> <p> # include "Midi. H "<br/> # include" midioutdevice. H "<br/> # include" shortmsg. H "</P> <p> using namespace STD; <br/> using MIDI: cmidioutdevice; <Br/> using MIDI: cshortmsg; </P> <p> // some useful constants <br/> const unsigned char channel = 0; <br/> const unsigned char note_id = 64; <br/> const unsigned char velocity = 127; </P> <p> class musicplayer <br/> {<br/> Public: <br/> musicplayer (MIDI: cmidioutdevice * Device) <br/>: _ DEVICE <br/>{< br/> m_keymap [0] = C; // <br/> m_keymap [1] = D; // <br/> m_keymap [2] = E; // <br/> m_keymap [3] = f; // <br/> M_keymap [4] = g; // <br/> m_keymap [5] = A; // <br/> m_keymap [6] = B; // <br/>}</P> <p> ~ Musicplayer () <br/>{< br/> _ DEVICE = 0; <br/>}</P> <p> Enum note_information <br/> {<br/> channel = 0, <br/> note_id = 64, <br/> velocity = 127, <br/> note_per_octave = 12, // one syllable <br/> low_note = 36 <br/> }; </P> <p> Enum note_id {C, c_sharp, D, d_sharp, E, F, f_sharp, G, g_sharp, A, <br/> a_sharp, B }; </P> <p> void playlatterrhythm (const unsigned char & letter, float time) <br/>{< br/> unsigned char noteid = lett Ertonote (letter); </P> <p> onnoteon (noteid); <br/>{< br/> // wait a bit <br/> :: sleep (700 * time); <br/>}onnoteoff (noteid); <br/>}</P> <p> // Postfix :_, -<br/> void playnumberrhythm (INT number, unsigned char Postfix, float time) <br/>{< br/> unsigned char noteid = numbertonote (number, postfix ); </P> <p> onnoteon (noteid); <br/>{< br/> // wait a bit <br/> //:: sleep (700 * time); <br/> clock_t current = clock (); </P> <P> while (clock ()-current <700 * Time) <br/>; </P> <p>} onnoteoff (noteid ); <br/>}</P> <p> protected: </P> <p> // note-on Event Notification <br/> bool onnoteon (unsigned char noteid) <br/>{< br/> MIDI: cshortmsg shortmsg (MIDI: note_on, channel, noteid, velocity, 0); <br/> shortmsg. sendmsg (* _ device); </P> <p> return true; <br/>}</P> <p> // note-Off Event Notification <br/> bool onnoteoff (unsigned char noteid) <br/> {< Br/> MIDI: cshortmsg shortmsg (MIDI: note_off, channel, noteid, velocity, 0); <br/> shortmsg. sendmsg (* _ device); </P> <p> return true; <br/>}</P> <p> //////////////////////////// /// // <br/> // low section <br/> // 1_2_3_4_5_6_7 _ <br/> // abcdefg </P> <p> // middle section <br/> // 1-2-3-4-5-6-7-<br/> // hijklmn </P> <p> // High Section <br/> // 1'2' 3' 4'5' 6'7' <br/> // opqrstu <br/> // <Br/> unsigned char lettertonote (unsigned char letter) <br/> {<br/> bool result; <br/> result = <br/> (letter> = 'A' & letter <= 'Z ') | <br/> (letter> = 'A' & letter <= 'Z'); </P> <p> If (! Result) <br/> return result; </P> <p> int octave (0); <br/> int idx (-1 ); </P> <p> If (letter> = 97) <br/> {<br/> Ave ave = (letter-'A')/7; <br/> idx = (letter-'A') % 7; <br/>}< br/> else <br/> {<br/> Ave ave = (letter-'A')/7; <br/> idx = (letter-'A') % 7; <br/>}</P> <p> int noteid (-1 ); </P> <p> noteid = m_keymap [idx]; <br/> noteid + = (Ave ave + 1) * note_per_octave + low_note; </P> <p> return noteid; <br/>}</P> <p> // postf IX: '_ ''-''' <br/> // lowmiddle high </P> <p> // Number: 1-7 <br/> unsigned char numbertonote (INT number, unsigned char postfix) <br/>{< br/> int octave (-1 ); <br/> int noteid (-1); </P> <p> If ('_' = postfix) <br/> octave = 0; <br/> else if ('-' = postfix) <br/> Ave ave = 1; <br/> else if (''' = postfix) <br/> octave = 2; </P> <p> noteid = m_keymap [number-1]; <br/> noteid + = (octave + 1) * note_per_octave + low_note; </P> <p> retu Rn noteid; <br/>}</P> <p> PRIVATE: <br/> MIDI: cmidioutdevice * _ device; <br/> intm_keymap [7]; <br/>}; </P> <p> int main (void) <br/>{< br/> try <br/> {<br/> // make sure there is an output device present <br/> If (cmidioutdevice :: getnumdevs ()> 0) <br/>{< br/> cmidioutdevice outdevice; </P> <p> // use the first device <br/> outdevice. open (0); </P> <p> musicplayer player (& outdevice); </P> <p> // ifstream infile ("BJ welcom U-letter.txt "); <br/> // vector <string> musiclist; <br/> // copy (istream_iterator <string> (infile), istream_iterator <string> (), back_inserter (musiclist); <br/> // copy (musiclist. begin (), musiclist. end (), ostream_iterator <string> (cout, "/N"); <br/> // For (size_t I (0 ); I <musiclist. size (); I ++) <br/> // {<br/> // STD: istringstream ISS (musiclist [I]); <br/> // unsigned char letter; <br/> // unsigned char U; <Br/> // float value; <br/>/ISS> letter> U> value; <br/> // STD :: cout <letter <"/t" <value <STD: Endl; <br/> // player. playlatterrhythm (letter, value); <br/>/}</P> <p> // ifstream infile ("BJ welcom U-number.txt "); <br/> ifstream infile ("Tian Kong Zhi cheng.txt"); </P> <p> vector <string> musiclist; <br/> copy (istream_iterator <string> (infile), istream_iterator <string> (), back_inserter (musiclist )); <Br/> copy (musiclist. begin (), musiclist. end (), ostream_iterator <string> (cout, "/N"); </P> <p> for (size_t I (0); I <musiclist. size (); I ++) <br/>{< br/> If ('#' = musiclist [I] [0]) <br/> continue; </P> <p> STD: istringstream ISS (musiclist [I]); <br/> int number; <br/> unsigned char Postfix; <br/> float value; <br/> ISS> number> Postfix> value; <br/> STD :: cout <number <"/t" <value <STD: Endl; <br/> play Er. playnumberrhythm (number, Postfix, value); <br/>}</P> <p> // close device <br/> outdevice. close (); <br/>}< br/> else <br/>{< br/> STD: cout <"No MIDI output devices present! /N "; <br/>}< br/> catch (const STD: exception & ERR) <br/>{< br/> STD :: cout <err. what (); <br/>}</P> <p> system ("pause"); </P> <p> return 0; <br/>}< br/>
To run the code, download cmidiwrapper:
This library uses the cwinthread under MFC, so you need to add the following in stdafx:
# DEFINE _ afxdll
# Include <afxwin. h>
In addition, the project is set to use a multi-byte character set. In C ++ code generation, the Runtime Library is multi-threaded dll/MD, and the input library winmm. Lib is added.
Program description
The playlatterrhythm function can play letters and notes. Float indicates the pause time,
Playnumberrhythm plays a digital note, with a suffix indicating the pitch, medium, and low. Float indicates the pause time.
Finally, based on the letter and syllable in Flash, I made my piano profile,
Letter ProfileFormat:Letter, playtime
Digital ProfileIn the following format:
Number_playtimeNumber-PlaytimeNumber 'playtime
BJ welcom U-letter.txt content, just Beijing Huan drink your first sentence:
J, 0.5l, 0.5j, 0.5i, 0.5j, 0.5i, 0.5j, 1j, 0.75i, 0.25f, 0.5 h, 0.5j, 0.5i, 1.5 <br/>
BJ welcom U-number.txt content, Beijing Huan drink your whole profile, digital version:
# Sentence1 <br/> latency 2-1.5 <br/> # sentence2 <br/> latency <br/> # sentene3 <br/> latency <br/> # sentence4 <br /> 2-0.53-0.52-0.51-0.55-0.756-0.253-16_0.53-0.52-0.52-0.51-1.5 <br/> # sentence5 <br/> 3-0.55-0.51 '0. 55-0.56-1.55-0.56-0.55-0.53-0.53-0.55-0.55-1.5 <br/> # sentence6 <br/> 3-0.55-0.56-0.51 '0. 52 '0. 51 '0. 55-0.53-0.52-0.55-1.53-2
When you run the program, the system automatically plays the created profile ~O (∩) O Haha ~