none
wave output???? RRS feed

  • Question

  • summary : BYTE sound data -> 32bit sample 

    environment : 64bits, win7, VS2010, lang C++(MFC) , base project is AudioCaptureRaw

    //doc

    max_amp1=-2147483647; //int max
    min_amp1=2147483646;    //int min

    BYTE *captureBuffer1 = new BYTE[BufferSize];

    unsigned int* tempIntBuffer=new unsigned int[BufferSize/4];  //int=4byte.
    int * tempIntBuffer1= new int [BufferSize/4];



    for(int i=0;i<BufferSize/4;i++)
    {
          unsigned int temp1=0,temp2=0,temp3=0,temp4=0;  
      
          temp1=(temp1 | captureBuffer1[i])&0x000000FF;
          temp2=(temp2 | captureBuffer1[i+1])&0x000000FF;
          temp3=(temp3 | captureBuffer1[i+2])&0x000000FF;
          temp4=(temp4 | captureBuffer1[i+3])&0x000000FF;
          tempIntBuffer[i] = ((temp1 << 24) & 0xFF000000) | ((temp2 << 16) & 0x00FF0000) | ((temp3 << 8) & 0x0000FF00) | ((temp4) & 0x000000FF );

          tempIntBuffer1[i]=(int)tempIntBuffer[i];
    }

     for(int i=0;i<BufferSize/4;i++)
    {
          if(tempIntBuffer1[i]>max_amp1)
               max_amp1=tempIntBuffer1[i];
    }

    for(int i=0;i<BufferSize/4;i++)
    {
          if(tempIntBuffer1[i]<min_amp1)

                  min_amp1=tempIntBuffer1[i];

    }


    //view.. ondraw..
    if(pDoc->recorded==true)
    {
          int k=0;
          int j=0;

         amp_scale=(float)pt.y/(float)(pDoc->max_amp1*2);
     
         
         pDC->MoveTo(0,pt.y/2); 


          for(float i=0;i<pt.x;i=i+0.03125)  //i = out width, k=out start point, full out i = 0.03125
         {
               j=pt.y/2+(pDoc->tempIntBuffer1[k++]*amp_scale);
               pDC->LineTo(i,j);
         }
    }









    • Edited by _yi Thursday, March 15, 2012 4:10 AM
    Thursday, March 15, 2012 4:06 AM

Answers

  • The root of the problem here is that samples are stored little endian.  This means that the first byte of the sample is the least significant, not the most.  The above code will basically work if you switch the line:

          tempIntBuffer[i] = ((temp1 << 24) & 0xFF000000) | ((temp2 << 16) & 0x00FF0000) | ((temp3 << 8) & 0x0000FF00) | ((temp4) & 0x000000FF );

    to read:

          tempIntBuffer[i] = ((temp4 << 24) & 0xFF000000) | ((temp3 << 16) & 0x00FF0000) | ((temp2 << 8) & 0x0000FF00) | ((temp1) & 0x000000FF );

    You will still get slightly unexpected results in the program as written for two reasons:

    1) The channels are interleaved.  After you change to samples, you only want every 4th one if you want to visualize a single channel

    2) Right now you're scaling the output to take the whole visual range.  If you're interested in seeing maximum variation in the rendered wave, this can be a useful tool... However, if you want to see absolute amplitude you should scale by the logical potential maximum value (MAXLONG in this case), not the observed highest value in the data stream.

    Tuesday, April 3, 2012 4:25 PM