Page 1 of 1

Need help to convert C to PB [Resolved]

Posted: Fri Mar 27, 2009 8:56 am
by ThorstenD
Hello people!
Am new here and needs help with convert from following C code:

Code: Select all

#define amptarget 30000 // target level
#define ampquiet 800 // quiet level
#define amprate 0.02f // amp adjustment rate

typedef struct {
      float gain; // amplification level
      int delay; // delay before increasing level
      int count; // count of sequential samples below target level
      int high; // the highest in that period
      int quiet; // count of sequential samples below quiet level
} AUTOAMPSTUFF;

void CALLBACK autoamp(HDSP handle, DWORD channel, void *buffer, DWORD length, AUTOAMPSTUFF *amp)
{
      short *data=(short*)buffer;
      DWORD c;
      for (c=0;c<length/2;c++) {
            int s=(int)(data[c]*amp->gain); // amplify sample
            int sa=abs(s);
            if (abs(data[c])<ampquiet)
                  amp->quiet++; // sample is below quiet level
            else
                  amp->quiet=0;
            if (sa<amptarget) { // amplified level is below target
                  if (sa>amp->high) amp->high=sa;
                  amp->count++;
                  if (amp->count==amp->delay) { // been below target for a while
                        if (amp->quiet>amp->delay)
                              // it's quiet, go back towards normal level
                              amp->gain+=10*amprate*(1-amp->gain);
                        else
                              amp->gain+=amprate*amptarget/amp->high; // increase amp
                        amp->high=amp->count=0; // reset counts
                  }
            } else { // amplified level is above target
                  if (s<-32768) s=-32768;
                  else if (s>32767) s=32767;
                  amp->gain-=2*amprate*sa/amptarget; // decrease amp
                  amp->high=amp->count=0;
            }
            data[c]=(short)s; // replace original sample with amplified version
      }
}
I hopes somebody can help me. Thank you :D

Posted: Fri Mar 27, 2009 9:17 am
by Mistrel
With all the -> I had to do a double-take at this part :).

Code: Select all

s<-32768
I would try and convert it but without a test-case I might be way off. The only thing that might be misleading is the '->'. If you pass a structure pointer you can access structure members using the '\' character instead of C's '.'.

Did you try and convert it?

Posted: Fri Mar 27, 2009 9:22 am
by Hroudtwolf
Hi,

Have fun.

Code: Select all

#amptarget = 30000 ; target level
#ampquiet  = 800 ; quiet level
#amprate   = 0.02 ; amp adjustment rate

Structure AUTOAMPSTUFF
      gain.f ; amplification level
      delay.f ; delay before increasing level
      count.f ; count of sequential samples below target level
      high.f ; the highest in that period
      quiet.f ; count of sequential samples below quiet level
EndStructure

Structure tWordArray
   w.w [ 0 ]
EndStructure

Procedure autoamp ( handle.i , channel.i, *buffer, length.i , *amp.AUTOAMPSTUFF )
 
      Protected *ptrData.tWordArray= *buffer
      Protected c       .i
      Protected s       .i
      Protected sa      .i
      
      For c=0 To length/2 
            s=(*ptrData\w[c]**amp\gain) ; amplify sample
            sa=Abs(s)
            If (Abs(*ptrData\w[c])<#ampquiet)
                *amp\quiet+1 ; sample is below quiet level
            Else
               *amp\quiet=0
               If (sa<#amptarget)  ; amplified level is below target
                     If (sa>*amp\high) : *amp\high=sa : EndIf
                     *amp\count+1
                     If (*amp\count=*amp\delay)  ; been below target For a While
                           If (*amp\quiet>*amp\delay)
                                 ; it's quiet, go back towards normal level
                                 *amp\gain+10*#amprate*(1-*amp\gain)
                           Else
                                 *amp\gain+#amprate*#amptarget/*amp\high ; increase amp
                                 *amp\high=*amp\count=0 ; reset counts
                           EndIf
                     EndIf
                Else   ; amplified level is above target
                     If (s<-32768) 
                        s=-32768
                     Else 
                        If (s>32767) : s=32767 : EndIf
                        *amp\gain-2*#amprate*sa/#amptarget ; decrease amp
                        *amp\high=*amp\count=0
                     EndIf
               EndIf
               *ptrData\w[c]=s ; replace original sample With amplified version
            EndIf
      Next 
      
      ProcedureReturn #Null
EndProcedure
Regards

Wolf

Posted: Fri Mar 27, 2009 11:09 am
by PB
@Hroudtwolf: Your conversion looks good! Did you ever think about writing
a C-to-PureBasic converter? Or is just easier to do it by hand?

Posted: Fri Mar 27, 2009 11:11 am
by Mistrel
PB wrote:@Hroudtwolf: Your conversion looks good! Did you ever think about writing
a C-to-PureBasic converter? Or is just easier to do it by hand?
That would be a pretty big undertaking. But in reality, would it actually be useful?

Posted: Fri Mar 27, 2009 11:14 am
by PB
> would it actually be useful?

Hell yeah. The example above taught me a thing or two about C conversions.
It's like looking at the ASM output of a PureBasic source; it teaches you a bit
about ASM when reading it. But I know it's a big ask, I was just wondering if
it's an easy thing to do.

Posted: Fri Mar 27, 2009 1:53 pm
by ThorstenD
@Hroudtwolf
Many thanks for the fast help. Functions like it has to do. :D Thank you also to the other. Have a nice day and up to next... Greetings Thorsten