Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 1 |

 

  Вопрос: Сохранить midi в файле Добавлено: 13.10.08 17:52  

Автор вопроса:  Андрей
Необходимо всунуть цикл в трек, чтобы изменяя данные создать и сохранить мелодию. Играет только написанное (в примере аккорд из 4 нот), но не более. Думаю, не могу правильно расчитать длину трека.


midi$ = "4D546864"                    'блок заголовка
midi$ = midi$ & "00000006"            'длина блока - 6 байт
midi$ = midi$ & "0000"                'формат файла - 0
midi$ = midi$ & "0001"                'номер трека
midi$ = midi$ & "0060"                '96 тиков в четверти
midi$ = midi$ & "4D54726B"            'блок трека
midi$ = midi$ & "0000003B"            'длина трека - 59 байт
midi$ = midi$ & "00FF580404021808"    'дельта-время 0, размер 4/4, один удар метронома на четверть, 8 тридцать вторых на 24 midi Clock
midi$ = midi$ & "00FF510309F38E"      'дельта-время 0, размер 4/4, темп - 652174 микросекунды на четверть
midi$ = midi$ & "00C000"              'канал 0, инструмент 00
midi$ = midi$ & "00C100"              'канал 1, инструмент 00
midi$ = midi$ & "00C200"              'канал 2, инструмент 00
midi$ = midi$ & "00923060"            'дельта-время 00 тиков, канал 2, играть ноту До малой октавы, громкость 60
midi$ = midi$ & "60914340"            'дельта-время 96 тиков, канал 1, играть ноту Соль первой октавы, громкость 40
midi$ = midi$ & "003C40"              'дельта-время 00 тиков, канал 1, играть ноту До первой октавы (Running Status), громкость 40
midi$ = midi$ & "60904C20"            'дельта-время 96 тиков, канал 0, играть ноту Ми второй октавы, громкость 20
midi$ = midi$ & "8140823060"          'дельта-время 192 тика, канал 2, снять ноту До малой октавы, громкость 60
midi$ = midi$ & "00814340"            'дельта-время 00 тиков, канал 1, снять ноту Соль первой октавы, громкость 40
midi$ = midi$ & "003C40"              'дельта-время 00 тиков, канал 1, снять ноту До первой октавы (Running Status), громкость 40
midi$ = midi$ & "00804C20"            'дельта-время 00 тиков, канал 0, снять ноту Ми второй октавы, громкость 20
midi$ = midi$ & "00FF2F00"            'конец трека


midi$ = Hex2Str(midi$)
Call SaveToFile(midi$, "C:\Windows\temp\file.mid")

Ответить

  Ответы Всего ответов: 4  

Номер ответа: 1
Автор ответа:
 Андрей



Вопросов: 8
Ответов: 42
 Профиль | | #1 Добавлено: 13.10.08 20:00
Сори, решил сам)


n = 2
midi$ = "4D546864"                    'блок заголовка
midi$ = midi$ & "00000006"            'длина блока - 6 байт
midi$ = midi$ & "0000"                'формат файла - 0
midi$ = midi$ & "0001"                'номер трека
midi$ = midi$ & "0060"                '96 тиков в четверти
midi$ = midi$ & "4D54726B"            'блок трека
midi$ = midi$ & "000000" & Hex(28 + 31 * n)            'длина трека - 59+31 байт
midi$ = midi$ & "00FF580404021808"    'дельта-время 0, размер 4/4, один удар метронома на четверть, 8 тридцать вторых на 24 midi Clock
midi$ = midi$ & "00FF510309F38E"      'дельта-время 0, размер 4/4, темп - 652174 микросекунды на четверть
midi$ = midi$ & "00C000"              'канал 0, инструмент 00
midi$ = midi$ & "00C100"              'канал 1, инструмент 00
midi$ = midi$ & "00C200"              'канал 2, инструмент 00
For i = 1 To n
midi$ = midi$ & "00923060"            'дельта-время 00 тиков, канал 2, играть ноту До малой октавы, громкость 60
midi$ = midi$ & "60914340"            'дельта-время 96 тиков, канал 1, играть ноту Соль первой октавы, громкость 40
midi$ = midi$ & "003C40"              'дельта-время 00 тиков, канал 1, играть ноту До первой октавы (Running Status), громкость 40
midi$ = midi$ & "60904C20"            'дельта-время 96 тиков, канал 0, играть ноту Ми второй октавы, громкость 20
midi$ = midi$ & "8140823060"          'дельта-время 192 тика, канал 2, снять ноту До малой октавы, громкость 60
midi$ = midi$ & "00814340"            'дельта-время 00 тиков, канал 1, снять ноту Соль первой октавы, громкость 40
midi$ = midi$ & "003C40"              'дельта-время 00 тиков, канал 1, снять ноту До первой октавы (Running Status), громкость 40
midi$ = midi$ & "00804C20"            'дельта-время 00 тиков, канал 0, снять ноту Ми второй октавы, громкость 20
Next i
midi$ = midi$ & "00FF2F00"            'конец трека


midi$ = Hex2Str(midi$)
Call SaveToFile(midi$, "C:\Windows\temp\file.mid";)

Ответить

Номер ответа: 2
Автор ответа:
 Андрей



Вопросов: 8
Ответов: 42
 Профиль | | #2 Добавлено: 14.10.08 20:07
Получился забавный код.
Прошу считать меня родоначальником музыкальных фракталов.))) Делюсь упрощенной версией.

Код в форму:

Private Sub Form_Load()
n = 21 'max число для данного примера

'играем замедляющуюся и затихающую синусоиду
Call MidiTrackOpen(0, n) 'инструмент (0-127), кол-во нот
For i = 1 To n
Call MidiTrack(Round(Abs(Sin(i)) * 70), 127 - i * 4, 16 + i) 'm - нота (36 = "До" первой октавы), громкость (16-127), темп (16-127)
Next i
Call MidiTrackClose

Call MidiFileSave 'сохраняем мелодию в файле mid
Call MidiFilePlay 'проигрываем мелодию
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Call MidiFileClose 'выгружаем и удаляем файл
End Sub


Код в модуль:

Option Explicit
Private Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As String, ByVal lpstrReturnString As String, ByVal uReturnLength As Long, ByVal hwndCallback As Long) As Long
Dim midi$
Dim i, n As Integer

'Начало трека
Sub MidiTrackOpen(Instrument, Num)
On Error Resume Next
If Instrument < 16 Then Instrument = 0 & Hex(Instrument)
If Instrument >= 16 Then Instrument = Hex(Instrument)
midi$ = ""
midi$ = "4D546864000000060000000100244D54726B000000"
midi$ = midi$ & Hex(22 + 8 * Num)
midi$ = midi$ & "00FF58040402180800FF510309F38E00C0"
midi$ = midi$ & Instrument
End Sub

'Тело трека
Sub MidiTrack(Nota, Volume, Temp)
midi$ = midi$ & "0090" & Hex(Nota + 12) & Hex(Volume)
midi$ = midi$ & Hex(Temp) & "80" & Hex(Nota + 12) & Hex(Volume)
End Sub

'Конец трека
Sub MidiTrackClose()
midi$ = midi$ & "00FF2F00"
End Sub

'Сохраняем файл
Sub MidiFileSave()
On Error Resume Next
Kill "C:\Windows\temp\file.mid"
midi$ = Hex2Str(midi$)
Call SaveToFile(midi$, "C:\Windows\temp\file.mid";)
End Sub

'Проигрываем файл
Sub MidiFilePlay()
On Error Resume Next
mciSendString "OPEN C:\Windows\temp\file.mid TYPE SEQUENCER ALIAS file", 0&, 0, 0
mciSendString "PLAY file FROM 0", 0&, 0, 0
mciSendString "CLOSE  ANIMATION", 0&, 0, 0
End Sub

'Выгружаем файл
Sub MidiFileClose()
On Error Resume Next
mciSendString& "STOP file", 0&, 0, 0
mciSendString& "CLOSE file", 0&, 0, 0
Kill "C:\Windows\temp\file.mid"
End Sub

'Функция сохранения переменной в файле
Sub SaveToFile(Data$, PathFile As String)
On Error Resume Next
n = FreeFile
Open PathFile For Binary As #n
Put n, , Data$
Close #n
Exit Sub
End Sub

'Функция декодирование переменной
Public Function Hex2Str(str$) As String
On Error Resume Next
Dim S$
For i = 1 To Len(str$) Step 2
S$ = Val("&H" & (Mid(str$, i, 2)))
Hex2Str = Hex2Str & Chr(S$)
Next i
End Function

Ответить

Номер ответа: 3
Автор ответа:
 Millenium



ICQ: 629966 

Вопросов: 118
Ответов: 903
 Web-сайт: www.aliyev.us
 Профиль | | #3
Добавлено: 14.10.08 23:21
Забавно!
А можеш дать справку по нотам?
Т.е. по биарному коду...

Ответить

Номер ответа: 4
Автор ответа:
 Андрей



Вопросов: 8
Ответов: 42
 Профиль | | #4 Добавлено: 15.10.08 08:53
Ой, действительно тупанул. Играет на октаву ниже. Нужно:

...
midi$ = midi$ & Hex(Temp) & "80" & Hex(Nota + 24) & Hex(Volume)
...


Номера midi-нот большой октавы (в примере это номера первой октавы):
36 - "До"
37 - "До-диез" или "Ре-бемоль"
38 - "Ре"
39 - "Ре-диез" или "Ми-бемоль"
40 - "Ми"
41 - "Фа"
42 - "Фа-диез" или "Соль-бемоль"
43 - "Соль"
44 - "Соль-диез" или "Ля-бемоль"
45 - "Ля"
46 - "Ля-диез" или "Си-бемоль"
47 - "Си"

Нота "Соль" малой октавы:
43 + 12 = 55
Нота "Соль" первой октавы:
55 + 12 = 67
В шестнацатиричной системе:
Hex(67) = 43

Бинарный код включения ноты:
00 91 43 60
где,
00 - дельта-время - разница между временем включения и началом такта;
91 - 9 - включение, 1 - канал;
43 - нота "Соль" первой октавы;
60 - громкость.

Бинарный код отключения ноты:
60 81 43 60
где,
60 - дельта-время - разница между временем отключения и действием в такте;
91 - 8 - отключение, 1 - канал;
43 - нота "Соль" первой октавы;
60 - громкость (можно просто 00).

Можно еще записать методом Running Status, но его понимают не все плейеры.

Для кучи, номера midi-инструментов:
0 Acoustic grand piano
1 Bright acoustic piano
2 Electric grand piano
3 Honky-tonk piano
4 Rhodes piano
5 Chorused piano
6 Harpsichord
7 Clavinet
8 Celesta
9 Glockenspiel
10 Music box
11 Vibraphone
12 Marimba
13 Xylophone
14 Tubular bells
15 Dulcimer
16 Hammond organ
17 Percussive organ
18 Rock organ
19 Church organ
20 Reed organ
21 Accordion
22 Harmonica
23 Tango accordion
24 Acoustic guitar (nylon)
25 Acoustic guitar (steel)
26 Electric guitar (jazz)
27 Electric guitar (clean)
28 Electric guitar (muted)
29 Overdriven guitar
30 Distortion guitar
31 Guitar harmonics
32 Acoustic bass
33 Electric bass (finger)
34 Electric bass (pick)
35 Fretless bass
36 Slap bass 1
37 Slap bass 2
38 Synth bass 1
39 Synth bass 2
40 Violin
41 Viola
42 Cello
43 Contrabass
44 Tremolo strings
45 Pizzicato strings
46 Orchestral harp
47 Timpani
48 String ensemble 1
49 String ensemble 2
50 Synth. strings 1
51 Synth. strings 2
52 Choir Aahs
53 Voice Oohs
54 Synth voice
55 Orchestra hit
56 Trumpet
57 Trombone
58 Tuba
59 Muted trumpet
60 French horn
61 Brass section
62 Synth. brass 1
63 Synth. brass 2
64 Soprano sax
65 Alto sax
66 Tenor sax
67 Baritone sax
68 Oboe
69 English horn
70 Bassoon
71 Clarinet
72 Piccolo
73 Flute
74 Recorder
75 Pan flute
76 Bottle blow
77 Shakuhachi
78 Whistle
79 Ocarina
80 Lead 1 (square)
81 Lead 2 (sawtooth)
82 Lead 3 (calliope lead)
83 Lead 4 (chiff lead)
84 Lead 5 (charang)
85 Lead 6 (voice)
86 Lead 7 (fifths)
87 Lead 8 (brass + lead)
88 Pad 1 (new age)
89 Pad 2 (warm)
90 Pad 3 (polysynth)
91 Pad 4 (choir)
92 Pad 5 (bowed)
93 Pad 6 (metallic)
94 Pad 7 (halo)
95 Pad 8 (sweep)
96 FX 1 (rain)
97 FX 2 (soundtrack)
98 FX 3 (crystal)
99 FX 4 (atmosphere)
100 FX 5 (brightness)
101 FX 6 (goblins)
102 FX 7 (echoes)
103 FX 8 (sci-fi)
104 Sitar
105 Banjo
106 Shamisen
107 Koto
108 Kalimba
109 Bagpipe
110 Fiddle
111 Shanai
112 Tinkle Bell
113 Agogo
114 Steel
115 Woodblock
116 Taiko Drum
117 Melodic Tom
118 Synth Drum
119 Reverse Cymbal
120 Guitar fret noise
121 Breath noise
122 Seashore
123 Bird tweet
124 Telephone ring
125 Helicopter
126 Applause
127 Gunshot

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам