Play song after song with MciSendString, "problem" with "wait"

1

Good morning, I want my code to be able to play one song after another, I managed to do it with "wait", but the problem is that I do not want to "freeze" the program while it is running the mp3, but it is available for the other functions like "pause" or "stop"

I have tried to inform and it seems that the command "status" could serve me, but I do not understand how to use it for what I need.

So I would appreciate your help, Thanks.

Here is the code in the "case IDC_Play1:"

if ((SendDlgItemMessage(hDlg, IDC_CHECK1, BM_GETSTATE, NULL, NULL)) == BST_CHECKED) {//codigo para reproducir solo una cancion(no hay problema aqui)}

else {
    int cuenta = SendDlgItemMessage(hDlg, IDC_LIST1, LB_GETCOUNT, NULL, NULL);
    int indice = 0;
    while (indice != cuenta) {
        char auxi[10] = "";
        UINT index = SendDlgItemMessage(hDlg, IDC_LIST1, LB_GETCURSEL, 0, 0);
        SendDlgItemMessage(hDlg, IDC_LIST1, LB_GETTEXT, index, (LPARAM)auxi);
        if (strcmp(auxi, "") == 0) {
            MessageBox(NULL, "No se selecciono cancion", "ERROR", MB_ICONERROR);
        }
        else {
            char Cnum[10];
            aux = inicio;
            aux = aux->sig;
            do {
                _itoa_s(aux->folio, Cnum, 10);
                if (strcmp(auxi, Cnum) == 0) {
                    strcpy_s(szFileName, aux->mptres);
                    bmp1 = (HBITMAP)SendDlgItemMessage(hDlg, IDC_Imagen1, STM_GETIMAGE, IMAGE_BITMAP, 0);
                    bmp2 = (HBITMAP)LoadImage(NULL, aux->imagen, IMAGE_BITMAP, 140, 120, LR_LOADFROMFILE);
                    SendDlgItemMessage(hDlg, IDC_Imagen1, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)bmp2);
                }
                else {
                    aux = aux->sig;
                }
            } while (strcmp(auxi, Cnum) == -1 || strcmp(auxi, Cnum) == 1);

            ShowWindow(GetDlgItem(hDlg, IDC_Play1), SW_HIDE);
            ShowWindow(GetDlgItem(hDlg, IDC_Pause1), SW_SHOW);

            char comillas[MAX_PATH] = "\"";
            char comillas2[MAX_PATH] = "\"";
            strcat_s(comillas, szFileName);
            strcat_s(comillas, comillas2);
            char musica[MAX_PATH] = "open ";
            strcat_s(musica, comillas);
            strcat_s(musica, " type mpegvideo");
            mciSendString(musica, NULL, 0, 0);
            char musica1[MAX_PATH] = "play ";
            char esperar[MAX_PATH] = " wait";
            strcat_s(musica1, comillas);
            strcat_s(musica1, esperar);

            mciSendString(musica1, NULL, 0, 0);
            char parar[MAX_PATH] = "stop ";
            strcat_s(parar, comillas);
            mciSendString(parar, NULL, 0, 0);
            char cerrar[MAX_PATH] = "close ";
            strcat_s(cerrar, comillas);
            mciSendString(cerrar, NULL, 0, 0);

            index++;
            SendDlgItemMessage(hDlg, IDC_LIST1, LB_SETCURSEL, index, NULL);
            SendDlgItemMessage(hDlg, IDC_LIST2, LB_SETCURSEL, index, NULL);
            SendDlgItemMessage(hDlg, IDC_LIST3, LB_SETCURSEL, index, NULL);
            SendDlgItemMessage(hDlg, IDC_LIST4, LB_SETCURSEL, index, NULL);
            SendDlgItemMessage(hDlg, IDC_LIST5, LB_SETCURSEL, index, NULL);

            indice = index;
        } //else
    } //while
}//else

Finally, a question about stackoverflow, how do I correctly insert a block of code?

    
asked by Dan Silva 08.07.2016 в 21:10
source

1 answer

1
  

The problem is that I do not want to "freeze" the program while running the mp3

What you describe is the usual behavior of synchronous routines, does not perform any new routine (such as pause or stop) until the current routine is finished (play). So the question is whether mciSendString is a synchronous routine.

Problem

I found it hard to find information about it, in Microsoft's official documentation it does not indicate if the function is synchronous or asynchronous but in this MSDN thread points to this documentation indicating the following (the translation and highlighting are mine):

  

REXX commands include mciRxSendString , mciRxGetErrorString , and mciRxGetDeviceID that provide access to the APIs mciSendString , mciGetErrorString , and mciGetDeviceID respectively. These REXX commands are linked with calls to mciRxInit and mciRxExit . Calls to these commands must contain the keyword wait or not use anything. This is because when the keyword notify is used, a notification is sent to a window process. When PMREXX has a window procedure, REXX does not. By not specifying either wait or notify , an asynchronous call is made without completion notification .

Therefore, when you use wait the call is synchronous, and that's why it stays frozen.

Suggestion

To be able to send commands of pause and stop with mciSendString , you should transform the call mciSendString(musica1, NULL, 0, 0); in asynchronous. For this you can use the library <thread> of C ++ 11:

// Funcion que invoca mciSendString con play y wait sobre el
// archivo indicado.
void play_wait(const char *file) {
    char musica1[MAX_PATH] = "play ";
    char esperar[MAX_PATH] = " wait";
    strcat_s(musica1, file);
    strcat_s(musica1, esperar);
    mciSendString(musica1, NULL, 0, 0);
}

First we create the function that makes the call, we can call this function asynchronously as follows:

char comillas[MAX_PATH] = "\"";
char comillas2[MAX_PATH] = "\"";
strcat_s(comillas, szFileName);
strcat_s(comillas, comillas2);
char musica[MAX_PATH] = "open ";
strcat_s(musica, comillas);
strcat_s(musica, " type mpegvideo");
mciSendString(musica, NULL, 0, 0);

std::thread asincrono(play_wait, comillas);
asincrono.detach();

The thread::detach function will cause the play_wait function to run asynchronously on another thread disengaging the asíncrono object from the current context, so you should not worry about it. When the call enclosed within play_wait ends, the thread will also end. While the thread is running, the file will be played and I suppose that the device can continue to receive commands asynchronously.

Warning

I have never used mciSendString nor have I been able to prove the polish, it might not work. Let me know if you find other related problems.

    
answered by 11.07.2016 в 11:24