locked
Convertion Wave en GSM610. RRS feed

  • Question

  • Bonjour,

    je voudrai savoir si Windows Mobile 5 est capable de convertir un son enregistré par le micro en format PCM vers un format GSM610 ?
    Dans l'idéal, je voulais enregistrer directement du son sous le format GSM mais apparement ce n'est pas possible. Je peux donc enregistrer en PCM mais je n'arrive pas à le convertir.
    J'utilise les fonctions ACM.

    En effet, les fonctions acmFormatSuggest et acmStreamOpen retournent à chaque fois l'erreur 512.

    je ne trouve pas d'ou peut provenir cette erreur. Je ne trouve pas non plus de bonnes documentations à ce sujet.
    Voici mon code qui génére cette erreur (C#) :

    public unsafe class convert
        {
            // Constantes
            public  const int      WAVE_FORMAT_PCM = 1;
            public const int      WAVE_FORMAT_GSM610 = 49;
            internal const uint     WAVE_MAPPER = uint.MaxValue;
            internal const int      CALLBACK_WINDOW = 0x0010000;
            internal const int      WAVE_FORMAT_QUERY = 0x00000001;
            internal const int      ACM_STREAMOPENF_QUERY = 0x00000001;
            public const int      ACM_STREAMOPENF_NONREALTIME = 0x00000004;
            internal const int     ACM_METRIC_MAX_SIZE_FORMAT = 50;
            public const int     ACM_FORMATSUGGESTF_WFORMATTAG = 0x10000;
            public const int        WAVE_FORMAT_ADPCM = 0x00000002;
              
             // Import DLL
            IntPtr m_hWaveIn = IntPtr.Zero;
            [DllImport("coredll.dll", EntryPoint = "acmStreamOpen", SetLastError = true)]
            internal static extern int acmStreamOpen(ref IntPtr handle, int driverHandle,ref WAVEFORMATEX_PCM WAVEFORMATEX_source, ref WAVEFORMATEX_PCM WAVEFORMATEX_dest,IntPtr WAVEFILTER,IntPtr Callback,IntPtr CallbackInstanceData,int fdwOpen);

            [DllImport("coredll.dll", EntryPoint = "acmMetrics", SetLastError = true)]
            internal static extern int acmMetrics(IntPtr hao, uint uMetric, uint *pMetric);

            [DllImport("coredll.dll", EntryPoint = "acmFormatSuggest", SetLastError = true)]
            internal static extern int acmFormatSuggest(IntPtr has, ref WAVEFORMATEX_PCM WAVEFORMATEX_source, ref WAVEFORMATEX_GSM610 WAVEFORMATEX_dest,uint cbwfxDst,uint fdwSuggest );

            // Declaration des structures
            [StructLayout(LayoutKind.Sequential)]
            public unsafe class WAVEFORMATEX_PCM
            {
                public  ushort wFormatTag;
                public  ushort nChannels;
                public  uint nSamplesPerSec;
                public  uint nAvgBytesPerSec;
                public  ushort nBlockAlign;
                public  ushort wBitsPerSample;
                public  ushort cbSize;
            }
            [StructLayout(LayoutKind.Sequential)]
            public unsafe class WAVEFORMATEX_GSM610
            {
                public unsafe WAVEFORMATEX_PCM wfx;
                public  ushort wSamplesPerBlock;
            }     
                 
            // Fonctions
            public unsafe int convertir (string Filename, Byte[] Buffer)
            {
                // Trouver le plus grand format
                uint maxFormatSize = 0;
                int result;
                result = acmMetrics( IntPtr.Zero, ACM_METRIC_MAX_SIZE_FORMAT, &maxFormatSize );
                if (result != 0)
                {
                    return result;
                }
               
                // Declare le format source
                WAVEFORMATEX_PCM wfxInput = new WAVEFORMATEX_PCM();
                wfxInput.cbSize = 0;
                wfxInput.nAvgBytesPerSec = 8000;
                wfxInput.nBlockAlign = 1;
                wfxInput.nChannels = 1;
                wfxInput.nSamplesPerSec = 8000;
                wfxInput.wBitsPerSample = 8;
                wfxInput.wFormatTag = WAVE_FORMAT_PCM;
               
                 // Declare le format desiré
                WAVEFORMATEX_GSM610  wfxOutput = new WAVEFORMATEX_GSM610();
                wfxOutput.wfx = new WAVEFORMATEX_PCM();
               
                wfxOutput.wfx.wFormatTag = WAVE_FORMAT_GSM610;
                wfxOutput.wfx.nChannels = 1;
                wfxOutput.wfx.nSamplesPerSec = 8000;
                wfxOutput.wfx.nAvgBytesPerSec = 1625;
                wfxOutput.wfx.nBlockAlign = 65;
                wfxOutput.wfx.wBitsPerSample = 0;
                wfxOutput.wfx.cbSize = 2;
                wfxOutput.wSamplesPerBlock = 320;

                IntPtr acmhandle = IntPtr.Zero;
                result = acmFormatSuggest(acmhandle, ref wfxInput, ref wfxOutput, maxFormatSize, ACM_FORMATSUGGESTF_WFORMATTAG);

                // ----- retourne le code erreur 512 ---------

               // result = acmStreamOpen(ref acmhandle, 0, ref wfxInput, ref (WAVEFORMATEX_PCM)wfxOutput, IntPtr.Zero,IntPtr.Zero , IntPtr.Zero, ACM_STREAMOPENF_NONREALTIME);
                // ----- retourne le code erreur 512 ---------
                if (result != 0)
                {
                    return result;
                }
                return 0;
            }

    J'ai essayé plusieurs configurations des formats sans succés.
    Je me demande si c'est vraiment réalisable ? Ou alors je n'ai pas du tout compris comment cela fonctionne. J'ai vu que ce fonctionne parfaitement sur un Windows classique. De plus, l'appareil sur lequel je teste ce code gére le format GSM puisque l'outil d'enregistrement par defaut permet d'enregistrer dans ce format.

    Si quelqu'un peut m'éclairer!
    Merci par avance.
    jeudi 12 avril 2007 16:15

Toutes les réponses

  • Bonjour,

     

    Peut-être pourriez-vous essayer dans un premier temps de tester directement le code en C afin de voir si le problème vient du code managé ou alors des fonctions natives.

     

    Fabien Decret
    Windows Embedded Consultant

    ADENEO (ADESET)
    http://www.adeneo.adetelgroup.com/

    dimanche 15 avril 2007 20:32