2015-01-28 4 views
0

Я только что начал изучать C++, и я пытаюсь понять, как играть в midi-файл и делать его бесконечным. (EDIT: в фоновом режиме, пока остальная часть кода работает). Я нашел решение, но я не понимаю, как его использовать. Я даже не знаю, как исследовать, чтобы понять, как его использовать. Чем больше я пытаюсь исследовать, тем больше теряюсь.Loop midi in C++, 'pass window handle'?

Я спрашиваю, по крайней мере, кто-то объясняет, какие темы мне нужны для исследования, чтобы понять, как реализовать предоставленное решение.

Вот что я был в состоянии собрать:

mciSendString("open Latin.mid", NULL, 0, NULL); 
mciSendString("play Latin.mid", NULL, 0, NULL); 

Конечно, это только играет песню один раз.

Вот решение - ответ на вопрос, так же, как мой с марта 2014 года:

case WM_CREATE: 
mciSendString("open pickin0.mid type sequencer alias music", NULL, 0, NULL); 
mciSendString("play music notify", NULL, 0, hWnd); 
break; 

case MM_MCINOTIFY: 
mciSendString("seek music to start", NULL, 0, NULL); 
mciSendString("play music notify", NULL, 0, hWnd); 
break; 

Вы должны передать свой дескриптор окна, когда вы используете команду извещать поэтому он может послать команду MM_MCINOTIFY где-то.

... Так что мне нужно научиться сначала создавать классы, а затем, как сделать класс Windows, правильно? Я иду в правильном направлении? Я, наверное, откусываю больше, чем я могу пережевывать как полный новичок, поэтому любое направление, которое вы можете предложить, было бы здорово! Спасибо заранее.

EDIT: Вот пример того, что я хочу, просто с другим типом файла (PlaySound не любит .midi'S)

PlaySound("Panama.wav", NULL, SND_LOOP | SND_ASYNC); 
+0

Вы понимаете, как писать циклы? Если да, не можете ли вы просто поместить свои первые две строки кода внутри цикла, который будет выполняться бесконечно? –

+0

Я знаю, как писать для и в то время как петли, но не будет ли программа просто застревать в цикле и не двигаться дальше, чтобы завершить остальную часть кода? – ABradford

+0

Хм, похоже, вы не написали полное описание того, что хотите, потому что то, что вы на самом деле писали, было то, что вы хотели, чтобы песня «играла бесконечно», и цикл сделает это. Если ваш код должен зацикливаться на воспроизведении песни ... до тех пор, пока не будет выполнено какое-то условие ... ну а) вы должны были сказать нам это, и б) вы можете сделать это и в циклах. –

ответ

0

пример, что вы нашли это хорошо, и это отличный способ сделать это. Однако, чтобы понять это, вам нужно знать, как работает Win32 api (в основном MS Window API) для создания окон и передачи их цикла сообщений.

Это совершенно другой предмет изучения, не связанный с воспроизведением файлов midi. Если вы хотите пойти таким образом, я бы предложил начать с получения большего количества знаний в C++, причем C-часть этого была достаточно. И тогда вы можете найти книгу или книгу об win32 api, но для начала это очень много для переваривания.

Как вы нашли работу, так это то, что при «уведомлении о воспроизведении музыки» она сообщает mciSendString для отправки оконного сообщения в окно с дескриптором, указанным параметром hWnd.

Затем в вашем примере мы видим два оператора case, которые относятся к функции обратного вызова окна, которые пересылают отправленное сообщение и принимают какое-то действие в зависимости от него. WM_CREATE - макрос C, соответствующий идентификатору, соответствующему коду для сообщения CREATE, которое отправляется в окно во время его создания. Затем макросом MM_MCINOTIFY является сообщение, отправленное в окно, когда будет воспроизводиться файл midi, поэтому мы просто перезапускаем файл midi и настраиваем сообщение для повторного отправки в следующий раз после его воспроизведения.

Быстрая и ленивая решение повторить свой файл миди до того, чтобы узнать все это, было бы:

while(true) //loop forever 
{ 
    //Call MCI functions to play the midi file 
    mciSendString("open Latin.mid", NULL, 0, NULL); 
    mciSendString("play Latin.mid", NULL, 0, NULL); 

    //Call the Sleep win32 api function, to have your process wait for the specified time in milliseconds. 
    //For example Sleep(60000) for 60 seconds if your midi file last for less than 60 seconds. 
    //This value needs to be changed depending on each midi file you play. 
    Sleep(60000); 
} 

Вам не нужно изучать классы первых, как API Win32 производится для использования с C.C++ обратно совместим с C, поэтому вы можете вызывать эти API из C++ и пока не беспокоиться о классах.

Вот ссылка на учебник по программированию окон напрямую с помощью Win32 API. http://www.winprog.org/tutorial/simple_window.html

Относительно немногие программисты знакомы с этим материалом, а просто используют простые в использовании фреймворки, такие как .NET или Java или другие. Но, чтобы разобраться в этом, так оно и работает.

+0

Спасибо. Теперь я знаю, в каком направлении заниматься исследованиями. Быстрое решение, которое вы дали на самом деле, - это не то, что я ищу, но, как сказал Тарин, мне было не очень понятно начинать, поэтому я редактировал свой OP. Я ищу музыку для петли в фоновом режиме, пока остальная часть кода работает. Конечно, я говорю это с предположением, что предоставленный вами код не будет работать в этом случае, или не так ли? – ABradford

+0

В этом случае первое решение, которое вы нашли, - это путь. – Valrandir

+0

Но если вам нужно быстрое и грязное решение, используйте мое решение в новом потоке, чтобы остальная часть вашего кода продолжала работать. – Valrandir

0

Вот пример темы. Вот информация о msdn на CreateThread. Эта часть проста. https://msdn.microsoft.com/en-us/library/windows/desktop/ms682453%28v=vs.85%29.aspx https://msdn.microsoft.com/en-us/library/windows/desktop/ms686736(v=vs.85).aspx

#define WIN32_LEAN_AND_MEAN 
#include <Windows.h> 

DWORD WINAPI ThreadProc(void* param) 
{ 
    //Play MIDI 
    //Sleep 
    return 0; 
} 

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) 
{ 
    //Launch the thread and continue execution 
    CreateThread(NULL, 0, ThreadProc, 0, 0, 0); 

    //Code below this comment will run while the music is playing 

    return 0; 
} 

Вы также можете определить на структуру containine имя файла и количество миллисекунд, чтобы ждать, таких как:

#define WIN32_LEAN_AND_MEAN 
#include <Windows.h> 

struct MusicInfo 
{ 
    LPCTSTR file_path; 
    DWORD milliseconds; 
}; 

DWORD WINAPI ThreadProc(void* param) 
{ 
    MusicInfo* mi = (MusicInfo*)param; 

    //Play MIDI 
    //mciApiFunc and use the string in mi->file_path 
    Sleep(mi->milliseconds); 

    delete mi; 
    return 0; 
} 

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) 
{ 
    MusicInfo* mi = new MusicInfo { TEXT("hello.mid"), 60000 }; 

    //Launch the thread and continue execution 
    CreateThread(NULL, 0, ThreadProc, (void*)mi, 0, 0); 

    //Code below this comment will run while the music is playing 

    return 0; 
}