1

Тема: Ноти та C++

Необхідна ваша допомога, потрібно реалізувати програму, яка б програвала ноти за допомогою MIDI.
Наприклад є стрічка з нотами: 8g1 4c2 8.g1 16a1 4b1 8e1 8e1 4a1 8.g1 16f1 4g1 8c1 8c1 4d1 8d1 8e1 4f1 чи щось, подібне, ми її зчитуєм (всерівно звідки, чи файлу, чи форми, чи з самого коду програми), а далі через міді вони програються)
Дякую.

2

Re: Ноти та C++

Тобто ви хочете щоб ми написали за вас програму?

3

Re: Ноти та C++

ні, я лише прошу допомогти мені з реалізацією саме програвання нот і тільки.

4

Re: Ноти та C++

- потрібно реалізувати програму, яка б програвала ноти
- Тобто ви хочете щоб ми написали за вас програму?
- прошу допомогти мені з реалізацією саме програвання нот і тільки.

Або я півсонний, або тема - лауреат на переміщення до Залу Слави. :D

5

Re: Ноти та C++

Як варіант згодуйте АПІ функції PlaySound готовий міді файл

Подякували: Equa2

6 Востаннє редагувалося Equa (10.05.2013 00:59:51)

Re: Ноти та C++

Очі.завидющі, в тому то й справа, що варіант не зовсім підходить)



//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <tchar.h>
#include <windows.h>
#include <iostream.h>
#include <mmsystem.h>
//---------------------------------------------------------------------------

#pragma argsused
int _tmain(int argc, _TCHAR* argv[])
{
    HMIDIOUT handle;
    unsigned int DEFAULT_DEVICE = 0;         // Default MIDI Device
    DWORD NoteC = 0x00403c90;
    DWORD NoteE = 0x00404090;
    DWORD NoteG = 0x00404390;

    if(!midiOutOpen(&handle, DEFAULT_DEVICE, 0,0, CALLBACK_NULL))
    {
    midiOutShortMsg(handle, NoteC);
    Sleep(250);

    midiOutShortMsg(handle, NoteE);
    Sleep(250);

    midiOutShortMsg(handle, NoteG);
    Sleep(1500);

    }
    else
    cout << "Error Opening Default MIDI Device" << endl;

return 0;
}
//---------------------------------------------------------------------------

ось дещо найшов, під білдер переробив, працює) залишилось, зробити так, щоб звучало більше ніж три рази і все те що задам, якось через потік?. Ну а форму прикрутити, то вже не складає проблем)

7

Re: Ноти та C++

Зчитайте рядок, розпарсіть у масив елементів Нота і Пауза (або як зручніше) і в циклі по масиву юзаєте midiOutShortMsg().

З.І: та, і вибачаюся - тема таки не з "халявопитних". Тож то я півсонний був.

8 Востаннє редагувалося Chemist-i (10.05.2013 01:46:43)

Re: Ноти та C++

Equa
Доберіть нот (до семи хочаб) це молодші чотири байти у костантах (мсдн)
а у вхідному потоці можна розбити рядок на символи, та порівнювати хочаб switch-ем, замість noteC, noteG, я б написав просто С, G, ..., etc

Подякували: Equa1

9 Востаннє редагувалося Очі.завидющі (10.05.2013 21:32:19)

Re: Ноти та C++

@Equa
Вірним шляхом, йдете, камраде. Я раджу подивитись ще на страшне породження Chiptune (чиптюну) - Music Macro Language, який так люблять японці. І помолившись на зорі каменюкам, додайте його до своєї програми. Я впевнений, що бібліотеки існують для будь-якої мови програмування.

Подякували: Equa1

10 Востаннє редагувалося Equa (10.05.2013 02:45:25)

Re: Ноти та C++

Дуже вдячний за корисні відповіді)
Bartash, Так швидше за все і зроблю, щось не маю бажання придумувати "ровер")
Та й справа тут на більш-менш курсову)

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <tchar.h>
#include <windows.h>
#include <iostream.h>
#include <mmsystem.h>
//---------------------------------------------------------------------------

#pragma argsused
int _tmain(int argc, _TCHAR* argv[])
{
    HMIDIOUT handle;
    unsigned int DEFAULT_DEVICE = 0;         // Default MIDI Device
    DWORD Note1;
    unsigned int i = 0;
    unsigned int a[]={
            0x007f3c90,
            0x60003c90,
            0x007f3e90,
            0x60003e90,
            0x007f4090,
            0x60004090,
            0x007f4190,
            0x60004190,
            0x097f4390,
            0x60004590,
            0x007f4590,
            0x60004590,
            0x007f4790,
            0x60004790,
            0x007f4890,
            0x60004890,
            0};

    if(!midiOutOpen(&handle, DEFAULT_DEVICE, 0,0, CALLBACK_NULL))
    {

    while(a[i])
    {
     Note1=a[i];
     midiOutShortMsg(handle, Note1);
     Sleep(250);
     i++;
    }

    }
    else
    cout << "Error Opening Default MIDI Device" << endl;

return 0;
}
//---------------------------------------------------------------------------

На швидку руку, вийшло щось таке)
Ще підкажіть будь ласка, як інструмент з піаніно на щось інше змінити, пробував через midiOutCacheDrumPatches, це або не те, що треба, або в мене з ним щось "не клеїться")))

11

Re: Ноти та C++

Ця функція лише для зовнішніх пристроїв.

This function applies only to internal MIDI synthesizer devices.

Гляньте на midiOutGetDevCaps та  midiOutGetNumDevs. Тобто останньою функцією створюєте список інструментів й обираєте потрібний за допомогою midiOutGetDevCaps.

Подякували: Equa1

12 Востаннє редагувалося Chemist-i (10.05.2013 04:30:14)

Re: Ноти та C++

Equa
Ви ж використовуєте

    unsigned int DEFAULT_DEVICE = 0;         // Default MIDI Device

UPD:

Equa написав:

як інструмент з піаніно на щось інше змінити

додайте перед надсиланням месседжу з нотами цей код:

    int Instrument = 128 -1; //instrument from the list below
    int Volume = 10;        
    midiOutShortMsg(handle, (Volume << 16) | (Instrument << 8) | 0xC0);  // Set instrument
Instrument list

/* Instruments */

/*   1 "Acoustic Grand Piano",     */
/*   2 "Bright Acoustic Piano",    */
/*   3 "Electric Grand Piano",     */
/*   4 "Honky-tonk Piano",         */
/*   5 "Electric Piano 1",         */
/*   6 "Electric Piano 2",         */
/*   7 "Harpsichord",              */
/*   8 "Clavi",                    */
/*   9 "Celesta",                  */
/*  10 "Glockenspiel",             */
/*  11 "Music Box",                */
/*  12 "Vibraphone",               */
/*  13 "Marimba",                  */
/*  14 "Xylophone",                */
/*  15 "Tubular Bells",            */
/*  16 "Dulcimer",                 */
/*  17 "Drawbar Organ",            */
/*  18 "Percussive Organ",         */
/*  19 "Rock Organ",               */
/*  20 "Church Organ",             */
/*  21 "Reed Organ",               */
/*  22 "Accordion",                */
/*  23 "Harmonica",                */
/*  24 "Tango Accordion",          */
/*  25 "Acoustic Guitar (nylon)",  */
/*  26 "Acoustic Guitar (steel)",  */
/*  27 "Electric Guitar (jazz)",   */
/*  28 "Electric Guitar (clean)",  */
/*  29 "Electric Guitar (muted)",  */
/*  30 "Overdriven Guitar",        */
/*  31 "Distortion Guitar",        */
/*  32 "Guitar harmonics",         */
/*  33 "Acoustic Bass",            */
/*  34 "Electric Bass (finger)",   */
/*  35 "Electric Bass (pick)",     */
/*  36 "Fretless Bass",            */
/*  37 "Slap Bass 1",              */
/*  38 "Slap Bass 2",              */
/*  39 "Synth Bass 1",             */
/*  40 "Synth Bass 2",             */
/*  41 "Violin",                   */
/*  42 "Viola",                    */
/*  43 "Cello",                    */
/*  44 "Contrabass",               */
/*  45 "Tremolo Strings",          */
/*  46 "Pizzicato Strings",        */
/*  47 "Orchestral Harp",          */
/*  48 "Timpani",                  */
/*  49 "String Ensemble 1",        */
/*  50 "String Ensemble 2",        */
/*  51 "SynthStrings 1",           */
/*  52 "SynthStrings 2",           */
/*  53 "Choir Aahs",               */
/*  54 "Voice Oohs",               */
/*  55 "Synth Voice",              */
/*  56 "Orchestra Hit",            */
/*  57 "Trumpet",                  */
/*  58 "Trombone",                 */
/*  59 "Tuba",                     */
/*  60 "Muted Trumpet",            */
/*  61 "French Horn",              */
/*  62 "Brass Section",            */
/*  63 "SynthBrass 1",             */
/*  64 "SynthBrass 2",             */
/*  65 "Soprano Sax",              */
/*  66 "Alto Sax",                 */
/*  67 "Tenor Sax",                */
/*  68 "Baritone Sax",             */
/*  69 "Oboe",                     */
/*  70 "English Horn",             */
/*  71 "Bassoon",                  */
/*  72 "Clarinet",                 */
/*  73 "Piccolo",                  */
/*  74 "Flute",                    */
/*  75 "Recorder",                 */
/*  76 "Pan Flute",                */
/*  77 "Blown Bottle",             */
/*  78 "Shakuhachi",               */
/*  79 "Whistle",                  */
/*  80 "Ocarina",                  */
/*  81 "Lead 1 (square)",          */
/*  82 "Lead 2 (sawtooth)",        */
/*  83 "Lead 3 (calliope)",        */
/*  84 "Lead 4 (chiff)",           */
/*  85 "Lead 5 (charang)",         */
/*  86 "Lead 6 (voice)",           */
/*  87 "Lead 7 (fifths)",          */
/*  88 "Lead 8 (bass + lead)",     */
/*  89 "Pad 1 (new age)",          */
/*  90 "Pad 2 (warm)",             */
/*  91 "Pad 3 (polysynth)",        */
/*  92 "Pad 4 (choir)",            */
/*  93 "Pad 5 (bowed)",            */
/*  94 "Pad 6 (metallic)",         */
/*  95 "Pad 7 (halo)",             */
/*  96 "Pad 8 (sweep)",            */
/*  97 "FX 1 (rain)",              */
/*  98 "FX 2 (soundtrack)",        */
/*  99 "FX 3 (crystal)",           */
/* 100 "FX 4 (atmosphere)",        */
/* 101 "FX 5 (brightness)",        */
/* 102 "FX 6 (goblins)",           */
/* 103 "FX 7 (echoes)",            */
/* 104 "FX 8 (sci-fi)",            */
/* 105 "Sitar",                    */
/* 106 "Banjo",                    */
/* 107 "Shamisen",                 */
/* 108 "Koto",                     */
/* 109 "Kalimba",                  */
/* 110 "Bag pipe",                 */
/* 111 "Fiddle",                   */
/* 112 "Shanai",                   */
/* 113 "Tinkle Bell",              */
/* 114 "Agogo",                    */
/* 115 "Steel Drums",              */
/* 116 "Woodblock",                */
/* 117 "Taiko Drum",               */
/* 118 "Melodic Tom",              */
/* 119 "Synth Drum",               */
/* 120 "Reverse Cymbal",           */
/* 121 "Guitar Fret Noise",        */
/* 122 "Breath Noise",             */
/* 123 "Seashore",                 */
/* 124 "Bird Tweet",               */
/* 125 "Telephone Ring",           */
/* 126 "Helicopter",               */
/* 127 "Applause",                 */
/* 128 "Gunshot";                 */

UPD_2: До речі, якщо Вам цікаво, то за допомогою цієї таблиці можна отримати повний контроль над міді пристроєм

Подякували: Очі.завидющі, Equa3

13

Re: Ноти та C++

Equa написав:

Ще підкажіть будь ласка, як інструмент з піаніно на щось інше змінити, пробував через midiOutCacheDrumPatches, це або не те, що треба, або в мене з ним щось "не клеїться")))

А ще раз можна, будь-ласка? Не зрозумів формулювання цілі. :)

14

Re: Ноти та C++

Стандартний інструмент - піаніно, а Equa треба інший - саксофон, наприклад. Що тут неясно?

Подякували: Equa2

15

Re: Ноти та C++

Очі.завидющі написав:

Стандартний інструмент - піаніно, а Equa треба інший - саксофон, наприклад. Що тут неясно?

Та вже прокурив. Попередній пост Chemist-i серед ночі не вгледів. :)

16

Re: Ноти та C++

Шановний Bartash, щож Ви не спите ночами?

17

Re: Ноти та C++

Chemist-i написав:

Шановний Bartash, щож Ви не спите ночами?

А що ж іще робити вночі? :D

http://dev.by/ckeditor_assets/pictures/394/content_night-prg-01.jpg

18 Востаннє редагувалося Equa (10.05.2013 15:57:31)

Re: Ноти та C++

Перегнав на форму, добавив зміну інструментів через вибір в комбобокс, зміну довжини ноти.

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit2.h"
#include <windows.h>
#include <iostream.h>
#include <mmsystem.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2 *Form2;
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------



HMIDIOUT handle; //ініціалізуємо midi
void __fastcall TForm2::Button1Click(TObject *Sender)
{

    unsigned int DEFAULT_DEVICE = 0;         // MIDI пристрій по-замовчуванню
    DWORD Note1; //наша нота
    int Instrument; //ініціалізуємо змінну інструментів

    //Вибираєм інструмент
    switch(ComboBox1->ItemIndex)
        {
         case 0 :
         Instrument = 1;
         break;
         case 1 :
         Instrument = 28;
         break;
         case 2:
         Instrument = 118;
         break;
         case 3:
         Instrument = 66;
         break;
        }

    int Volume = 10;
    unsigned int i = 0;
    unsigned int a[]={
            0x60003e90,
            0x60003c90,
            0x007f3e90,
            0x497f5390,
            0x60004590,
            0x007f4590,
            0x60004590,
            0x007f4790,
            0x60004790,
            0x007f4890,
            0x60004890,
            0x60004190,
            0x097f4390,
            0x60004590,
            0x007f4590,
            0x60004590,
            0x007f4790,
            0x60004790,
            0x007f4890,
            0x60004890,

            0};

    if(!midiOutOpen(&handle, DEFAULT_DEVICE, 0,0, CALLBACK_NULL))
    {
        midiOutShortMsg(handle, (Volume << 16) | (Instrument << 8) | 0xC0);  // Set instrument

        while(a[i])
        {
            Note1=a[i];
            midiOutShortMsg(handle, Note1);
            Sleep(StrToInt( Edit1->Text));
            i++;
        }

    }
    else
    Edit2->Text="Не ініціалізовано MIDI пристрій";

    midiOutClose(handle);
}
//---------------------------------------------------------------------------

Ще би тепер з нотами розібратись, в якому форматі їх вводити в поле мемо, і як адекватно перегнати в вигляд типу "0x60003e90", пробував підставляти ці самі числа в десятковому вигляді, теж працює

Post's attachments

midi.jpg 31.07 kb, 299 downloads since 2013-05-10 

Подякували: Очі.завидющі1

19 Востаннє редагувалося Chemist-i (11.05.2013 07:40:09)

Re: Ноти та C++

Equa
Я б Вам радив зробити простенький інтерпретатор, наприклад:

SetInst( Piano );
1e3 2d2 3e7 3g8;
end;

Де, SetInst - зрозуміло,
1e3 - нота Мі, третьої октави ціла,
2d2 - нота Ре, другої октави половинна,
3e7 - нота Мі, сьомої октави четвертна,
3g8 - нота Соль, восьмої октави четвертна;

Інтерпретується це досить просто у борляндії є AnsiCompareText та AnsiCompareStr (не пам_ятаю як з ними працювати) але суть ясна, розбиваєте весь рядок на "слова" (які одділяються одне від одного пробілами та службовими символами (всіякими "<>=-()@" і т.д.) у якийсь массивчик, після чого кожну ноту обробляєте (можна у циклі) спочатку довжина (встановлюється затримка), потім сама нота, і потім октава.
Розбор на Вашому прикладі (0x60003e90) - тут 3E h = 62 dec -> D4 (converter тут) - це нота Ре четвертої октави.

upd: якщо хочте виділити саму ноту у змінну - можна зробити так:

unsigned char Note = 0x3е;
unsigned int Note1 = 0x60003e90 | Note << 8;

і потім Note1 підставляєте у міді месседж


Корисні лінки:
Тривалість нот;
Самі ноти (обережно москалі)

Подякували: Equa, koala3

20

Re: Ноти та C++

Виправив повідомлення, трохи не правильно привів тлумачення ноти ( у 0x60003e90 )