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

 C++ Discussion :

mettre une partie de buffer à 0


Sujet :

C++

  1. #1
    Membre averti
    Inscrit en
    Mai 2010
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 18
    Par défaut mettre une partie de buffer à 0
    Bonjour,

    j'ai un buffer que je rempli ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    m_headerbufferlen = m_wfx.nAvgBytesPerSec/20 * 2;
    for(int t=0; t<HDRCUNT; t++){
        CWaveHdr * phdr = new CWaveHdr();
        ZeroMemory(phdr, sizeof(CWaveHdr)); 
        phdr->lpData = new char[m_headerbufferlen];
        m_freeq.push(phdr);
    }
    et je souhaiterai forcer à 0 du début du buffer (pour l'instant) phdr juska la fin, 16bits à 0 et ainsi de suite tous les 16 bits.. coment faire cela?

    pour info, il s'agit d'un fichier wave, stéréo,16bits, et je veux forcer un canal à 0 afin de pouvoir en faire un fichier mono en forcant ensuite le canal à 0.
    Merci

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut et bienvenu,
    A moins que CWaveHdr ne soit un type POD, j'ai peur que ce que tu demandes ne t'entraine vers quelque soucis. Une structure/classe C++ n'est pas une structure C.
    Si tu veux initialiser les membres de CWaveHdr, utilises un constructeur adéquat.

  3. #3
    Membre averti
    Inscrit en
    Mai 2010
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 18
    Par défaut
    Mais je ne veux pas faire ca à l'initialisation, je veux faire un traitement à un moment donné.. et je me retrouve avec ce buffer à qui je doit mettre en gros la moitié des bits à zéro.. c'est pas possible??

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    quelle est la définition de CWaveHdr ?

  5. #5
    Membre averti
    Inscrit en
    Mai 2010
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 18
    Par défaut
    la voila..

    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
    class CWaveHdr:
    public WAVEHDR{
     
    };
     
     
    /* wave data block header */
    typedef struct wavehdr_tag {
        LPSTR       lpData;                 /* pointer to locked data buffer */
        DWORD       dwBufferLength;         /* length of data buffer */
        DWORD       dwBytesRecorded;        /* used for input only */
        DWORD_PTR   dwUser;                 /* for client's use */
        DWORD       dwFlags;                /* assorted flags (see defines) */
        DWORD       dwLoops;                /* loop control counter */
        struct wavehdr_tag FAR *lpNext;     /* reserved for driver */
        DWORD_PTR   reserved;               /* reserved for driver */
    } WAVEHDR, *PWAVEHDR, NEAR *NPWAVEHDR, FAR *LPWAVEHDR;

  6. #6
    Membre averti
    Inscrit en
    Mai 2010
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 18
    Par défaut
    ou bien copier tout ca dans un std::vector<int> buffer ? mais idem, comment faire cela? je vois pas comment acceder à mon buffer..

  7. #7
    Membre averti
    Inscrit en
    Mai 2010
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 18
    Par défaut
    si je fait ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    char *pCurrentBuffer = phdr->lpData 
    int nbSamples = m_headerbufferlen / 4; // 2 canaux, 2 octets par sample 
    newBuffer.reserve( nbSamples );
    for( int i = 0; i < nbSamples; ++i )
    {
      newBuffer.push_back( pCurrentBuffer[ i * 2 ] );
    }
    phdr->lpData = &newBuffer[0]; 
    m_freeq.push(phdr);
    ca plante mon programme... une idée?

  8. #8
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Si j'étais vous j'essayerais de faire une union. C'est assez rarement utilisé, mais c'est bien pratique pour accéder aux membres d'une structure indirectement.

  9. #9
    Membre averti
    Inscrit en
    Mai 2010
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 18
    Par défaut
    comment ca? une union de quoi et quoi? le but ici serait juste d'extraire une zone qui m'interresse dans le buffer.

  10. #10
    Invité
    Invité(e)
    Par défaut
    Une union est assez comparable à une structure.
    Par contre, ce qui est utile est que la même zone peut être connue sous 2 noms différente et donc 2 type différents.
    Je n'ai pas utilisé cette méthode très souvent, mais une toute petite lecture permet de s'y retrouver.
    Le principe est le suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    MonUnion
    {
      double D;
      int i; 
    } mu;
      mu.D=3.1416;
      mu.i=0;
    Alors les octets correspondant à i (4 octets probablement) sont mis à 0
    donc les 4 premiers octets de D seront à 0 et les 4 autres inchangés, ce qui fait naturellement que D n'aura plus rien à voir avec 3.1416.
    Un short int mesure normalement 2 octets, soit 16 bits.
    Donc, avec ce principe vous devriez y arriver.

    Il y a aussi les champs de bits qui permettent une décomposition au nibeau des bits.

    J'ai regardé un peu plus votre structure. Il s'agit d'une structure de liste chainée, je n'ai pas très bien vu dedans lesquels 16 bits parmi 16 vous voulez mettre à 0, c'est à dire je ne comprend pas à quoi servent les différents membres de cette structure.

    Il y aurait peut-être le membre dwFlags qui pourrait apporter des informations intéressantes.
    Dernière modification par Invité ; 01/06/2010 à 18h55.

  11. #11
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    Je ne recommande pas l'usage de l'union qui embrouillerait le code avec un pauvre hack et introduirait probablement du risque (sans compter qu'un int peut ne pas faire 4 octets ni un short 2).

    En revanche, j'ai du mal à comprendre ce que tu veux initialiser à 0 : toute la structure pointée par phdr ou un champs ? Et pourquoi passer par un std::vector ?

  12. #12
    Membre averti
    Inscrit en
    Mai 2010
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 18
    Par défaut
    Ces champs sont deux bandes son d'un wave, donc je veux mettre la voie de droite ou gauche à 0..pour n'avoir qu'un seul canal. Je suis en train d'essayer de faire ca avec un std::vector mais je galère un peu.. ca ne marche pas comme je le souhaite..

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    vector< signed short > newBuffer;
    signed short *pCurrentBuffer = reinterpret_cast<signed short*>( phdr->lpData );
    int nbSamples = m_headerbufferlen / 4; // 2 canaux, 2 octets par sample 
    newBuffer.reserve( nbSamples );
    for( int i = 0; i < nbSamples; ++i )
    {
      newBuffer.push_back( pCurrentBuffer[ i * 2 ] );
    }
    phdr->lpData = &newBuffer[0];  
    m_freeq.push(phdr);

  13. #13
    Membre averti
    Inscrit en
    Mai 2010
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 18
    Par défaut
    et pourquoi pas passer par un std::vector? c'est génant?

  14. #14
    Membre averti
    Inscrit en
    Mai 2010
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 18
    Par défaut
    en fait j'essaye soit de mettre une partie à 0, soit d'extraire l'autre partie et de travailler avec. D'ou le std::vector car je ne voit pas comment mettre à zéro simplement.
    le wave est fait ainsi : 16bit voie G,16bits voie D et ainsi de suite.. donc je doit travailler sur une certaine partie de buffer..tous les 16bits en fait.

  15. #15
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Le buffer associé au std::vector sera détruit au moment où le std::vector va sortir de sa portée.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    {
    vector< signed short > newBuffer;
    signed short *pCurrentBuffer = reinterpret_cast<signed short*>( phdr->lpData );
    int nbSamples = m_headerbufferlen / 4; // 2 canaux, 2 octets par sample 
    newBuffer.reserve( nbSamples );
    for( int i = 0; i < nbSamples; ++i )
    {
      newBuffer.push_back( pCurrentBuffer[ i * 2 ] );
    }
    phdr->lpData = &newBuffer[0];  
    m_freeq.push(phdr);
    }
    // ici newBuffer est détruit et m_free.back()->lpData pointe sur une zone invalide
    Ce que je comprends à partir de ton code :
    -> A l'entrée, phdr->lpData contient headerbufferlen octets définissant nbrCanaux interlacés sur des mots de nbrOctets.
    Par exemple avec 2 canaux :
    |C10|C20|C11|C21|C12|C22....|C1N|C2N
    -> A la sortie phdr->lpData contient headerbufferlen les données d'un seul canal. Le reste a été supprimé.
    |C10|C11|C12|....|C1N
    Est-ce bien ça ? Ou veux tu :
    |C10|0|C11|0|C12|0....|C1N|0
    ?

  16. #16
    Membre averti
    Inscrit en
    Mai 2010
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 18
    Par défaut
    c'est bien la première solution, je veux obtenir |C10|C11|C12|....|C1N..
    mais si tu me dit que m_free.back()->lpData pointe sur une zone invalide, c'est pour cela que ca plante au bout d'un court instant... une idée sur comment palier ce problème?

  17. #17
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    En reprenant bourrin ton code :
    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
    // nombre de canaux
    const size_t nbr_canaux = 2;
    // canal que l'on souhaite garder >=0 et <nbr_canaux:
    const size_t canal = 0;
    // où on va écrire la valeur
    signed short *pCurrentBuffer = reinterpret_cast<signed short*>( phdr->lpData );
    // la valeur à lire :
    signed short const *pNext = pCurrentBuffer + canal;
    for(unsigned long i=0;i<m_headerbufferlen/nbr_canaux;++i)
    {
        *pCurrentBuffer = *pNext;
        // on écrit au short suivant :
        ++pCurrentBuffer;
        // mais on saute le bon nombre de canaux :
        pNext+=nbr_canaux;
    }
    // phdr->lpData; inchange
    phdr->dwBufferLength = m_headerbufferlen/nbr_canaux;
    m_freeq.push(phdr);

  18. #18
    Membre averti
    Inscrit en
    Mai 2010
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 18
    Par défaut
    quand tu mets : // phdr->lpData; inchange
    je suppose quand même que je dois mettre du genre : phdr->lpData = reinterpret_cast<char*> (&pCurrentBuffer [0]); sinon j'ai rien dans mon lpData ..
    mais ca plante dans la boucle, à priori, il faudrait faire un /4 au lieu de /2 car m_headerbufferlen = nb samples * nb canaux(2) * taille de sample en octet(2)..
    mais la encore ca plante mais plus loin..

  19. #19
    Membre averti
    Inscrit en
    Mai 2010
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 18
    Par défaut
    bon sinon autre technique, recopier une voie sur lautre..histoire d'avoir la même valeur sur mes 2 voie..
    en gros je rajoute ca :
    {
    *pCurrentBuffer = *pNext;
    // on écrit au short suivant :
    ++pCurrentBuffer;
    *pCurrentBuffer = *pNext; //copie d'une voie sur l'autre..
    // mais on saute le bon nombre de canaux :
    pNext = pNext + nbr_canaux;
    }

    ca devrait le faire nan?

  20. #20
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    A tout hasard, comment est alloué phdr->lpData ? Avant cette fonction, j'espère.

Discussions similaires

  1. mettre une partie de la page invisible.
    Par rainlily dans le forum ASP.NET
    Réponses: 2
    Dernier message: 06/08/2007, 13h25
  2. memcpy, memmove etc. d'une partie du buffer
    Par muquet dans le forum Débuter
    Réponses: 5
    Dernier message: 19/07/2007, 17h49
  3. [champ de saisie] Mettre une partie en gras
    Par popov2 dans le forum WinDev
    Réponses: 2
    Dernier message: 23/05/2007, 20h27
  4. [ListBox] Mettre une partie du texte d'un item en gras
    Par Sergio29 dans le forum Delphi
    Réponses: 2
    Dernier message: 28/01/2007, 19h55
  5. Excel : mettre une partie du contenu d'une cellule en gras
    Par cladsam dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 23/08/2006, 10h05

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