3 Replies Latest reply: Apr 6, 2011 11:25 AM by rquantin RSS

    bytes float and sound

    rquantin Community Member

      Hi,

       

      I'm trying to do something simple:

      send a byteArray to a C library, fill up a buffer and read the memory, but I think I have float conversion problems.

       

      Here is what I do in AS:

       

      var memory:ByteArray = gstate.ds;

      // get sound

      var soundBytes:ByteArray = new ByteArray();
      _source.extract(soundBytes, 4096);

      soundBytes.position = 0;

      // send sound

      _lib.processSound(soundBytes);

      // get sound back to play it

      memory.position = _dataPosition

      event.data.writeBytes(memory);

       

      The C code:

       

      My buffer variable:

      float *buffer;

       

      The buffer is intialize at the beginning:

      static AS3_Val initByteArray(void* self, AS3_Val args) {
          AS3_ArrayValue(args, "IntType", &bufferSize);
          buffer = (float*)malloc(bufferSize*sizeof(float));
          return AS3_Int((int)buffer);
      }

       

      And I process the sound:

       

      AS3_Val src = AS3_Undefined();

      AS3_ArrayValue( args,"AS3ValType", &src );

      // get length

      AS3_Val lengthOfArgs = AS3_GetS(src,"length");
      int len = AS3_IntValue(lengthOfArgs);

      // set position to 0 and write the buffer

      AS3_ByteArray_seek(src, 0, SEEK_SET);
      AS3_Trace(AS3_GetS(src, "bytesAvailable"));
      AS3_ByteArray_readBytes(buffer, src, len);

       

      Now I get the error:

      Exception fault: RangeError: Error #2004: One of the parameters is invalid.
          at flash.media::Sound/play()

       

      The memory seems to be increased correctly when I write in the buffer, 32768 for 4096 * 8 (4 for float times 2 for left and right channel).


      When I trace the bytes in flash before sending the byteArray, I get some numbers like this (at a specific position of 1421 to compare):

      soundBytes.position = 1421 * 8;
      trace(soundBytes.readFloat()); // trace -0.000030517578125 (left)
      trace(soundBytes.readFloat()); // trace 0.000030517578125 (right)

       

      I can trace the same number in C:

      AS3_ByteArray_seek(src, 1421*8, SEEK_SET);
      AS3_Val emptyParams = AS3_Array("");
      AS3_Val readFloat = AS3_GetS(src, "readFloat");
      AS3_Trace(readFloat);
      AS3_Val left = AS3_Call(readFloat, src, emptyParams);
      AS3_Trace(left); // trace -0.000030517578125 (left)
      AS3_Val right = AS3_Call(readFloat, src, emptyParams);
      AS3_Trace(right); // trace 0.000030517578125 (right)

       

      But when I trace the buffer:

      AS3_Trace(AS3_Number(buffer[1421*2])); // trace 2.5783891743576634e-43
      AS3_Trace(AS3_Number(buffer[(1421*2)+1])); trace 7.847271400218976e-44

       

      And in flash after calling the lib:

      soundBytes.position = 1421 * 8;
      trace(soundBytes.readFloat()); // trace 2.5783891743576634e-43
      trace(soundBytes.readFloat()); // trace 7.847271400218976e-44

       

      I looks like the number has been converted or has a different type/format:

      -0.000030517578125

      vs

      2.5783891743576634e-43

       

      I'm not that fluent in C, any idea of what's happening?

       

      Thanks for reading.

       

      Romu

        • 1. Re: bytes float and sound
          andrey.mironov Community Member

          Hi Romu,

           

          I think it may be the endian issue. Since when you create new ByteArray in ActionScript it is big-endian by default. But the C memory ByteArray is little endian. Try to change it to little endian:

          var soundBytes:ByteArray = new ByteArray();

          soundBytes.endian = Endian.LITTLE_ENDIAN;

          • 2. Re: bytes float and sound
            rquantin Community Member

            Oh yes, definitely the problem!

            I can know read the same values everywhere, thanks a lot!

             

            event.data.writeBytes(memory, _dataPosition, 4096*8);

             

            Now the SampleDataEvent loops and I can read it.

             

            I'm freeing the buffer at every call, so the data should be at the same position in the memory:

             

            free(buffer);
            *buffer = 0;

             

            But now I dont have errors, there's still no sound playing. It is running, but silent. Any other wonderful idea?

             

            Am I writing the same bunch of bytes that are the first ones? (as there's no sound at the beginning)?

             

            Thanks again.

             

            Romu

            • 3. Re: bytes float and sound
              rquantin Community Member

              Found my mistake.

               

              I didn't have to send a little endian to the C library, but to convert the memory to a big endian.

               

              var output:ByteArray = new ByteArray();
              output.endian = Endian.BIG_ENDIAN;
              output.writeBytes(memory, _dataPosition, 4096*8);

               

              Solved.

               

              Thanks a lot for the hint!

               

              Romu