IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contribuez Discussion :

WaveForm (forme d'onde audio)


Sujet :

Contribuez

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    564
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 564
    Par défaut WaveForm (forme d'onde audio)
    Ce projet 64-bit VS2022 dessine une forme d'onde audio comme dans Audacity.

    Nom : SkinWave.png
Affichages : 144
Taille : 539,4 Ko

    Mode d'emploi :
    Glissez-déposez un fichier audio au format mp3, ogg, wav.
    Ou cliquez sur le bouton "Play" pour utiliser la musique par défaut.

    Image de fond :
    Cliquez sur l'icône en haut à gauche (avec le bouton gauche ou droit de la souris) pour modifier l'arrière-plan.

    A propos du code :
    La procédure "CreateWaveform" décode le canal audio avec BASS_StreamCreateFile (Bass.dll)
    et utilise ZI_CreateDIBSection (GDImage64.DLL) pour représenter le PixelArray.

    La fonction "Animate" se charge alors de visualiser la progression du flux audio au fur et à mesure de la lecture de la musique.
    Le curseur clignotant peut être déplacé vers l'avant ou vers l'arrière, la progression étant mise à jour en conséquence.

    Comment compiler le code :
    Dans les propriétés du projet
    C/C++ -> Code Generation -> Runtime Library -> "Multi-threaded (/MT)".
    Linker -> Input -> TClib.lib;kernel32.lib;user32.lib;gdi32.lib;shell32.lib;
    Privilégier le code procédral et les appels directs à la FLAT API.
    Ceci permet de créer un exécutable qui fait seulement 26 Ko.

    Crédits :
    Bass.dll (audio www.un4seen.com)
    GDImage64.dll (graphique www.zapsolution.com)
    WinLIFT64.dll (interface utilisateur www.zapsolution.com)

    Note :
    En raison de la limitation de la taille des pièces jointes autorisées sur ce forum,
    j'ai été obligé de supprimer le fichier audio de démo.
    Ainsi que les différentes images qui permettent de changer l'arrière plan à la volée
    vous devez donc utiliser le trirer-déplacer depuis l'explorateur
    pour jouer un fichier audio de votre choix (.mp3, .ogg, .wav)


    Si vous voulez la version complète contactez moi sur mon forum privé
    http://www.objreader.com/index.php?topic=5.0
    Fichiers attachés Fichiers attachés

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    564
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 564
    Par défaut Correctif
    J'ai trouvé une erreur dans le code de la procedure CreateWaveform (array bound error).

    Voici le correctif :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    static void CreateWaveform(IN WCHAR* audiofile) {
        HSTREAM nScanChannel = BASS_StreamCreateFile(0, audiofile, 0, 0, BASS_STREAM_DECODE);
        HBITMAP hDIB = 0;
     
        static DWORD PixelArray[SCANHEIGHT][SCANWIDTH];
     
        long nMax, nX, nY, nXpos, nLpeak, nRpeak, nL, nR;
        WCHAR szFile[MAX_PATH] = { 0 };
        if (nScanChannel) {
            QWORD nBpp = BASS_ChannelGetLength(nScanChannel, BASS_POS_BYTE) / SCANWIDTH;
            if (nBpp) {
                long nHalfHeight = SCANHEIGHT / 2;
                HDC hIC = zDisplayDC();
                HDC hDC = CreateCompatibleDC(hIC);
                hDIB = zCreateDIBSection(hDC, SCANWIDTH, SCANHEIGHT, 32);
                SelectObject(hDC, hDIB);
                DeleteDC(hIC);
                // Must use static to avoid the default stack size limitation
                ClearMemory(PixelArray, static_cast<unsigned long long>(SCANWIDTH) * SCANHEIGHT * sizeof(DWORD));
                float rCoef = (float)(33 / (float)nHalfHeight);
                DWORD nLevel;
                nXpos = 0;
     
                // LOOP
                for (;;) {
                    nLevel = BASS_ChannelGetLevel(nScanChannel); // scan peaks
                    nLpeak = LOWORD(nLevel);
                    nRpeak = HIWORD(nLevel);
     
                    if (BASS_ChannelIsActive(nScanChannel) == 0) { // reached the }
                        break;
                    } else {
                        nX = (long)(BASS_ChannelGetPosition(nScanChannel, BASS_POS_BYTE) / nBpp);
                    }
     
                    if (nX > nXpos) {
                        if (nX >= SCANWIDTH - 1) break;
     
                        nL = (nLpeak * nHalfHeight / 32768) - 1;
                        nR = (nRpeak * nHalfHeight / 32768) - 1;
                        nMax = max(nL, nR);
     
                        for (nY = 0; nY <= nMax; nY++) {
                            if (nY < nL + 1) PixelArray[nHalfHeight - nY][nX] = LevelColor((long)(rCoef * nY));
                            // Out of bound error, because of nY + 1 below.
                            //if (nY < nR + 1) PixelArray[min(nHalfHeight + nY + 1, 127)][nX] = LevelColor((long)(rCoef * nY));
                            if (nY < nR + 1) PixelArray[nHalfHeight + nY][nX] = LevelColor((long)(rCoef * nY));
                        }
     
                        nXpos = nX;
                    }
                }
     
                ZI_SetDIBits(hDC, &PixelArray);
     
     
                BASS_StreamFree(nScanChannel); // free the decoder
                DeleteDC(hDC);
     
            }
        } else { // In case of music tracker
            Path_Combine(szFile, EXEresource(), L"tracker.png");
            hDIB = ZI_ResizeBitmapFromFile(szFile, SCANWIDTH, SCANHEIGHT);
        }
        RECT lpr; GetClientRect(gP.hGDImage, &lpr);
     
        nX = (rWidth(lpr) - SCANWIDTH) / 2;
        nY = (rHeight(lpr) - SCANHEIGHT) / 2;
        if (hDIB) ZD_DrawBitmapToCtrl(gP.hGDImage, nX, nY, hDIB, ZD_ColorARGB(80, 0), ID_WAVEFORM, ZS_VISIBLE);
     
        ZD_SetObjectImageLabel(ID_WAVEFORM, L"Waveform");
        ZD_SetObjectZorder(ID_WAVEFORM, ZD_ORDER_BOTTOM);
        ZD_SetObjectLocked(ID_WAVEFORM, TRUE);
        ZD_SetObjectAnchorMode(ID_WAVEFORM, ANCHOR_CENTER);
     
        Path_Combine(szFile, EXEresource(), L"trebuc.ttf");
        if (FileExist(szFile)) {
            long nID, bmW, bmH;
            nID = ID_ELLAPSED_TIME;
            ZD_DrawTextToCtrlEx(gP.hGDImage, L"00:00:00:00", 0, -1000, 0, 0, ZD_ARGB(192, 255,255,255), szFile, 18, nID, ZS_VISIBLE, 0, 0);
            nY += SCANHEIGHT;
            ZD_SetObjectXY(nID, nX, nY, 0);
            SetObjectAnchorMode(nID, ANCHOR_CENTER);
            ZD_SetObjectHidden(nID, ZS_INACTIVE); // 2 = Transparent, its ID won't be detected and it couldn't be moved.
     
            nID = ID_DURATION;
            ZD_DrawTextToCtrlEx(gP.hGDImage, L"00:00:00", 0, -1000, 0, 0, ZD_ARGB(192, 255,255,255), szFile, 18, nID, ZS_VISIBLE, 0, 0);
            SetStatusTime(ToMFTIME(gB.medialength), ID_DURATION, TRUE);
            ZD_GetObjectBound(nID, bmW, bmH);
            nX += SCANWIDTH - bmW + 4;
            ZD_SetObjectXY(nID, nX, nY, 0);
            SetObjectAnchorMode(nID, ANCHOR_CENTER);
            ZD_SetObjectHidden(nID, ZS_INACTIVE); // 2 = Transparent, its ID won't be detected and it couldn't be moved.
        }
     
        ZD_SetObjectZorder(ID_FLARE, ZD_ORDER_TOP);
     
        ////Use this code to save the waveform to disk
        //  nRet is int = API(GDImage, "ZI_SaveBitmapToFile", AnsiToUnicode(ExePath()+ fExtractPath(audiofile, fFileName)+".png"), hDIB, 0)
        ////if the hDIB is not used in the GDImage control, { it must be deleted with DeleteObject
        //  DeleteObject(hDIB)}
    }
    //if (nY < nR + 1) PixelArray[min(nHalfHeight + nY + 1, 127)][nX] = LevelColor((long)(rCoef * nY));
    if (nY < nR + 1) PixelArray[nHalfHeight + nY][nX] = LevelColor((long)(rCoef * nY));

Discussions similaires

  1. [Lazarus] Affichage forme d'onde d'un fichier wav
    Par st02938 dans le forum Lazarus
    Réponses: 2
    Dernier message: 24/09/2009, 14h32
  2. forme d'onde d'un fichier sons
    Par glebourg dans le forum DirectX
    Réponses: 1
    Dernier message: 29/06/2005, 18h07
  3. dessiner la forme d'onde d'un fichier audio
    Par cgodefrw dans le forum DirectX
    Réponses: 7
    Dernier message: 26/06/2005, 08h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo