21

Re: Ноти та C++

щось я застряв на конвертації нот, ніяк не виходить, надати вигляду "0x60003e90"

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

#include <vcl.h>
#pragma hdrstop

#include "Unit2.h"
#include <windows.h>
#include <iostream.h>
#include <mmsystem.h>
#include <string.h>
#include <sstream>
//---------------------------------------------------------------------------
#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 char* notem;
        unsigned int notemi[255];

    AnsiString mas[255];
    int k=0;
    for(int i=0;i<=Memo1->Lines->Count;i++)
        {
            char* end=0;
            notem=0;
            mas[i]=Memo1->Lines->Strings[i].c_str();
            notem=mas[i].c_str();

            notemi[i]=strtol(notem,&end,16);

            Memo2->Lines->Append(notemi[i]);
        }

    unsigned int DEFAULT_DEVICE = 0;         // MIDI пристрій по-замовчуванню
    DWORD Note1; //наша нота
    unsigned 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);
}
//---------------------------------------------------------------------------

що не так? можливо якось можна попростіше?

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

22

Re: Ноти та C++

unsigned char* notem;

Це вказівник, спробуйте без зірочки =)

23

Re: Ноти та C++

1. Сформулюйте детальніше, що саме ви хочете зробити - що у що конвертувати? 80%, що просто після того, як ви повністю сформулюєте, що хочете зробити, ви одразу і побачите, як це зробити. Ідею вам вже Chemist-i підкинув.
2. Візміть за правило називати змінні і (особливо) елементи інтерфейсу зрозумілими іменами. Наприклад, не Memo1, а memoReadableNotes чи meNotes, не Memo2, а meCodes. Купа головного болю зникне. Так, і оголошуйте змінні безпосередньо перед використанням.
3. За моїм досвідом - якщо ви використовуєте оператор switch-case, то або це не ООП, або ви займаєтеся системним програмуванням, або некоректно побудували об'єктну модель. Ну, принаймні в 90% випадків. У вашому випадку значно простіше буде зробити

const int Instruments[4]={1,28,118,66};
int Instrument=Instruments[ComboBox1->ItemIndex];

а правильніше - причепити на елементи списку об'єкти з потрібними значеннями і прямо витягати їх.

Подякували: Chemist-i, Equa2

24

Re: Ноти та C++

1. потрібно, з поля мемо витягнути ноту вигляду типу (1e3) і сконвертувати її у вигляд (0x007f4590)це для прикладу, щоб потім закинути їх у такому вигляді у масив, з якого будуть зчитуватись і програватись.
2. дещо маю мало практики, тому не привик, але буду намагатись.
3. що на думку спало, те й використав) основну функцію виконує)

25

Re: Ноти та C++

Chemist-i написав:
unsigned char* notem;

Це вказівник, спробуйте без зірочки =)

без зірочки - помилки при конвертації

26 Востаннє редагувалося koala (11.05.2013 11:40:58)

Re: Ноти та C++

Таблицю вам вже наводили. Якщо формат (довжина)(нота)(октава), і все по одному символу, то буде щось на кшталт

char onenote[4] = "1E3";//в прикладі розбирається тільки одна нота
int length = onenote[0] - '0',
    note   = onenote[1] - 'A',
    octava = onenote[2] - '0',
    volume = 0x7f;//гучність
int shifts[7]={ 9, 11, 0, 2, 4, 5, 7 };//"білі клавіші" в хроматичній октаві, з урахуванням того, що C - до.
int notecode= 12 //С0 - це нота до нульової октави
               + octava * 12 //12 нот у хроматичній октаві
               + shifts[note];//зсув клавіші від початку октави
midiOutShortMsg( handle, ( volume << 16 ) | ( notecode << 8  ) | ( 0x90 ) );//збираємо ноту докупи
Sleep( 1000 / length );//довжина
midiOutShortMsg( handle, ( volume << 16 ) | ( notecode << 8  ) | ( 0x80 ) );//вимикаємо звук

Дякую Chemist-i за виправлення

P.S. Але все це за умови, що позначки по 1 символу. Для дієзів і бемолів доведеться переписувати. Ну і взагалі це бажано в окрему функцію винести.

Подякували: Equa, Chemist-i2

27

Re: Ноти та C++

дякую, зараз спробую

28 Востаннє редагувалося Chemist-i (11.05.2013 11:37:37)

Re: Ноти та C++

koala
У шортМессадж - хендли,
сліп з Великої
і ще у затримці залежність не прямопропорційна, а зворотньо..., і 1 - то має бути одна секунда, 2 - 0.5 секунди і т.д.:

Sleep( 1000 / length );
Подякували: koala1

29

Re: Ноти та C++

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

#include <vcl.h>
#pragma hdrstop

#include "Unit2.h"
#include <windows.h>
#include <iostream.h>
#include <mmsystem.h>
#include <string.h>
#include <sstream>
//---------------------------------------------------------------------------
#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; //наша нота
    unsigned int Instrument; //ініціалізуємо змінну інструментів
    int k=0;


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

   int shifts[7]={ 9, 11, 0, 2, 4, 5, 7 };//"білі клавіші" в хроматичній октаві, з урахуванням того, що C - до.
   int notecode= 12; //С0 - це нота до нульової октави


    int Volume = 0x7f;
    int notu[1000];
    unsigned int gotoviNotu[1000];
    char* onenote;
    AnsiString note4;

    note4=Memo1->Text;     //зчитуємо з memo в ansistring
    onenote=note4.c_str();  //переписуємо в char
     int zminna=0;
    for(int i=0;i<=strlen(note4.c_str());i+=3)
    {
    notu[i]=onenote[i];   //довжина
    notu[i+1]=onenote[i+1];        //нота
    notu[i+2]=onenote[i+2];              //октава
     zminna=notu[i+1];
    gotoviNotu[k]=12+(notu[i+2]*12)+shifts[zminna];

      k++;
    }







    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) | 0x90);  // Set instrument

        while(gotoviNotu[i])
        {
        Memo2->Lines->Append(gotoviNotu[i]);
            Note1=gotoviNotu[i];
            midiOutShortMsg(handle, Note1);
            Sleep(StrToInt( Edit1->Text));
            i++;

        }

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

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

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

Post's attachments

22.png 62.93 kb, 224 downloads since 2013-05-11 

30

Re: Ноти та C++

106. midiOutShortMsg(handle, (Volume << 16) | (Instrument << 8) | 0x90);  // Set instrument

Це не set instrument, а note on (останній байт 0xC0)

я не впевнений, бо дуже швидко переглянув, але може у 111-113 рядки слід замінити на:

midiOutShortMsg(handle, ( volume << 16 ) | ( Note1 << 8  ) | ( 0x90 ) );//вмикаємо звук
Sleep( 1000 / length );//довжина
midiOutShortMsg(handle,  ( volume << 16 ) | ( Note1 << 8  ) | ( 0x80 ) );//вимикаємо звук
Подякували: Equa, koala2

31

Re: Ноти та C++

Спробував замінити, тепер грає нот з 5)