Audio
view release on metacpan or search on metacpan
Data/Data.xs view on Meta::CPAN
Audio * au
PPCODE:
{
int gimme = GIMME_V;
if (items > 1)
{
int i;
au->flags &= ~AUDIO_F_COMPLEX;
SvCUR(au->data) = 0;
for (i=1; i < items; i++)
{
Audio_append_sv(aTHX_ au,ST(i));
}
}
if (gimme == G_VOID)
{
XSRETURN(0);
}
else if (gimme == G_ARRAY)
{
STRLEN sz;
int count = 0;
float *p = (float *) SvPV(au->data,sz);
while (sz >= sizeof(float))
{
double d = *p++;
XPUSHs(sv_2mortal(newSVnv(d)));
sz -= sizeof(float);
count++;
}
XSRETURN(count);
}
else
{
XPUSHs(SvREFCNT_inc(au->data));
XSRETURN(1);
}
}
void
Audio_dB(au,start = 0, count = (GIMME == G_ARRAY) ? Audio_samples(au)-start : 1)
Audio * au
int start
int count
PPCODE:
{
int n = Audio_samples(au);
float *p = AUDIO_DATA(au)+start*AUDIO_WORDS(au);
/* Min noticable value in 16bit is 1/(2**15) - call that 100dB */
float min = 1.0/(1 << 15);
float dB0 = 10*log10(min);
if (start+count > n)
count = n - start;
if (AUDIO_COMPLEX(au))
{
for (n=0; n < count; n++)
{
float r = *p++;
float i = *p++;
r = sqrt(r*r+i*i);
/* hack to avoid log10(0) yielding NaN or fault */
if (r < min)
r = min;
XPUSHs(sv_2mortal(newSVnv(10*log10(r)-dB0)));
}
}
else
{
for (n=0; n < count; n++)
{
float r = *p++;
if (r < 0)
r = -r;
/* hack to avoid log10(0) yielding NaN or fault */
if (r < min)
r = min;
XPUSHs(sv_2mortal(newSVnv(10*log10(r)-dB0)));
}
}
XSRETURN(count);
}
void
Audio_amplitude(au,start = 0, count = (GIMME == G_ARRAY) ? Audio_samples(au)-start : 1)
Audio * au
int start
int count
PPCODE:
{
int n = Audio_samples(au);
float *p = AUDIO_DATA(au)+start*AUDIO_WORDS(au);
if (start+count > n)
count = n - start;
if (AUDIO_COMPLEX(au))
{
for (n=0; n < count; n++)
{
float r = *p++;
float i = *p++;
XPUSHs(sv_2mortal(newSVnv(sqrt(r*r+i*i))));
}
}
else
{
for (n=0; n < count; n++)
{
float r = *p++;
XPUSHs(sv_2mortal(newSVnv(r)));
}
}
XSRETURN(count);
}
void
Audio_phase(au,start = 0, count = (GIMME == G_ARRAY) ? Audio_samples(au)-start : 1)
Audio * au
int start
int count
PPCODE:
{
int n = Audio_samples(au);
float *p = AUDIO_DATA(au)+start*AUDIO_WORDS(au);
if (start+count > n)
count = n - start;
if (AUDIO_COMPLEX(au))
{
for (n=0; n < count; n++)
{
float r = *p++;
float i = *p++;
XPUSHs(sv_2mortal(newSVnv(atan2(i,r))));
}
}
else
( run in 0.877 second using v1.01-cache-2.11-cpan-39bf76dae61 )