Сейчас на форуме: (+5 невидимых) |
![]() |
eXeL@B —› Программирование —› Как проиграть midi из ресурса |
Посл.ответ | Сообщение |
|
Создано: 09 июля 2007 11:25 · Личное сообщение · #1 Уважаемые посетители форума! Я давно уже хотел узнать, как проиграть midi-файл из ресурса. Естественно, напрямую, без всяких трюков с сохранением на диск, воспроизведением через mciSendCommand и последующим стиранием. Недавно нашёл кое-какую информацию по этой теме, попробовал реализовать (на Delphi), но постоянно происходит одна и та же ошибка. Может кто-нибудь знает, как пользоваться этими API и посмотрит, в чём дело: uses MMSYSTEM; ... var hRes : DWORD; // Это для pRes : Pointer; // ресурсов midi : HMIDI; //Handle потока воспроизведения header : MIDIHDR; //Заголовок с информацией для потока pDev : integer; //Номер устройства воспроизведения err : DWORD; //Код ошибки begin //Файл 1.mid полностью загнан в ресурс '1' типа 'MIDI' //Все функции, кроме последней (midiStreamOut), //выполняются без ошибок //Загружаем ресурс hRes:=FindResource(hInstance,PChar(1),PChar('MIDI')); hRes:=LoadResource(hInstance,hRes); pRes:=LockResource(hRes); //Инициализация параметров pDev:=MIDI_MAPPER; midi:=0; FillChar(header,SizeOf(header),0); //Создание потока и подготовка заголовка midiStreamOpen(@midi,@pDev,1,0,0,0); header.lpData:=pRes; header.dwBufferLength:=4373; header.dwFlags:=0; midiOutPrepareHeader(midi,@header,SizeOf(header)); //Попытка проиграть... err:=midiStreamOut(midi,@header,SizeOf(header)); showmessage(inttostr(err)) //err=11 (equ 'Неверные параметры'), а должен быть 0 end; ![]() |
|
Создано: 09 июля 2007 14:55 · Личное сообщение · #2 |
|
Создано: 09 июля 2007 16:28 · Личное сообщение · #3 |
|
Создано: 09 июля 2007 18:10 · Личное сообщение · #4 у меня ошибка уже не та же. была 11 как у тебя, а стала 64. просто не учел особенностей твоего кода =)
и теперь еще midiOutPrepareHeader возвращает 11. =((( не знаю, шаг назад я сделал или вперед :/ ![]() |
|
Создано: 09 июля 2007 18:18 · Личное сообщение · #5 дебажил winmm.dll внутри midiOutPrepareHeader и нашёл следующее:
0x0B - код ошибки MMSYSERR_INVALPARAM. [ESI+4] - это значение поля dwBufferLength. у меня midi-файл на 100 кб, точный размер - 0x18C3F, а это больше, чем 0x10000. с таким длинным буфером не работает =(( и что же делать? ![]() |
|
Создано: 09 июля 2007 18:36 · Личное сообщение · #6 И еще я решил, что нельзя передавать содержимое .mid-файла в качестве stream. stream это нечто другое. вот к примеру, я добился:
играет одну ноту =))) ![]() |
|
Создано: 09 июля 2007 18:41 · Личное сообщение · #7 |
|
Создано: 10 июля 2007 10:52 · Личное сообщение · #8 Большое спасибо за информацию! Из неё можно сделать вывод, что midiStreamOpen - это действительно нечто другое. Дело в том, что недавно на каком-то форуме, где обсуждалась подобная проблема, кто-то написал, что долго мучился и справился в конце концов с помощью функций midiStreamOpen, midiStreamOut и т д. И вот нет чтобы написать кусок кода, так ведь нет же, просто написал названия функций и ушёл. Возможно, что ничего у него не получилось, а он просто увидел "умные" названия API и написал. Не исключено также, что он был совсем уж маньяк =) и "на лету" перебивал midi-файл в правильную для Stream'а структуру. Так что тут многое непонятно. PS. А буфер не должен превышать 64 кб, это в справке по функции сказано. PPS.А ещё есть функции midiOutOpen, midiOutClose, midiOutShortMsg, midiOutLongMsg и др. (вообще много информации по всем этим функциям на promidi.by.ru/) ![]() |
|
Создано: 10 июля 2007 13:18 · Личное сообщение · #9 |
|
Создано: 10 июля 2007 15:13 · Личное сообщение · #10 sotona пишет: И еще я решил, что нельзя передавать содержимое .mid-файла в качестве stream. stream это нечто другое. вот к примеру, я добился: Вы имеете ввиду стрим == midiStreamOpen(@midi,@pDev,1,0,0,0); А ежели как в вашем примере с набором байт, но подгрузить миди-файл в TStream (TMemoryStream) ? ----- Я медленно снимаю с неё UPX... *FF_User* ![]() |
|
Создано: 10 июля 2007 16:35 · Личное сообщение · #11 |
|
Создано: 10 июля 2007 18:04 · Поправил: AlexZ · Личное сообщение · #12 Да-да... сейчас поигрался с TStream и выяснил, что придется разбирать на дорожки. Ранее вопрос воспроизведения мидях из памяти уже неоднократно поднимался, и скажу, что было решено играть его из файла с диска. Хотя, если память не подводит, товарисчь Asterix что-то эксперементировал с API PlaySound и флагом "из_памяти", но кажись, тоже окончилось неудачей. P.s. Есть тулзень GuitarPro для сочинения мидях, может её стОит реверснуть... ----- Я медленно снимаю с неё UPX... *FF_User* ![]() |
|
Создано: 10 июля 2007 19:06 · Личное сообщение · #13 Да, эта проблема для меня тоже очень важна. В аттаче есть мой давний пример на фасме как играть миди-поток. Там используется два инструмента (Kick и еще что-то), миди-буфер построен вручную(чем то сродни писать музыку в MadTracker ![]() Как выход из ситуации могу предложить написать тулзу которая будет "обычный" мидик переводить в такой вот миди-поток без заголовков и его уже и играть... Скорее всего миди-плееры считывают из файла все дорожки, потом "склеивают" их в один поток, бьют на блоки по 64К и играют уже данными API. P.S.: мб я и неправ насчет всего этого ![]() ![]() |
|
Создано: 10 июля 2007 19:07 · Личное сообщение · #14 |
![]() |
eXeL@B —› Программирование —› Как проиграть midi из ресурса |