No naked malloc (calloc, strup, ...) and free!

This commit is contained in:
Paul Licameli 2017-03-09 09:54:43 -05:00
commit a399d4e23a
47 changed files with 727 additions and 923 deletions

View File

@ -521,7 +521,7 @@ class GnomeShutdown
public:
GnomeShutdown()
{
mArgv[0] = strdup("Audacity");
mArgv[0].reset(strdup("Audacity"));
mGnomeui = dlopen("libgnomeui-2.so.0", RTLD_NOW);
if (!mGnomeui) {
@ -550,11 +550,11 @@ class GnomeShutdown
return;
}
gnome_program_init(mArgv[0],
gnome_program_init(mArgv[0].get(),
"1.0",
libgnomeui_module_info_get(),
1,
mArgv,
reinterpret_cast<char**>(mArgv),
NULL);
mClient = gnome_master_client();
@ -568,13 +568,11 @@ class GnomeShutdown
virtual ~GnomeShutdown()
{
// Do not dlclose() the libraries here lest you want segfaults...
free(mArgv[0]);
}
private:
char *mArgv[1];
MallocString<> mArgv[1];
void *mGnomeui;
void *mGnome;
GnomeClient *mClient;

View File

@ -113,8 +113,6 @@ void InitFFT()
void DeinitFFT()
{
gFFTBitTable.reset();
// Deallocate any unused RealFFTf tables
CleanupFFT();
}
static inline size_t FastReverseBits(size_t i, size_t NumBits)
@ -230,14 +228,14 @@ void FFT(size_t NumSamples,
void RealFFT(size_t NumSamples, const float *RealIn, float *RealOut, float *ImagOut)
{
HFFT hFFT = GetFFT(NumSamples);
auto hFFT = GetFFT(NumSamples);
Floats pFFT{ NumSamples };
// Copy the data into the processing buffer
for(size_t i = 0; i < NumSamples; i++)
pFFT[i] = RealIn[i];
// Perform the FFT
RealFFTf(pFFT.get(), hFFT);
RealFFTf(pFFT.get(), hFFT.get());
// Copy the data into the real and imaginary outputs
for (size_t i = 1; i<(NumSamples / 2); i++) {
@ -253,8 +251,6 @@ void RealFFT(size_t NumSamples, const float *RealIn, float *RealOut, float *Imag
RealOut[i] = RealOut[NumSamples-i];
ImagOut[i] = -ImagOut[NumSamples-i];
}
ReleaseFFT(hFFT);
}
/*
@ -271,7 +267,7 @@ void RealFFT(size_t NumSamples, const float *RealIn, float *RealOut, float *Imag
void InverseRealFFT(size_t NumSamples, const float *RealIn, const float *ImagIn,
float *RealOut)
{
HFFT hFFT = GetFFT(NumSamples);
auto hFFT = GetFFT(NumSamples);
Floats pFFT{ NumSamples };
// Copy the data into the processing buffer
for (size_t i = 0; i < (NumSamples / 2); i++)
@ -287,12 +283,10 @@ void InverseRealFFT(size_t NumSamples, const float *RealIn, const float *ImagIn,
pFFT[1] = RealIn[NumSamples / 2];
// Perform the FFT
InverseRealFFTf(pFFT.get(), hFFT);
InverseRealFFTf(pFFT.get(), hFFT.get());
// Copy the data to the (purely real) output buffer
ReorderToTime(hFFT, pFFT.get(), RealOut);
ReleaseFFT(hFFT);
ReorderToTime(hFFT.get(), pFFT.get(), RealOut);
}
/*
@ -308,14 +302,14 @@ void InverseRealFFT(size_t NumSamples, const float *RealIn, const float *ImagIn,
void PowerSpectrum(size_t NumSamples, const float *In, float *Out)
{
HFFT hFFT = GetFFT(NumSamples);
auto hFFT = GetFFT(NumSamples);
Floats pFFT{ NumSamples };
// Copy the data into the processing buffer
for (size_t i = 0; i<NumSamples; i++)
pFFT[i] = In[i];
// Perform the FFT
RealFFTf(pFFT.get(), hFFT);
RealFFTf(pFFT.get(), hFFT.get());
// Copy the data into the real and imaginary outputs
for (size_t i = 1; i<NumSamples / 2; i++) {
@ -325,7 +319,6 @@ void PowerSpectrum(size_t NumSamples, const float *In, float *Out)
// Handle the (real-only) DC and Fs/2 bins
Out[0] = pFFT[0]*pFFT[0];
Out[NumSamples / 2] = pFFT[1]*pFFT[1];
ReleaseFFT(hFFT);
}
/*

View File

@ -386,10 +386,10 @@ int import_ffmpeg_decode_frame(streamContext *sc, bool flushing)
}
sc->m_samplefmt = sc->m_codecCtx->sample_fmt;
sc->m_samplesize = av_get_bytes_per_sample(sc->m_samplefmt);
sc->m_samplesize = static_cast<size_t>(av_get_bytes_per_sample(sc->m_samplefmt));
int channels = sc->m_codecCtx->channels;
unsigned int newsize = sc->m_samplesize * frame->nb_samples * channels;
auto newsize = sc->m_samplesize * frame->nb_samples * channels;
sc->m_decodedAudioSamplesValidSiz = newsize;
// Reallocate the audio sample buffer if it's smaller than the frame size.
if (newsize > sc->m_decodedAudioSamplesSiz )

View File

@ -982,13 +982,13 @@ struct streamContext
int m_frameValid{}; // is m_decodedVideoFrame/m_decodedAudioSamples valid?
AVMallocHolder<uint8_t> m_decodedAudioSamples; // decoded audio samples stored here
unsigned int m_decodedAudioSamplesSiz{}; // current size of m_decodedAudioSamples
int m_decodedAudioSamplesValidSiz{}; // # valid bytes in m_decodedAudioSamples
size_t m_decodedAudioSamplesValidSiz{}; // # valid bytes in m_decodedAudioSamples
int m_initialchannels{}; // number of channels allocated when we begin the importing. Assumes that number of channels doesn't change on the fly.
int m_samplesize{}; // input sample size in bytes
size_t m_samplesize{}; // input sample size in bytes
AVSampleFormat m_samplefmt{ AV_SAMPLE_FMT_NONE }; // input sample format
int m_osamplesize{}; // output sample size in bytes
size_t m_osamplesize{}; // output sample size in bytes
sampleFormat m_osamplefmt{ floatSample }; // output sample format
streamContext() { memset(this, 0, sizeof(*this)); }

View File

@ -15,6 +15,8 @@ information.
*//*******************************************************************/
#include "Audacity.h"
#include "MemoryX.h"
#include <wx/arrstr.h>
#include <wx/intl.h>
#include "sndfile.h"
@ -119,7 +121,6 @@ wxString sf_header_name(int format)
wxString sf_header_shortname(int format)
{
SF_FORMAT_INFO format_info;
char *tmp;
int i;
wxString s;
@ -127,8 +128,7 @@ wxString sf_header_shortname(int format)
format_info.format = (format & SF_FORMAT_TYPEMASK);
sf_command(NULL, SFC_GET_FORMAT_INFO, &format_info, sizeof(format_info));
tmp = (char *)malloc(strlen(format_info.name)+1);
strcpy(tmp, format_info.name);
MallocString<> tmp { strdup( format_info.name ) };
i = 0;
while(tmp[i]) {
if (tmp[i]==' ')
@ -137,9 +137,7 @@ wxString sf_header_shortname(int format)
i++;
}
s = LAT1CTOWX(tmp);
free(tmp);
s = LAT1CTOWX(tmp.get());
return s;
}

View File

@ -37,11 +37,14 @@
*/
#include "Audacity.h"
#include <vector>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "Experimental.h"
#include <wx/thread.h>
#include "RealFFTf.h"
#ifdef EXPERIMENTAL_EQ_SSE_THREADED
#include "RealFFTf48x.h"
@ -58,13 +61,8 @@
HFFT InitializeFFT(size_t fftlen)
{
int temp;
HFFT h;
HFFT h{ safenew FFTParam };
if((h=(HFFT)malloc(sizeof(FFTParam)))==NULL)
{
fprintf(stderr,"Error allocating memory for FFT\n");
exit(8);
}
/*
* FFT size is only half the number of data points
* The full FFT output can be reconstructed from this FFT's output.
@ -72,17 +70,9 @@ HFFT InitializeFFT(size_t fftlen)
*/
h->Points = fftlen / 2;
if((h->SinTable=(fft_type *)malloc(2*h->Points*sizeof(fft_type)))==NULL)
{
fprintf(stderr,"Error allocating memory for Sine table.\n");
exit(8);
}
h->SinTable.reinit(2*h->Points);
if((h->BitReversed=(int *)malloc(h->Points*sizeof(int)))==NULL)
{
fprintf(stderr,"Error allocating memory for BitReversed.\n");
exit(8);
}
h->BitReversed.reinit(h->Points);
for(size_t i = 0; i < h->Points; i++)
{
@ -109,40 +99,33 @@ HFFT InitializeFFT(size_t fftlen)
return h;
}
/*
* Free up the memory allotted for Sin table and Twiddle Pointers
*/
void EndFFT(HFFT h)
{
if(h->Points > 0) {
free(h->BitReversed);
free(h->SinTable);
}
h->Points = 0;
free(h);
}
enum : size_t { MAX_HFFT = 10 };
static HFFT hFFTArray[MAX_HFFT] = { NULL };
static int nFFTLockCount[MAX_HFFT] = { 0 };
// Maintain a pool:
static std::vector< movable_ptr<FFTParam> > hFFTArray(MAX_HFFT);
wxCriticalSection getFFTMutex;
/* Get a handle to the FFT tables of the desired length */
/* This version keeps common tables rather than allocating a NEW table every time */
HFFT GetFFT(size_t fftlen)
{
// To do: smarter policy about when to retain in the pool and when to
// allocate a unique instance.
wxCriticalSectionLocker locker{ getFFTMutex };
size_t h = 0;
auto n = fftlen/2;
auto size = hFFTArray.size();
for(;
(h < MAX_HFFT) && (hFFTArray[h] != NULL) && (n != hFFTArray[h]->Points);
(h < size) && hFFTArray[h] && (n != hFFTArray[h]->Points);
h++)
;
if(h < MAX_HFFT) {
if(h < size) {
if(hFFTArray[h] == NULL) {
hFFTArray[h] = InitializeFFT(fftlen);
nFFTLockCount[h] = 0;
hFFTArray[h].reset( InitializeFFT(fftlen).release() );
}
nFFTLockCount[h]++;
return hFFTArray[h];
return HFFT{ hFFTArray[h].get() };
} else {
// All buffers used, so fall back to allocating a NEW set of tables
return InitializeFFT(fftlen);
@ -150,31 +133,21 @@ HFFT GetFFT(size_t fftlen)
}
/* Release a previously requested handle to the FFT tables */
void ReleaseFFT(HFFT hFFT)
void FFTDeleter::operator() (FFTParam *hFFT) const
{
int h;
for(h=0; (h<MAX_HFFT) && (hFFTArray[h] != hFFT); h++);
if(h<MAX_HFFT) {
nFFTLockCount[h]--;
} else {
EndFFT(hFFT);
}
}
wxCriticalSectionLocker locker{ getFFTMutex };
/* Deallocate any unused FFT tables */
void CleanupFFT()
{
int h;
for(h=0; (h<MAX_HFFT); h++) {
if((nFFTLockCount[h] <= 0) && (hFFTArray[h] != NULL)) {
EndFFT(hFFTArray[h]);
hFFTArray[h] = NULL;
}
}
auto it = hFFTArray.begin(), end = hFFTArray.end();
while (it != end && it->get() != hFFT)
++it;
if ( it != end )
;
else
delete hFFT;
}
/*
* Forward FFT routine. Must call InitializeFFT(fftlen) first!
* Forward FFT routine. Must call GetFFT(fftlen) first!
*
* Note: Output is BIT-REVERSED! so you must use the BitReversed to
* get legible output, (i.e. Real_i = buffer[ h->BitReversed[i] ]
@ -191,7 +164,7 @@ void CleanupFFT()
* values would be similar in amplitude to the input values, which is
* good when using fixed point arithmetic)
*/
void RealFFTf(fft_type *buffer,HFFT h)
void RealFFTf(fft_type *buffer, const FFTParam *h)
{
fft_type *A,*B;
const fft_type *sptr;
@ -216,7 +189,7 @@ void RealFFTf(fft_type *buffer,HFFT h)
{
A = buffer;
B = buffer + ButterfliesPerGroup * 2;
sptr = h->SinTable;
sptr = h->SinTable.get();
while(A < endptr1)
{
@ -239,8 +212,8 @@ void RealFFTf(fft_type *buffer,HFFT h)
ButterfliesPerGroup >>= 1;
}
/* Massage output to get the output for a real input sequence. */
br1 = h->BitReversed + 1;
br2 = h->BitReversed + h->Points - 1;
br1 = h->BitReversed.get() + 1;
br2 = h->BitReversed.get() + h->Points - 1;
while(br1<br2)
{
@ -281,7 +254,7 @@ void RealFFTf(fft_type *buffer,HFFT h)
* get legible output, (i.e. wave[2*i] = buffer[ BitReversed[i] ]
* wave[2*i+1] = buffer[ BitReversed[i]+1 ] )
* Input is in normal order, interleaved (real,imaginary) complex data
* You must call InitializeFFT(fftlen) first to initialize some buffers!
* You must call GetFFT(fftlen) first to initialize some buffers!
*
* Input buffer[0] is the DC bin, and input buffer[1] is the Fs/2 bin
* - this can be done because both values will always be real only
@ -293,7 +266,7 @@ void RealFFTf(fft_type *buffer,HFFT h)
* values would be similar in amplitude to the input values, which is
* good when using fixed point arithmetic)
*/
void InverseRealFFTf(fft_type *buffer,HFFT h)
void InverseRealFFTf(fft_type *buffer, const FFTParam *h)
{
fft_type *A,*B;
const fft_type *sptr;
@ -307,7 +280,7 @@ void InverseRealFFTf(fft_type *buffer,HFFT h)
/* Massage input to get the input for a real output sequence. */
A = buffer + 2;
B = buffer + h->Points * 2 - 2;
br1 = h->BitReversed + 1;
br1 = h->BitReversed.get() + 1;
while(A<B)
{
sin=h->SinTable[*br1];
@ -353,7 +326,7 @@ void InverseRealFFTf(fft_type *buffer,HFFT h)
{
A = buffer;
B = buffer + ButterfliesPerGroup * 2;
sptr = h->SinTable;
sptr = h->SinTable.get();
while(A < endptr1)
{
@ -376,7 +349,7 @@ void InverseRealFFTf(fft_type *buffer,HFFT h)
}
}
void ReorderToFreq(HFFT hFFT, const fft_type *buffer,
void ReorderToFreq(const FFTParam *hFFT, const fft_type *buffer,
fft_type *RealOut, fft_type *ImagOut)
{
// Copy the data into the real and imaginary outputs
@ -390,7 +363,7 @@ void ReorderToFreq(HFFT hFFT, const fft_type *buffer,
ImagOut[hFFT->Points] = 0;
}
void ReorderToTime(HFFT hFFT, const fft_type *buffer, fft_type *TimeOut)
void ReorderToTime(const FFTParam *hFFT, const fft_type *buffer, fft_type *TimeOut)
{
// Copy the data into the real outputs
for(size_t i = 0; i < hFFT->Points; i++) {

View File

@ -1,28 +1,33 @@
#ifndef __realfftf_h
#define __realfftf_h
#include "Audacity.h"
#include "Experimental.h"
#include "MemoryX.h"
#define fft_type float
using fft_type = float;
struct FFTParam {
int *BitReversed;
fft_type *SinTable;
ArrayOf<int> BitReversed;
ArrayOf<fft_type> SinTable;
size_t Points;
#ifdef EXPERIMENTAL_EQ_SSE_THREADED
int pow2Bits;
#endif
};
typedef FFTParam * HFFT;
HFFT InitializeFFT(size_t);
void EndFFT(HFFT);
struct FFTDeleter{
void operator () (FFTParam *p) const;
};
using HFFT = std::unique_ptr<
FFTParam, FFTDeleter
>;
HFFT GetFFT(size_t);
void ReleaseFFT(HFFT);
void CleanupFFT();
void RealFFTf(fft_type *,HFFT);
void InverseRealFFTf(fft_type *,HFFT);
void ReorderToTime(HFFT hFFT, const fft_type *buffer, fft_type *TimeOut);
void ReorderToFreq(HFFT hFFT, const fft_type *buffer,
void RealFFTf(fft_type *, const FFTParam *);
void InverseRealFFTf(fft_type *, const FFTParam *);
void ReorderToTime(const FFTParam *hFFT, const fft_type *buffer, fft_type *TimeOut);
void ReorderToFreq(const FFTParam *hFFT, const fft_type *buffer,
fft_type *RealOut, fft_type *ImagOut);
#endif

View File

@ -34,6 +34,8 @@
* and BitReversed tables so they don't need to be reallocated
* and recomputed on every call.
* - Added Reorder* functions to undo the bit-reversal
* Modified 15 April 2016 Paul Licameli
* - C++11 smart pointers
*
* Copyright (C) 2009 Philip VanBaren
*
@ -146,7 +148,7 @@ int SmallRB(int bits, int numberBits)
};
/* wrapper funcitons. If passed -1 function choice will be made locally */
void RealFFTf1x(fft_type *buffer, HFFT h, int functionType)
void RealFFTf1x(fft_type *buffer, FFTParam *h, int functionType)
{
switch(functionType) {
case FFT_SinCosTableVBR16:
@ -167,7 +169,7 @@ void RealFFTf1x(fft_type *buffer, HFFT h, int functionType)
};
}
void InverseRealFFTf1x(fft_type *buffer, HFFT h, int functionType)
void InverseRealFFTf1x(fft_type *buffer, FFTParam *h, int functionType)
{
switch(functionType) {
case FFT_SinCosTableVBR16:
@ -188,7 +190,7 @@ void InverseRealFFTf1x(fft_type *buffer, HFFT h, int functionType)
};
}
void ReorderToTime1x(HFFT hFFT, fft_type *buffer, fft_type *TimeOut, int functionType)
void ReorderToTime1x(FFTParam *hFFT, fft_type *buffer, fft_type *TimeOut, int functionType)
{
switch(functionType) {
case FFT_SinCosTableVBR16:
@ -209,7 +211,7 @@ void ReorderToTime1x(HFFT hFFT, fft_type *buffer, fft_type *TimeOut, int functio
};
}
void ReorderToFreq1x(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut, int functionType)
void ReorderToFreq1x(FFTParam *hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut, int functionType)
{
switch(functionType) {
case FFT_SinCosTableVBR16:
@ -230,7 +232,7 @@ void ReorderToFreq1x(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *I
};
}
void RealFFTf4x( fft_type *buffer, HFFT h, int functionType)
void RealFFTf4x( fft_type *buffer, FFTParam *h, int functionType)
{
switch(functionType) {
case FFT_SinCosTableVBR16:
@ -251,7 +253,7 @@ void RealFFTf4x( fft_type *buffer, HFFT h, int functionType)
};
}
void InverseRealFFTf4x( fft_type *buffer, HFFT h, int functionType)
void InverseRealFFTf4x( fft_type *buffer, FFTParam *h, int functionType)
{
switch(functionType) {
case FFT_SinCosTableVBR16:
@ -272,7 +274,7 @@ void InverseRealFFTf4x( fft_type *buffer, HFFT h, int functionType)
};
}
void ReorderToTime4x(HFFT hFFT, fft_type *buffer, fft_type *TimeOut, int functionType)
void ReorderToTime4x(FFTParam *hFFT, fft_type *buffer, fft_type *TimeOut, int functionType)
{
switch(functionType) {
case FFT_SinCosTableVBR16:
@ -293,7 +295,7 @@ void ReorderToTime4x(HFFT hFFT, fft_type *buffer, fft_type *TimeOut, int functio
};
}
void ReorderToFreq4x(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut, int functionType)
void ReorderToFreq4x(FFTParam *hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut, int functionType)
{
switch(functionType) {
case FFT_SinCosTableVBR16:
@ -318,7 +320,7 @@ void ReorderToFreq4x(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *I
#ifdef REAL_SINCOSBRTABLE
/*
* Forward FFT routine. Must call InitializeFFT(fftlen) first!
* Forward FFT routine. Must call GetFFT(fftlen) first!
*
* Note: Output is BIT-REVERSED! so you must use the BitReversed to
* get legible output, (i.e. Real_i = buffer[ h->BitReversed[i] ]
@ -335,7 +337,7 @@ void ReorderToFreq4x(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *I
* values would be similar in amplitude to the input values, which is
* good when using fixed point arithmetic)
*/
void RealFFTf1xSinCosBRTable(fft_type *buffer,HFFT h)
void RealFFTf1xSinCosBRTable(fft_type *buffer, FFTParam *h)
{
fft_type *A,*B;
fft_type *sptr;
@ -360,7 +362,7 @@ void RealFFTf1xSinCosBRTable(fft_type *buffer,HFFT h)
{
A = buffer;
B = buffer + ButterfliesPerGroup * 2;
sptr = h->SinTable;
sptr = h->SinTable.get();
while(A < endptr1)
{
@ -383,8 +385,8 @@ void RealFFTf1xSinCosBRTable(fft_type *buffer,HFFT h)
ButterfliesPerGroup >>= 1;
}
/* Massage output to get the output for a real input sequence. */
br1 = h->BitReversed + 1;
br2 = h->BitReversed + h->Points - 1;
br1 = h->BitReversed.get() + 1;
br2 = h->BitReversed.get() + h->Points - 1;
while(br1 < br2)
{
@ -425,7 +427,7 @@ void RealFFTf1xSinCosBRTable(fft_type *buffer,HFFT h)
* get legible output, (i.e. wave[2*i] = buffer[ BitReversed[i] ]
* wave[2*i+1] = buffer[ BitReversed[i]+1 ] )
* Input is in normal order, interleaved (real,imaginary) complex data
* You must call InitializeFFT(fftlen) first to initialize some buffers!
* You must call GetFFT(fftlen) first to initialize some buffers!
*
* Input buffer[0] is the DC bin, and input buffer[1] is the Fs/2 bin
* - this can be done because both values will always be real only
@ -437,7 +439,7 @@ void RealFFTf1xSinCosBRTable(fft_type *buffer,HFFT h)
* values would be similar in amplitude to the input values, which is
* good when using fixed point arithmetic)
*/
void InverseRealFFTf1xSinCosBRTable(fft_type *buffer,HFFT h)
void InverseRealFFTf1xSinCosBRTable(fft_type *buffer, FFTParam *h)
{
fft_type *A,*B;
fft_type *sptr;
@ -451,7 +453,7 @@ void InverseRealFFTf1xSinCosBRTable(fft_type *buffer,HFFT h)
/* Massage input to get the input for a real output sequence. */
A = buffer + 2;
B = buffer + h->Points * 2 - 2;
br1 = h->BitReversed + 1;
br1 = h->BitReversed.get() + 1;
while(A < B)
{
sin=h->SinTable[*br1];
@ -497,7 +499,7 @@ void InverseRealFFTf1xSinCosBRTable(fft_type *buffer,HFFT h)
{
A = buffer;
B = buffer + ButterfliesPerGroup * 2;
sptr = h->SinTable;
sptr = h->SinTable.get();
while(A < endptr1)
{
@ -520,7 +522,7 @@ void InverseRealFFTf1xSinCosBRTable(fft_type *buffer,HFFT h)
}
}
void ReorderToFreq1xSinCosBRTable(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut)
void ReorderToFreq1xSinCosBRTable(FFTParam *hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut)
{
// Copy the data into the real and imaginary outputs
for(size_t i = 1; i < hFFT->Points; i++) {
@ -533,7 +535,7 @@ void ReorderToFreq1xSinCosBRTable(HFFT hFFT, fft_type *buffer, fft_type *RealOut
ImagOut[hFFT->Points] = 0;
}
void ReorderToTime1xSinCosBRTable(HFFT hFFT, fft_type *buffer, fft_type *TimeOut)
void ReorderToTime1xSinCosBRTable(FFTParam *hFFT, fft_type *buffer, fft_type *TimeOut)
{
// Copy the data into the real outputs
for(size_t i = 0; i < hFFT->Points; i++) {
@ -543,7 +545,7 @@ void ReorderToTime1xSinCosBRTable(HFFT hFFT, fft_type *buffer, fft_type *TimeOut
}
// 4x processing simd
void RealFFTf4xSinCosBRTable(fft_type *buffer,HFFT h)
void RealFFTf4xSinCosBRTable(fft_type *buffer, FFTParam *h)
{
__m128 *localBuffer=(__m128 *)buffer;
@ -571,7 +573,7 @@ void RealFFTf4xSinCosBRTable(fft_type *buffer,HFFT h)
{
A = localBuffer;
B = &localBuffer[ButterfliesPerGroup * 2];
sptr = h->SinTable;
sptr = h->SinTable.get();
while(A < endptr1)
{
sin = _mm_set1_ps(*(sptr++));
@ -637,7 +639,7 @@ void RealFFTf4xSinCosBRTable(fft_type *buffer,HFFT h)
* get legible output, (i.e. wave[2*i] = buffer[ BitReversed[i] ]
* wave[2*i+1] = buffer[ BitReversed[i]+1 ] )
* Input is in normal order, interleaved (real,imaginary) complex data
* You must call InitializeFFT(fftlen) first to initialize some buffers!
* You must call GetFFT(fftlen) first to initialize some buffers!
*
* Input buffer[0] is the DC bin, and input buffer[1] is the Fs/2 bin
* - this can be done because both values will always be real only
@ -649,7 +651,7 @@ void RealFFTf4xSinCosBRTable(fft_type *buffer,HFFT h)
* values would be similar in amplitude to the input values, which is
* good when using fixed point arithmetic)
*/
void InverseRealFFTf4xSinCosBRTable(fft_type *buffer,HFFT h)
void InverseRealFFTf4xSinCosBRTable(fft_type *buffer, FFTParam *h)
{
__m128 *localBuffer=(__m128 *)buffer;
@ -717,7 +719,7 @@ void InverseRealFFTf4xSinCosBRTable(fft_type *buffer,HFFT h)
{
A = localBuffer;
B = localBuffer + ButterfliesPerGroup * 2;
sptr = h->SinTable;
sptr = h->SinTable.get();
while(A < endptr1)
{
sin = _mm_set1_ps(*(sptr++));
@ -739,7 +741,7 @@ void InverseRealFFTf4xSinCosBRTable(fft_type *buffer,HFFT h)
}
}
void ReorderToFreq4xSinCosBRTable(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut)
void ReorderToFreq4xSinCosBRTable(FFTParam *hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut)
{
__m128 *localBuffer=(__m128 *)buffer;
__m128 *localRealOut=(__m128 *)RealOut;
@ -758,7 +760,7 @@ void ReorderToFreq4xSinCosBRTable(HFFT hFFT, fft_type *buffer, fft_type *RealOut
localImagOut[hFFT->Points] = _mm_set1_ps(0.0);
}
void ReorderToTime4xSinCosBRTable(HFFT hFFT, fft_type *buffer, fft_type *TimeOut)
void ReorderToTime4xSinCosBRTable(FFTParam *hFFT, fft_type *buffer, fft_type *TimeOut)
{
__m128 *localBuffer=(__m128 *)buffer;
__m128 *localTimeOut=(__m128 *)TimeOut;
@ -777,7 +779,7 @@ void ReorderToTime4xSinCosBRTable(HFFT hFFT, fft_type *buffer, fft_type *TimeOut
#ifdef REAL_SINCOSTABLE_VBR16
/*
* Forward FFT routine. Must call InitializeFFT(fftlen) first!
* Forward FFT routine. Must call GetFFT(fftlen) first!
*
* Note: Output is BIT-REVERSED! so you must use the BitReversed to
* get legible output, (i.e. Real_i = buffer[ h->BitReversed[i] ]
@ -794,7 +796,7 @@ void ReorderToTime4xSinCosBRTable(HFFT hFFT, fft_type *buffer, fft_type *TimeOut
* values would be similar in amplitude to the input values, which is
* good when using fixed point arithmetic)
*/
void RealFFTf1xSinCosTableVBR16(fft_type *buffer,HFFT h)
void RealFFTf1xSinCosTableVBR16(fft_type *buffer, FFTParam *h)
{
fft_type *A,*B;
fft_type *endptr1,*endptr2;
@ -880,7 +882,7 @@ void RealFFTf1xSinCosTableVBR16(fft_type *buffer,HFFT h)
* get legible output, (i.e. wave[2*i] = buffer[ BitReversed[i] ]
* wave[2*i+1] = buffer[ BitReversed[i]+1 ] )
* Input is in normal order, interleaved (real,imaginary) complex data
* You must call InitializeFFT(fftlen) first to initialize some buffers!
* You must call GetFFT(fftlen) first to initialize some buffers!
*
* Input buffer[0] is the DC bin, and input buffer[1] is the Fs/2 bin
* - this can be done because both values will always be real only
@ -892,7 +894,7 @@ void RealFFTf1xSinCosTableVBR16(fft_type *buffer,HFFT h)
* values would be similar in amplitude to the input values, which is
* good when using fixed point arithmetic)
*/
void InverseRealFFTf1xSinCosTableVBR16(fft_type *buffer,HFFT h)
void InverseRealFFTf1xSinCosTableVBR16(fft_type *buffer, FFTParam *h)
{
fft_type *A,*B;
fft_type *endptr1,*endptr2;
@ -907,7 +909,7 @@ void InverseRealFFTf1xSinCosTableVBR16(fft_type *buffer,HFFT h)
/* Massage input to get the input for a real output sequence. */
A = buffer + 2;
B = buffer + h->Points * 2 - 2;
br1 = h->BitReversed + 1;
br1 = h->BitReversed.get() + 1;
br1Index = 1; //h->BitReversed + 1;
while(A < B)
{
@ -980,7 +982,7 @@ void InverseRealFFTf1xSinCosTableVBR16(fft_type *buffer,HFFT h)
}
}
void ReorderToTime1xSinCosTableVBR16(HFFT hFFT, fft_type *buffer, fft_type *TimeOut)
void ReorderToTime1xSinCosTableVBR16(FFTParam *hFFT, fft_type *buffer, fft_type *TimeOut)
{
// Copy the data into the real outputs
for(size_t i = 0;i < hFFT->Points; i++) {
@ -991,7 +993,7 @@ void ReorderToTime1xSinCosTableVBR16(HFFT hFFT, fft_type *buffer, fft_type *Time
}
}
void ReorderToFreq1xSinCosTableVBR16(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut)
void ReorderToFreq1xSinCosTableVBR16(FFTParam *hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut)
{
// Copy the data into the real and imaginary outputs
for(size_t i = 1; i < hFFT->Points; i++) {
@ -1007,7 +1009,7 @@ void ReorderToFreq1xSinCosTableVBR16(HFFT hFFT, fft_type *buffer, fft_type *Real
}
// 4x processing simd
void RealFFTf4xSinCosTableVBR16(fft_type *buffer,HFFT h)
void RealFFTf4xSinCosTableVBR16(fft_type *buffer, FFTParam *h)
{
__m128 *localBuffer=(__m128 *)buffer;
@ -1105,7 +1107,7 @@ void RealFFTf4xSinCosTableVBR16(fft_type *buffer,HFFT h)
* get legible output, (i.e. wave[2*i] = buffer[ BitReversed[i] ]
* wave[2*i+1] = buffer[ BitReversed[i]+1 ] )
* Input is in normal order, interleaved (real,imaginary) complex data
* You must call InitializeFFT(fftlen) first to initialize some buffers!
* You must call GetFFT(fftlen) first to initialize some buffers!
*
* Input buffer[0] is the DC bin, and input buffer[1] is the Fs/2 bin
* - this can be done because both values will always be real only
@ -1117,7 +1119,7 @@ void RealFFTf4xSinCosTableVBR16(fft_type *buffer,HFFT h)
* values would be similar in amplitude to the input values, which is
* good when using fixed point arithmetic)
*/
void InverseRealFFTf4xSinCosTableVBR16(fft_type *buffer,HFFT h)
void InverseRealFFTf4xSinCosTableVBR16(fft_type *buffer, FFTParam *h)
{
__m128 *localBuffer=(__m128 *)buffer;
@ -1210,7 +1212,7 @@ void InverseRealFFTf4xSinCosTableVBR16(fft_type *buffer,HFFT h)
}
}
void ReorderToTime4xSinCosTableVBR16(HFFT hFFT, fft_type *buffer, fft_type *TimeOut)
void ReorderToTime4xSinCosTableVBR16(FFTParam *hFFT, fft_type *buffer, fft_type *TimeOut)
{
__m128 *localBuffer = (__m128 *)buffer;
__m128 *localTimeOut = (__m128 *)TimeOut;
@ -1223,7 +1225,7 @@ void ReorderToTime4xSinCosTableVBR16(HFFT hFFT, fft_type *buffer, fft_type *Time
}
}
void ReorderToFreq4xSinCosTableVBR16(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut)
void ReorderToFreq4xSinCosTableVBR16(FFTParam *hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut)
{
__m128 *localBuffer = (__m128 *)buffer;
__m128 *localRealOut = (__m128 *)RealOut;
@ -1247,7 +1249,7 @@ void ReorderToFreq4xSinCosTableVBR16(HFFT hFFT, fft_type *buffer, fft_type *Real
#ifdef REAL_SINCOSTABLE_BR16
/*
* Forward FFT routine. Must call InitializeFFT(fftlen) first!
* Forward FFT routine. Must call GetFFT(fftlen) first!
*
* Note: Output is BIT-REVERSED! so you must use the BitReversed to
* get legible output, (i.e. Real_i = buffer[ h->BitReversed[i] ]
@ -1264,7 +1266,7 @@ void ReorderToFreq4xSinCosTableVBR16(HFFT hFFT, fft_type *buffer, fft_type *Real
* values would be similar in amplitude to the input values, which is
* good when using fixed point arithmetic)
*/
void RealFFTf1xSinCosTableBR16(fft_type *buffer,HFFT h)
void RealFFTf1xSinCosTableBR16(fft_type *buffer, FFTParam *h)
{
fft_type *A,*B;
fft_type *endptr1, *endptr2;
@ -1354,7 +1356,7 @@ void RealFFTf1xSinCosTableBR16(fft_type *buffer,HFFT h)
* get legible output, (i.e. wave[2*i] = buffer[ BitReversed[i] ]
* wave[2*i+1] = buffer[ BitReversed[i]+1 ] )
* Input is in normal order, interleaved (real,imaginary) complex data
* You must call InitializeFFT(fftlen) first to initialize some buffers!
* You must call GetFFT(fftlen) first to initialize some buffers!
*
* Input buffer[0] is the DC bin, and input buffer[1] is the Fs/2 bin
* - this can be done because both values will always be real only
@ -1366,7 +1368,7 @@ void RealFFTf1xSinCosTableBR16(fft_type *buffer,HFFT h)
* values would be similar in amplitude to the input values, which is
* good when using fixed point arithmetic)
*/
void InverseRealFFTf1xSinCosTableBR16(fft_type *buffer,HFFT h)
void InverseRealFFTf1xSinCosTableBR16(fft_type *buffer, FFTParam *h)
{
fft_type *A,*B;
fft_type *endptr1,*endptr2;
@ -1453,7 +1455,7 @@ void InverseRealFFTf1xSinCosTableBR16(fft_type *buffer,HFFT h)
}
}
void ReorderToFreq1xSinCosTableBR16(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut)
void ReorderToFreq1xSinCosTableBR16(FFTParam *hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut)
{
int bitReverseShift=16-hFFT->pow2Bits;
// Copy the data into the real and imaginary outputs
@ -1470,7 +1472,7 @@ void ReorderToFreq1xSinCosTableBR16(HFFT hFFT, fft_type *buffer, fft_type *RealO
ImagOut[hFFT->Points] = 0;
}
void ReorderToTime1xSinCosTableBR16(HFFT hFFT, fft_type *buffer, fft_type *TimeOut)
void ReorderToTime1xSinCosTableBR16(FFTParam *hFFT, fft_type *buffer, fft_type *TimeOut)
{
int bitReverseShift=16-hFFT->pow2Bits;
// Copy the data into the real outputs
@ -1484,7 +1486,7 @@ void ReorderToTime1xSinCosTableBR16(HFFT hFFT, fft_type *buffer, fft_type *TimeO
}
// 4x processing simd
void RealFFTf4xSinCosTableBR16(fft_type *buffer,HFFT h)
void RealFFTf4xSinCosTableBR16(fft_type *buffer, FFTParam *h)
{
__m128 *localBuffer=(__m128 *)buffer;
@ -1586,7 +1588,7 @@ void RealFFTf4xSinCosTableBR16(fft_type *buffer,HFFT h)
* get legible output, (i.e. wave[2*i] = buffer[ BitReversed[i] ]
* wave[2*i+1] = buffer[ BitReversed[i]+1 ] )
* Input is in normal order, interleaved (real,imaginary) complex data
* You must call InitializeFFT(fftlen) first to initialize some buffers!
* You must call GetFFT(fftlen) first to initialize some buffers!
*
* Input buffer[0] is the DC bin, and input buffer[1] is the Fs/2 bin
* - this can be done because both values will always be real only
@ -1598,7 +1600,7 @@ void RealFFTf4xSinCosTableBR16(fft_type *buffer,HFFT h)
* values would be similar in amplitude to the input values, which is
* good when using fixed point arithmetic)
*/
void InverseRealFFTf4xSinCosTableBR16(fft_type *buffer,HFFT h)
void InverseRealFFTf4xSinCosTableBR16(fft_type *buffer, FFTParam *h)
{
__m128 *localBuffer=(__m128 *)buffer;
@ -1692,7 +1694,7 @@ void InverseRealFFTf4xSinCosTableBR16(fft_type *buffer,HFFT h)
}
}
void ReorderToTime4xSinCosTableBR16(HFFT hFFT, fft_type *buffer, fft_type *TimeOut)
void ReorderToTime4xSinCosTableBR16(FFTParam *hFFT, fft_type *buffer, fft_type *TimeOut)
{
__m128 *localBuffer = (__m128 *)buffer;
__m128 *localTimeOut = (__m128 *)TimeOut;
@ -1708,7 +1710,7 @@ void ReorderToTime4xSinCosTableBR16(HFFT hFFT, fft_type *buffer, fft_type *TimeO
}
}
void ReorderToFreq4xSinCosTableBR16(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut)
void ReorderToFreq4xSinCosTableBR16(FFTParam *hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut)
{
__m128 *localBuffer = (__m128 *)buffer;
__m128 *localRealOut = (__m128 *)RealOut;
@ -1734,7 +1736,7 @@ void ReorderToFreq4xSinCosTableBR16(HFFT hFFT, fft_type *buffer, fft_type *RealO
#ifdef FAST_MATH_BR24
/*
* Forward FFT routine. Must call InitializeFFT(fftlen) first!
* Forward FFT routine. Must call GetFFT(fftlen) first!
*
* Note: Output is BIT-REVERSED! so you must use the BitReversed to
* get legible output, (i.e. Real_i = buffer[ h->BitReversed[i] ]
@ -1751,7 +1753,7 @@ void ReorderToFreq4xSinCosTableBR16(HFFT hFFT, fft_type *buffer, fft_type *RealO
* values would be similar in amplitude to the input values, which is
* good when using fixed point arithmetic)
*/
void RealFFTf1xFastMathBR24(fft_type *buffer,HFFT h)
void RealFFTf1xFastMathBR24(fft_type *buffer, FFTParam *h)
{
fft_type *A, *B;
fft_type *endptr1, *endptr2;
@ -1886,7 +1888,7 @@ void RealFFTf1xFastMathBR24(fft_type *buffer,HFFT h)
* get legible output, (i.e. wave[2*i] = buffer[ BitReversed[i] ]
* wave[2*i+1] = buffer[ BitReversed[i]+1 ] )
* Input is in normal order, interleaved (real,imaginary) complex data
* You must call InitializeFFT(fftlen) first to initialize some buffers!
* You must call GetFFT(fftlen) first to initialize some buffers!
*
* Input buffer[0] is the DC bin, and input buffer[1] is the Fs/2 bin
* - this can be done because both values will always be real only
@ -1898,7 +1900,7 @@ void RealFFTf1xFastMathBR24(fft_type *buffer,HFFT h)
* values would be similar in amplitude to the input values, which is
* good when using fixed point arithmetic)
*/
void InverseRealFFTf1xFastMathBR24(fft_type *buffer,HFFT h)
void InverseRealFFTf1xFastMathBR24(fft_type *buffer, FFTParam *h)
{
fft_type *A,*B;
fft_type *endptr1,*endptr2;
@ -2019,7 +2021,7 @@ void InverseRealFFTf1xFastMathBR24(fft_type *buffer,HFFT h)
}
}
void ReorderToFreq1xFastMathBR24(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut)
void ReorderToFreq1xFastMathBR24(FFTParam *hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut)
{
int bitReverseShift = 24 - hFFT->pow2Bits;
// Copy the data into the real and imaginary outputs
@ -2037,7 +2039,7 @@ void ReorderToFreq1xFastMathBR24(HFFT hFFT, fft_type *buffer, fft_type *RealOut,
ImagOut[hFFT->Points] = 0;
}
void ReorderToTime1xFastMathBR24(HFFT hFFT, fft_type *buffer, fft_type *TimeOut)
void ReorderToTime1xFastMathBR24(FFTParam *hFFT, fft_type *buffer, fft_type *TimeOut)
{
int bitReverseShift = 24 - hFFT->pow2Bits;
// Copy the data into the real outputs
@ -2050,7 +2052,7 @@ void ReorderToTime1xFastMathBR24(HFFT hFFT, fft_type *buffer, fft_type *TimeOut)
}
}
void RealFFTf4xFastMathBR24(fft_type *buffer,HFFT h)
void RealFFTf4xFastMathBR24(fft_type *buffer, FFTParam *h)
{
__m128 *localBuffer=(__m128 *)buffer;
@ -2186,7 +2188,7 @@ void RealFFTf4xFastMathBR24(fft_type *buffer,HFFT h)
* get legible output, (i.e. wave[2*i] = buffer[ BitReversed[i] ]
* wave[2*i+1] = buffer[ BitReversed[i]+1 ] )
* Input is in normal order, interleaved (real,imaginary) complex data
* You must call InitializeFFT(fftlen) first to initialize some buffers!
* You must call GetFFT(fftlen) first to initialize some buffers!
*
* Input buffer[0] is the DC bin, and input buffer[1] is the Fs/2 bin
* - this can be done because both values will always be real only
@ -2198,7 +2200,7 @@ void RealFFTf4xFastMathBR24(fft_type *buffer,HFFT h)
* values would be similar in amplitude to the input values, which is
* good when using fixed point arithmetic)
*/
void InverseRealFFTf4xFastMathBR24(fft_type *buffer,HFFT h)
void InverseRealFFTf4xFastMathBR24(fft_type *buffer, FFTParam *h)
{
__m128 *localBuffer=(__m128 *)buffer;
@ -2325,7 +2327,7 @@ void InverseRealFFTf4xFastMathBR24(fft_type *buffer,HFFT h)
}
}
void ReorderToFreq4xFastMathBR24(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut)
void ReorderToFreq4xFastMathBR24(FFTParam *hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut)
{
__m128 *localBuffer = (__m128 *)buffer;
__m128 *localRealOut = (__m128 *)RealOut;
@ -2347,7 +2349,7 @@ void ReorderToFreq4xFastMathBR24(HFFT hFFT, fft_type *buffer, fft_type *RealOut,
localImagOut[hFFT->Points] = _mm_set1_ps(0.0);
}
void ReorderToTime4xFastMathBR24(HFFT hFFT, fft_type *buffer, fft_type *TimeOut)
void ReorderToTime4xFastMathBR24(FFTParam *hFFT, fft_type *buffer, fft_type *TimeOut)
{
__m128 *localBuffer = (__m128 *)buffer;
__m128 *localTimeOut = (__m128 *)TimeOut;
@ -2369,7 +2371,7 @@ void ReorderToTime4xFastMathBR24(HFFT hFFT, fft_type *buffer, fft_type *TimeOut)
#ifdef FAST_MATH_BR16
/*
* Forward FFT routine. Must call InitializeFFT(fftlen) first!
* Forward FFT routine. Must call GetFFT(fftlen) first!
*
* Note: Output is BIT-REVERSED! so you must use the BitReversed to
* get legible output, (i.e. Real_i = buffer[ h->BitReversed[i] ]
@ -2386,7 +2388,7 @@ void ReorderToTime4xFastMathBR24(HFFT hFFT, fft_type *buffer, fft_type *TimeOut)
* values would be similar in amplitude to the input values, which is
* good when using fixed point arithmetic)
*/
void RealFFTf1xFastMathBR16(fft_type *buffer,HFFT h)
void RealFFTf1xFastMathBR16(fft_type *buffer, FFTParam *h)
{
fft_type *A,*B;
fft_type *endptr1,*endptr2;
@ -2517,7 +2519,7 @@ void RealFFTf1xFastMathBR16(fft_type *buffer,HFFT h)
* get legible output, (i.e. wave[2*i] = buffer[ BitReversed[i] ]
* wave[2*i+1] = buffer[ BitReversed[i]+1 ] )
* Input is in normal order, interleaved (real,imaginary) complex data
* You must call InitializeFFT(fftlen) first to initialize some buffers!
* You must call GetFFT(fftlen) first to initialize some buffers!
*
* Input buffer[0] is the DC bin, and input buffer[1] is the Fs/2 bin
* - this can be done because both values will always be real only
@ -2529,7 +2531,7 @@ void RealFFTf1xFastMathBR16(fft_type *buffer,HFFT h)
* values would be similar in amplitude to the input values, which is
* good when using fixed point arithmetic)
*/
void InverseRealFFTf1xFastMathBR16(fft_type *buffer,HFFT h)
void InverseRealFFTf1xFastMathBR16(fft_type *buffer, FFTParam *h)
{
fft_type *A,*B;
fft_type *endptr1,*endptr2;
@ -2650,7 +2652,7 @@ void InverseRealFFTf1xFastMathBR16(fft_type *buffer,HFFT h)
}
}
void ReorderToFreq1xFastMathBR16(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut)
void ReorderToFreq1xFastMathBR16(FFTParam *hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut)
{
int bitReverseShift = 16 - hFFT->pow2Bits;
// Copy the data into the real and imaginary outputs
@ -2667,7 +2669,7 @@ void ReorderToFreq1xFastMathBR16(HFFT hFFT, fft_type *buffer, fft_type *RealOut,
ImagOut[hFFT->Points] = 0;
}
void ReorderToTime1xFastMathBR16(HFFT hFFT, fft_type *buffer, fft_type *TimeOut)
void ReorderToTime1xFastMathBR16(FFTParam *hFFT, fft_type *buffer, fft_type *TimeOut)
{
int bitReverseShift=16-hFFT->pow2Bits;
// Copy the data into the real outputs
@ -2680,7 +2682,7 @@ void ReorderToTime1xFastMathBR16(HFFT hFFT, fft_type *buffer, fft_type *TimeOut)
}
}
void RealFFTf4xFastMathBR16(fft_type *buffer,HFFT h)
void RealFFTf4xFastMathBR16(fft_type *buffer, FFTParam *h)
{
__m128 *localBuffer = (__m128 *)buffer;
@ -2816,7 +2818,7 @@ void RealFFTf4xFastMathBR16(fft_type *buffer,HFFT h)
* get legible output, (i.e. wave[2*i] = buffer[ BitReversed[i] ]
* wave[2*i+1] = buffer[ BitReversed[i]+1 ] )
* Input is in normal order, interleaved (real,imaginary) complex data
* You must call InitializeFFT(fftlen) first to initialize some buffers!
* You must call GetFFT(fftlen) first to initialize some buffers!
*
* Input buffer[0] is the DC bin, and input buffer[1] is the Fs/2 bin
* - this can be done because both values will always be real only
@ -2828,7 +2830,7 @@ void RealFFTf4xFastMathBR16(fft_type *buffer,HFFT h)
* values would be similar in amplitude to the input values, which is
* good when using fixed point arithmetic)
*/
void InverseRealFFTf4xFastMathBR16(fft_type *buffer,HFFT h)
void InverseRealFFTf4xFastMathBR16(fft_type *buffer, FFTParam *h)
{
__m128 *localBuffer=(__m128 *)buffer;
@ -2955,7 +2957,7 @@ void InverseRealFFTf4xFastMathBR16(fft_type *buffer,HFFT h)
}
}
void ReorderToFreq4xFastMathBR16(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut)
void ReorderToFreq4xFastMathBR16(FFTParam *hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut)
{
__m128 *localBuffer=(__m128 *)buffer;
__m128 *localRealOut=(__m128 *)RealOut;
@ -2977,7 +2979,7 @@ void ReorderToFreq4xFastMathBR16(HFFT hFFT, fft_type *buffer, fft_type *RealOut,
localImagOut[hFFT->Points] = _mm_set1_ps(0.0);
}
void ReorderToTime4xFastMathBR16(HFFT hFFT, fft_type *buffer, fft_type *TimeOut)
void ReorderToTime4xFastMathBR16(FFTParam *hFFT, fft_type *buffer, fft_type *TimeOut)
{
__m128 *localBuffer=(__m128 *)buffer;
__m128 *localTimeOut=(__m128 *)TimeOut;

View File

@ -16,64 +16,64 @@ enum {
};
/* wrapper funcitons. If passed -1 function choice will be made locally */
void RealFFTf1x(fft_type *,HFFT, int functionType=-1);
void InverseRealFFTf1x(fft_type *,HFFT, int functionType=-1);
void ReorderToTime1x(HFFT hFFT, fft_type *buffer, fft_type *TimeOut, int functionType=-1);
void ReorderToFreq1x(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut, int functionType=-1);
void RealFFTf4x(fft_type *,HFFT, int functionType=-1);
void InverseRealFFTf4x(fft_type *,HFFT, int functionType=-1);
void ReorderToTime4x(HFFT hFFT, fft_type *buffer, fft_type *TimeOut, int functionType=-1);
void ReorderToFreq4x(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut, int functionType=-1);
void RealFFTf1x(fft_type *, FFTParam*, int functionType=-1);
void InverseRealFFTf1x(fft_type *, FFTParam*, int functionType=-1);
void ReorderToTime1x(FFTParam *hFFT, fft_type *buffer, fft_type *TimeOut, int functionType=-1);
void ReorderToFreq1x(FFTParam *hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut, int functionType=-1);
void RealFFTf4x(fft_type *, FFTParam *, int functionType=-1);
void InverseRealFFTf4x(fft_type *, FFTParam *, int functionType=-1);
void ReorderToTime4x(FFTParam *hFFT, fft_type *buffer, fft_type *TimeOut, int functionType=-1);
void ReorderToFreq4x(FFTParam *hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut, int functionType=-1);
/* SinCosBRTable versions */
void RealFFTf1xSinCosBRTable(fft_type *,HFFT);
void InverseRealFFTf1xSinCosBRTable(fft_type *,HFFT);
void ReorderToTime1xSinCosBRTable(HFFT hFFT, fft_type *buffer, fft_type *TimeOut);
void ReorderToFreq1xSinCosBRTable(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut);
void RealFFTf4xSinCosBRTable(fft_type *,HFFT);
void InverseRealFFTf4xSinCosBRTable(fft_type *,HFFT);
void ReorderToTime4xSinCosBRTable(HFFT hFFT, fft_type *buffer, fft_type *TimeOut);
void ReorderToFreq4xSinCosBRTable(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut);
void RealFFTf1xSinCosBRTable(fft_type *, FFTParam*);
void InverseRealFFTf1xSinCosBRTable(fft_type *, FFTParam*);
void ReorderToTime1xSinCosBRTable(FFTParam *hFFT, fft_type *buffer, fft_type *TimeOut);
void ReorderToFreq1xSinCosBRTable(FFTParam *hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut);
void RealFFTf4xSinCosBRTable(fft_type *, FFTParam *);
void InverseRealFFTf4xSinCosBRTable(fft_type *, FFTParam *);
void ReorderToTime4xSinCosBRTable(FFTParam *hFFT, fft_type *buffer, fft_type *TimeOut);
void ReorderToFreq4xSinCosBRTable(FFTParam *hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut);
/* Fast Math BR16 versions */
void RealFFTf1xFastMathBR16(fft_type *,HFFT);
void InverseRealFFTf1xFastMathBR16(fft_type *,HFFT);
void ReorderToTime1xFastMathBR16(HFFT hFFT, fft_type *buffer, fft_type *TimeOut);
void ReorderToFreq1xFastMathBR16(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut);
void RealFFTf4xFastMathBR16(fft_type *,HFFT);
void InverseRealFFTf4xFastMathBR16(fft_type *,HFFT);
void ReorderToTime4xFastMathBR16(HFFT hFFT, fft_type *buffer, fft_type *TimeOut);
void ReorderToFreq4xFastMathBR16(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut);
void RealFFTf1xFastMathBR16(fft_type *, FFTParam*);
void InverseRealFFTf1xFastMathBR16(fft_type *, FFTParam*);
void ReorderToTime1xFastMathBR16(FFTParam *hFFT, fft_type *buffer, fft_type *TimeOut);
void ReorderToFreq1xFastMathBR16(FFTParam *hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut);
void RealFFTf4xFastMathBR16(fft_type *, FFTParam *);
void InverseRealFFTf4xFastMathBR16(fft_type *, FFTParam *);
void ReorderToTime4xFastMathBR16(FFTParam *hFFT, fft_type *buffer, fft_type *TimeOut);
void ReorderToFreq4xFastMathBR16(FFTParam *hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut);
/* Fast Math BR24 versions */
void RealFFTf1xFastMathBR24(fft_type *,HFFT);
void InverseRealFFTf1xFastMathBR24(fft_type *,HFFT);
void ReorderToTime1xFastMathBR24(HFFT hFFT, fft_type *buffer, fft_type *TimeOut);
void ReorderToFreq1xFastMathBR24(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut);
void RealFFTf4xFastMathBR24(fft_type *,HFFT);
void InverseRealFFTf4xFastMathBR24(fft_type *,HFFT);
void ReorderToTime4xFastMathBR24(HFFT hFFT, fft_type *buffer, fft_type *TimeOut);
void ReorderToFreq4xFastMathBR24(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut);
void RealFFTf1xFastMathBR24(fft_type *, FFTParam*);
void InverseRealFFTf1xFastMathBR24(fft_type *, FFTParam*);
void ReorderToTime1xFastMathBR24(FFTParam *hFFT, fft_type *buffer, fft_type *TimeOut);
void ReorderToFreq1xFastMathBR24(FFTParam *hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut);
void RealFFTf4xFastMathBR24(fft_type *, FFTParam *);
void InverseRealFFTf4xFastMathBR24(fft_type *, FFTParam *);
void ReorderToTime4xFastMathBR24(FFTParam *hFFT, fft_type *buffer, fft_type *TimeOut);
void ReorderToFreq4xFastMathBR24(FFTParam *hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut);
/* SinCosTable virtual BR versions */
void RealFFTf1xSinCosTableVBR16(fft_type *,HFFT);
void InverseRealFFTf1xSinCosTableVBR16(fft_type *,HFFT);
void ReorderToTime1xSinCosTableVBR16(HFFT hFFT, fft_type *buffer, fft_type *TimeOut);
void ReorderToFreq1xSinCosTableVBR16(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut);
void RealFFTf4xSinCosTableVBR16(fft_type *,HFFT);
void InverseRealFFTf4xSinCosTableVBR16(fft_type *,HFFT);
void ReorderToTime4xSinCosTableVBR16(HFFT hFFT, fft_type *buffer, fft_type *TimeOut);
void ReorderToFreq4xSinCosTableVBR16(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut);
void RealFFTf1xSinCosTableVBR16(fft_type *, FFTParam*);
void InverseRealFFTf1xSinCosTableVBR16(fft_type *, FFTParam*);
void ReorderToTime1xSinCosTableVBR16(FFTParam *hFFT, fft_type *buffer, fft_type *TimeOut);
void ReorderToFreq1xSinCosTableVBR16(FFTParam *hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut);
void RealFFTf4xSinCosTableVBR16(fft_type *, FFTParam *);
void InverseRealFFTf4xSinCosTableVBR16(fft_type *, FFTParam *);
void ReorderToTime4xSinCosTableVBR16(FFTParam *hFFT, fft_type *buffer, fft_type *TimeOut);
void ReorderToFreq4xSinCosTableVBR16(FFTParam *hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut);
/* SinCosTable BR16 versions */
void RealFFTf1xSinCosTableBR16(fft_type *,HFFT);
void InverseRealFFTf1xSinCosTableBR16(fft_type *,HFFT);
void ReorderToTime1xSinCosTableBR16(HFFT hFFT, fft_type *buffer, fft_type *TimeOut);
void ReorderToFreq1xSinCosTableBR16(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut);
void RealFFTf4xSinCosTableBR16(fft_type *,HFFT);
void InverseRealFFTf4xSinCosTableBR16(fft_type *,HFFT);
void ReorderToTime4xSinCosTableBR16(HFFT hFFT, fft_type *buffer, fft_type *TimeOut);
void ReorderToFreq4xSinCosTableBR16(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut);
void RealFFTf1xSinCosTableBR16(fft_type *, FFTParam*);
void InverseRealFFTf1xSinCosTableBR16(fft_type *, FFTParam*);
void ReorderToTime1xSinCosTableBR16(FFTParam *hFFT, fft_type *buffer, fft_type *TimeOut);
void ReorderToFreq1xSinCosTableBR16(FFTParam *hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut);
void RealFFTf4xSinCosTableBR16(fft_type *, FFTParam *);
void InverseRealFFTf4xSinCosTableBR16(fft_type *, FFTParam *);
void ReorderToTime4xSinCosTableBR16(FFTParam *hFFT, fft_type *buffer, fft_type *TimeOut);
void ReorderToFreq4xSinCosTableBR16(FFTParam *hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut);
void TableUsage(int iMask);

View File

@ -41,13 +41,11 @@ Resample::Resample(const bool useBestMethod, const double dMinFactor, const doub
mbWantConstRateResampling = false; // variable rate resampling
q_spec = soxr_quality_spec(SOXR_HQ, SOXR_VR);
}
mHandle = (void *)soxr_create(1, dMinFactor, 1, 0, 0, &q_spec, 0);
mHandle.reset(soxr_create(1, dMinFactor, 1, 0, 0, &q_spec, 0));
}
Resample::~Resample()
{
soxr_delete((soxr_t)mHandle);
mHandle = NULL;
}
int Resample::GetNumMethods() { return 4; }
@ -85,16 +83,16 @@ std::pair<size_t, size_t>
size_t idone, odone;
if (mbWantConstRateResampling)
{
soxr_process((soxr_t)mHandle,
soxr_process(mHandle.get(),
inBuffer , (lastFlag? ~inBufferLen : inBufferLen), &idone,
outBuffer, outBufferLen, &odone);
}
else
{
soxr_set_io_ratio((soxr_t)mHandle, 1/factor, 0);
soxr_set_io_ratio(mHandle.get(), 1/factor, 0);
inBufferLen = lastFlag? ~inBufferLen : inBufferLen;
soxr_process((soxr_t)mHandle,
soxr_process(mHandle.get(),
inBuffer , inBufferLen , &idone,
outBuffer, outBufferLen, &odone);
}

View File

@ -14,11 +14,19 @@
#include "Audacity.h"
#include "MemoryX.h"
#include <wx/intl.h>
#include <wx/string.h>
#include "SampleFormat.h"
struct soxr;
extern "C" void soxr_delete(soxr*);
struct soxr_deleter {
void operator () (soxr *p) const { if (p) soxr_delete(p); }
};
using soxrHandle = std::unique_ptr<soxr, soxr_deleter>;
class Resample final
{
public:
@ -78,7 +86,7 @@ class Resample final
protected:
int mMethod; // resampler-specific enum for resampling method
void* mHandle; // constant-rate or variable-rate resampler (XOR per instance)
soxrHandle mHandle; // constant-rate or variable-rate resampler (XOR per instance)
bool mbWantConstRateResampling;
};

View File

@ -74,16 +74,6 @@ const wxChar *GetSampleFormatStr(sampleFormat format)
return wxT("Unknown format"); // compiler food
}
AUDACITY_DLL_API samplePtr NewSamples(size_t count, sampleFormat format)
{
return (samplePtr)malloc(count * SAMPLE_SIZE(format));
}
AUDACITY_DLL_API void DeleteSamples(samplePtr p)
{
free(p);
}
// TODO: Risky? Assumes 0.0f is represented by 0x00000000;
void ClearSamples(samplePtr src, sampleFormat format,
size_t start, size_t len)

View File

@ -49,10 +49,6 @@ const wxChar *GetSampleFormatStr(sampleFormat format);
// Allocating/Freeing Samples
//
AUDACITY_DLL_API samplePtr NewSamples(size_t count, sampleFormat format);
AUDACITY_DLL_API void DeleteSamples(samplePtr p);
// RAII version of above
class SampleBuffer {
public:
@ -60,7 +56,7 @@ public:
: mPtr(0)
{}
SampleBuffer(size_t count, sampleFormat format)
: mPtr(NewSamples(count, format))
: mPtr((samplePtr)malloc(count * SAMPLE_SIZE(format)))
{}
~SampleBuffer()
{
@ -71,14 +67,14 @@ public:
SampleBuffer &Allocate(size_t count, sampleFormat format)
{
Free();
mPtr = NewSamples(count, format);
mPtr = (samplePtr)malloc(count * SAMPLE_SIZE(format));
return *this;
}
void Free()
{
DeleteSamples(mPtr);
free(mPtr);
mPtr = 0;
}

View File

@ -347,7 +347,9 @@ wxImage ThemeBase::MaskedImage( char const ** pXpm, char const ** pMask )
// unsigned char *src = Img1.GetData();
unsigned char *mk = Img2.GetData();
unsigned char *alpha = (unsigned char*)malloc( nBytes );
//wxImage::setAlpha requires memory allocated with malloc, not new
MallocString<unsigned char> alpha{
static_cast<unsigned char*>(malloc( nBytes )) };
// Extract alpha channel from second XPM.
for(i=0;i<nBytes;i++)
@ -356,7 +358,7 @@ wxImage ThemeBase::MaskedImage( char const ** pXpm, char const ** pMask )
mk+=3;
}
Img1.SetAlpha( alpha);
Img1.SetAlpha( alpha.release() );
//dmazzoni: the top line does not work on wxGTK
//wxBitmap Result( Img1, 32 );

View File

@ -273,7 +273,8 @@ protected:
};
static void ComputeSpectrumUsingRealFFTf
(float * __restrict buffer, HFFT hFFT, const float * __restrict window, size_t len, float * __restrict out)
(float * __restrict buffer, const FFTParam *hFFT,
const float * __restrict window, size_t len, float * __restrict out)
{
size_t i;
if(len > hFFT->Points * 2)
@ -924,7 +925,7 @@ bool SpecCache::CalculateOneSpectrum
}
else if (reassignment) {
static const double epsilon = 1e-16;
const HFFT hFFT = settings.hFFT;
const auto hFFT = settings.hFFT.get();
float *const scratch2 = scratch + fftLen;
std::copy(scratch, scratch2, scratch2);
@ -1024,7 +1025,7 @@ bool SpecCache::CalculateOneSpectrum
// This function mutates useBuffer
ComputeSpectrumUsingRealFFTf
(useBuffer, settings.hFFT, settings.window.get(), fftLen, results);
(useBuffer, settings.hFFT.get(), settings.window.get(), fftLen, results);
if (!gainFactors.empty()) {
// Apply a frequency-dependant gain factor
for (size_t ii = 0; ii < nBins; ++ii)
@ -1160,7 +1161,7 @@ void SpecCache::Populate
#endif
for (auto xx = lowerBoundX; xx < upperBoundX; ++xx) {
float *const results = &freq[nBins * xx];
const HFFT hFFT = settings.hFFT;
const auto hFFT = settings.hFFT.get();
for (size_t ii = 0; ii < nBins; ++ii) {
float &power = results[ii];
if (power <= 0)

View File

@ -220,7 +220,7 @@ EffectEqualization::EffectEqualization()
mCurve = NULL;
mPanel = NULL;
hFFT = InitializeFFT(windowSize);
hFFT = GetFFT(windowSize);
SetLinearEffectFlag(true);
@ -282,9 +282,6 @@ EffectEqualization::EffectEqualization()
EffectEqualization::~EffectEqualization()
{
if(hFFT)
EndFFT(hFFT);
hFFT = NULL;
}
// IdentInterface implementation
@ -1319,7 +1316,7 @@ void EffectEqualization::Filter(size_t len, float *buffer)
{
float re,im;
// Apply FFT
RealFFTf(buffer, hFFT);
RealFFTf(buffer, hFFT.get());
//FFT(len, false, inr, NULL, outr, outi);
// Apply filter
@ -1336,8 +1333,8 @@ void EffectEqualization::Filter(size_t len, float *buffer)
mFFTBuffer[1] = buffer[1] * mFilterFuncR[len/2];
// Inverse FFT and normalization
InverseRealFFTf(mFFTBuffer.get(), hFFT);
ReorderToTime(hFFT, mFFTBuffer.get(), buffer);
InverseRealFFTf(mFFTBuffer.get(), hFFT.get());
ReorderToTime(hFFT.get(), mFFTBuffer.get(), buffer);
}
//

View File

@ -158,7 +158,7 @@ void * malloc_simd(const size_t size)
#endif
}
void free_simd(void* mem)
void free_simd::operator() (void* mem) const
{
#if defined WIN32 // WIN32
_aligned_free(mem);
@ -169,7 +169,7 @@ void free_simd(void* mem)
EffectEqualization48x::EffectEqualization48x():
mThreadCount(0),mFilterSize(0),mWindowSize(0),mBlockSize(0),mWorkerDataCount(0),mBlocksPerBuffer(20),
mScratchBufferSize(0),mSubBufferSize(0),mBigBuffer(NULL),mThreaded(false),
mScratchBufferSize(0),mSubBufferSize(0),mThreaded(false),
mBenching(false),mBufferCount(0)
{
}
@ -211,7 +211,7 @@ bool EffectEqualization48x::AllocateBuffersWorkers(int nThreads)
mScratchBufferSize=mWindowSize*3*sizeof(float)*mBufferCount; // 3 window size blocks of instruction size
mSubBufferSize=mBlockSize*(mBufferCount*(mBlocksPerBuffer-1)); // we are going to do a full block overlap
mBigBuffer=(float *)malloc_simd(sizeof(float)*(mSubBufferSize+mFilterSize+mScratchBufferSize)*mWorkerDataCount); // we run over by filtersize
mBigBuffer.reset( (float *)malloc_simd(sizeof(float) * (mSubBufferSize + mFilterSize + mScratchBufferSize) * mWorkerDataCount) ); // we run over by filtersize
// fill the bufferInfo
mBufferInfo.reinit(mWorkerDataCount);
for(int i=0;i<mWorkerDataCount;i++) {
@ -250,8 +250,7 @@ bool EffectEqualization48x::FreeBuffersWorkers()
mWorkerDataCount=0;
}
mBufferInfo.reset();
free_simd(mBigBuffer);
mBigBuffer=NULL;
mBigBuffer.reset();
return true;
}
@ -672,8 +671,8 @@ bool EffectEqualization48x::ProcessOne1x(int count, WaveTrack * t,
output->Append((samplePtr)&mBigBuffer[(bigRun?mBlockSize:0)+(mFilterSize>>1)], floatSample, subBufferSize-((bigRun?mBlockSize:0)+(mFilterSize>>1)));
}
if(singleProcessLength && !bBreakLoop) {
t->Get((samplePtr)mBigBuffer, floatSample, currentSample, singleProcessLength+mBlockSize+(mFilterSize>>1));
ProcessBuffer(mBigBuffer, mBigBuffer, singleProcessLength+mBlockSize+(mFilterSize>>1));
t->Get((samplePtr)mBigBuffer.get(), floatSample, currentSample, singleProcessLength+mBlockSize+(mFilterSize>>1));
ProcessBuffer(mBigBuffer.get(), mBigBuffer.get(), singleProcessLength+mBlockSize+(mFilterSize>>1));
output->Append((samplePtr)&mBigBuffer[bigRuns > 0 ? mBlockSize : 0], floatSample, singleProcessLength+mBlockSize+(mFilterSize>>1));
}
output->Flush();
@ -688,7 +687,7 @@ void EffectEqualization48x::Filter1x(size_t len,
int i;
float real, imag;
// Apply FFT
RealFFTf1x(buffer, mEffectEqualization->hFFT);
RealFFTf1x(buffer, mEffectEqualization->hFFT.get());
// Apply filter
// DC component is purely real
@ -721,8 +720,8 @@ void EffectEqualization48x::Filter1x(size_t len,
scratchBuffer[1] = buffer[1] * filterFuncR;
// Inverse FFT and normalization
InverseRealFFTf1x(scratchBuffer, mEffectEqualization->hFFT);
ReorderToTime1x(mEffectEqualization->hFFT, scratchBuffer, buffer);
InverseRealFFTf1x(scratchBuffer, mEffectEqualization->hFFT.get());
ReorderToTime1x(mEffectEqualization->hFFT.get(), scratchBuffer, buffer);
}
bool EffectEqualization48x::ProcessBuffer4x(BufferInfo *bufferInfo)
@ -853,8 +852,8 @@ bool EffectEqualization48x::ProcessOne4x(int count, WaveTrack * t,
output->Append((samplePtr)&mBigBuffer[(bigRun?mBlockSize:0)+(mFilterSize>>1)], floatSample, subBufferSize-((bigRun?mBlockSize:0)+(mFilterSize>>1)));
}
if(singleProcessLength && !bBreakLoop) {
t->Get((samplePtr)mBigBuffer, floatSample, currentSample, singleProcessLength+mBlockSize+(mFilterSize>>1));
ProcessBuffer(mBigBuffer, mBigBuffer, singleProcessLength+mBlockSize+(mFilterSize>>1));
t->Get((samplePtr)mBigBuffer.get(), floatSample, currentSample, singleProcessLength+mBlockSize+(mFilterSize>>1));
ProcessBuffer(mBigBuffer.get(), mBigBuffer.get(), singleProcessLength+mBlockSize+(mFilterSize>>1));
output->Append((samplePtr)&mBigBuffer[bigRuns > 0 ? mBlockSize : 0], floatSample, singleProcessLength+mBlockSize+(mFilterSize>>1));
// output->Append((samplePtr)&mBigBuffer[bigRuns?mBlockSize:0], floatSample, singleProcessLength);
}
@ -965,8 +964,8 @@ bool EffectEqualization48x::ProcessOne1x4xThreaded(int count, WaveTrack * t,
mDataMutex.Unlock(); // Get back in line for data
}
if(singleProcessLength && !bBreakLoop) {
t->Get((samplePtr)mBigBuffer, floatSample, currentSample, singleProcessLength+mBlockSize+(mFilterSize>>1));
ProcessBuffer(mBigBuffer, mBigBuffer, singleProcessLength+mBlockSize+(mFilterSize>>1));
t->Get((samplePtr)mBigBuffer.get(), floatSample, currentSample, singleProcessLength+mBlockSize+(mFilterSize>>1));
ProcessBuffer(mBigBuffer.get(), mBigBuffer.get(), singleProcessLength+mBlockSize+(mFilterSize>>1));
output->Append((samplePtr)&mBigBuffer[mBlockSize], floatSample, singleProcessLength+mBlockSize+(mFilterSize>>1));
}
output->Flush();
@ -981,7 +980,7 @@ void EffectEqualization48x::Filter4x(size_t len,
int i;
__m128 real128, imag128;
// Apply FFT
RealFFTf4x(buffer, mEffectEqualization->hFFT);
RealFFTf4x(buffer, mEffectEqualization->hFFT.get());
// Apply filter
// DC component is purely real
@ -1015,8 +1014,8 @@ void EffectEqualization48x::Filter4x(size_t len,
localFFTBuffer[1] = _mm_mul_ps(localBuffer[1], filterFuncR);
// Inverse FFT and normalization
InverseRealFFTf4x(scratchBuffer, mEffectEqualization->hFFT);
ReorderToTime4x(mEffectEqualization->hFFT, scratchBuffer, buffer);
InverseRealFFTf4x(scratchBuffer, mEffectEqualization->hFFT.get());
ReorderToTime4x(mEffectEqualization->hFFT.get(), scratchBuffer, buffer);
}
#ifdef __AVX_ENABLED
@ -1183,8 +1182,8 @@ bool EffectEqualization48x::ProcessOne8x(int count, WaveTrack * t,
output->Append((samplePtr)&mBigBuffer[(bigRun?mBlockSize:0)+(mFilterSize>>1)], floatSample, mSubBufferSize-((bigRun?mBlockSize:0)+(mFilterSize>>1)));
}
if(singleProcessLength && !bBreakLoop) {
t->Get((samplePtr)mBigBuffer, floatSample, currentSample, singleProcessLength+mBlockSize+(mFilterSize>>1));
ProcessBuffer(mBigBuffer, mBigBuffer, singleProcessLength+mBlockSize+(mFilterSize>>1));
t->Get((samplePtr)mBigBuffer.get(), floatSample, currentSample, singleProcessLength+mBlockSize+(mFilterSize>>1));
ProcessBuffer(mBigBuffer.get(), mBigBuffer.get(), singleProcessLength+mBlockSize+(mFilterSize>>1));
output->Append((samplePtr)&mBigBuffer[mBlockSize], floatSample, singleProcessLength+mBlockSize+(mFilterSize>>1));
}
output->Flush();
@ -1262,8 +1261,8 @@ bool EffectEqualization48x::ProcessOne8xThreaded(int count, WaveTrack * t,
mDataMutex.Unlock(); // Get back in line for data
}
if(singleProcessLength && !bBreakLoop) {
t->Get((samplePtr)mBigBuffer, floatSample, currentSample, singleProcessLength+mBlockSize+(mFilterSize>>1));
ProcessBuffer(mBigBuffer, mBigBuffer, singleProcessLength+mBlockSize+(mFilterSize>>1));
t->Get((samplePtr)mBigBuffer.get(), floatSample, currentSample, singleProcessLength+mBlockSize+(mFilterSize>>1));
ProcessBuffer(mBigBuffer.get(), mBigBuffer.get(), singleProcessLength+mBlockSize+(mFilterSize>>1));
output->Append((samplePtr)&mBigBuffer[mBlockSize], floatSample, singleProcessLength+mBlockSize+(mFilterSize>>1));
}
output->Flush();

View File

@ -32,6 +32,11 @@ Intrinsics (SSE/AVX) and Threaded Equalization
#define MATH_FUNCTION_AVX 16
#define MATH_FUNCTION_SEGMENTED_CODE 32
struct free_simd {
void operator () (void*) const;
};
using simd_floats = std::unique_ptr< float[], free_simd >;
// added by Andrew Hallendorff intrinsics processing
enum EQBufferStatus
{
@ -156,7 +161,7 @@ private:
size_t mBlocksPerBuffer;
size_t mScratchBufferSize;
size_t mSubBufferSize;
float *mBigBuffer;
simd_floats mBigBuffer;
ArrayOf<BufferInfo> mBufferInfo;
wxMutex mDataMutex;
ArrayOf<EQWorker> mEQWorkers;

View File

@ -640,7 +640,6 @@ bool EffectNoiseReduction::Process()
EffectNoiseReduction::Worker::~Worker()
{
EndFFT(hFFT);
}
bool EffectNoiseReduction::Worker::Process
@ -727,7 +726,7 @@ EffectNoiseReduction::Worker::Worker
, mSampleRate(sampleRate)
, mWindowSize(settings.WindowSize())
, hFFT(InitializeFFT(mWindowSize))
, hFFT(GetFFT(mWindowSize))
, mFFTBuffer(mWindowSize)
, mInWaveBuffer(mWindowSize)
, mOutOverlapBuffer(mWindowSize)
@ -945,7 +944,7 @@ void EffectNoiseReduction::Worker::FillFirstHistoryWindow()
mFFTBuffer[ii] = mInWaveBuffer[ii] * mInWindow[ii];
else
memmove(&mFFTBuffer[0], &mInWaveBuffer[0], mWindowSize * sizeof(float));
RealFFTf(&mFFTBuffer[0], hFFT);
RealFFTf(&mFFTBuffer[0], hFFT.get());
Record &record = *mQueue[0];
@ -1243,7 +1242,7 @@ void EffectNoiseReduction::Worker::ReduceNoise
}
// Invert the FFT into the output buffer
InverseRealFFTf(&mFFTBuffer[0], hFFT);
InverseRealFFTf(&mFFTBuffer[0], hFFT.get());
// Overlap-add
if (mOutWindow.size() > 0) {

View File

@ -288,7 +288,7 @@ void EffectNoiseRemoval::Initialize()
mImagFFTs.reinit(mHistoryLen, mSpectrumSize);
// Initialize the FFT
hFFT = InitializeFFT(mWindowSize);
hFFT = GetFFT(mWindowSize);
mFFTBuffer.reinit(mWindowSize);
mInWaveBuffer.reinit(mWindowSize);
@ -307,7 +307,7 @@ void EffectNoiseRemoval::Initialize()
void EffectNoiseRemoval::Cleanup()
{
EndFFT(hFFT);
hFFT.reset();
if (mDoProfile) {
ApplyFreqSmoothing(mNoiseThreshold.get());
@ -374,8 +374,8 @@ void EffectNoiseRemoval::FillFirstHistoryWindow()
{
for(size_t i = 0; i < mWindowSize; i++)
mFFTBuffer[i] = mInWaveBuffer[i];
RealFFTf(mFFTBuffer.get(), hFFT);
for(size_t i = 1; i < (mSpectrumSize-1); i++) {
RealFFTf(mFFTBuffer.get(), hFFT.get());
for(size_t i = 1; i + 1 < mSpectrumSize; i++) {
mRealFFTs[0][i] = mFFTBuffer[hFFT->BitReversed[i] ];
mImagFFTs[0][i] = mFFTBuffer[hFFT->BitReversed[i]+1];
mSpectrums[0][i] = mRealFFTs[0][i]*mRealFFTs[0][i] + mImagFFTs[0][i]*mImagFFTs[0][i];
@ -502,7 +502,7 @@ void EffectNoiseRemoval::RemoveNoise()
mFFTBuffer[1] = mRealFFTs[out][mSpectrumSize-1] * mGains[out][mSpectrumSize-1];
// Invert the FFT into the output buffer
InverseRealFFTf(mFFTBuffer.get(), hFFT);
InverseRealFFTf(mFFTBuffer.get(), hFFT.get());
// Overlap-add
for(size_t j = 0; j < (mSpectrumSize-1); j++) {

View File

@ -78,8 +78,8 @@ FactoryPresets[] =
struct Reverb_priv_t
{
reverb_t reverb;
float *dry;
float *wet[2];
float *dry {};
float *wet[2] { {}, {} };
};
//
@ -171,7 +171,7 @@ bool EffectReverb::ProcessInitialize(sampleCount WXUNUSED(totalLen), ChannelName
mNumChans = 2;
}
mP = (Reverb_priv_t *) calloc(sizeof(*mP), mNumChans);
mP.reinit(mNumChans, true);
for (int i = 0; i < mNumChans; i++)
{
@ -194,12 +194,7 @@ bool EffectReverb::ProcessInitialize(sampleCount WXUNUSED(totalLen), ChannelName
bool EffectReverb::ProcessFinalize()
{
for (int i = 0; i < mNumChans; i++)
{
reverb_delete(&mP[i].reverb);
}
free(mP);
mP.reset();
return true;
}

View File

@ -97,7 +97,7 @@ private:
private:
unsigned mNumChans {};
Reverb_priv_t *mP;
ArrayOf<Reverb_priv_t> mP;
Params mParams;

View File

@ -29,16 +29,15 @@ using std::max;
#define FIFO_SIZE_T size_t
#define FIFO_MIN 0x4000
#define fifo_read_ptr(f) fifo_read(f, (FIFO_SIZE_T)0, NULL)
#define lsx_zalloc(var, n) var = (float *)calloc(n, sizeof(*var))
#define filter_advance(p) if (--(p)->ptr < (p)->buffer) (p)->ptr += (p)->size
#define filter_delete(p) free((p)->buffer)
#define lsx_zalloc(var, n) (var.reinit(n, true), var.get())
#define filter_advance(p) if (--(p)->ptr < (p)->buffer.get()) (p)->ptr += (p)->size
typedef struct {
char * data;
size_t allocation; /* Number of bytes allocated for data. */
size_t item_size; /* Size of each item in data */
size_t begin; /* Offset of the first byte to read. */
size_t end; /* 1 + Offset of the last byte byte to read. */
ArrayOf<char> data;
size_t allocation {}; /* Number of bytes allocated for data. */
size_t item_size {}; /* Size of each item in data */
size_t begin {}; /* Offset of the first byte to read. */
size_t end {}; /* 1 + Offset of the last byte byte to read. */
} fifo_t;
static void fifo_clear(fifo_t * f)
@ -55,19 +54,19 @@ static void * fifo_reserve(fifo_t * f, FIFO_SIZE_T n)
while (1) {
if (f->end + n <= f->allocation) {
void *p = f->data + f->end;
void *p = f->data.get() + f->end;
f->end += n;
return p;
}
if (f->begin > FIFO_MIN) {
memmove(f->data, f->data + f->begin, f->end - f->begin);
memmove(f->data.get(), f->data.get() + f->begin, f->end - f->begin);
f->end -= f->begin;
f->begin = 0;
continue;
}
f->allocation += n;
f->data = (char *)realloc(f->data, f->allocation);
f->data.reinit(f->allocation);
}
}
@ -81,7 +80,7 @@ static void * fifo_write(fifo_t * f, FIFO_SIZE_T n, void const * data)
static void * fifo_read(fifo_t * f, FIFO_SIZE_T n, void * data)
{
char * ret = f->data + f->begin;
char * ret = f->data.get() + f->begin;
n *= f->item_size;
if (n > (FIFO_SIZE_T)(f->end - f->begin))
return NULL;
@ -91,22 +90,18 @@ static void * fifo_read(fifo_t * f, FIFO_SIZE_T n, void * data)
return ret;
}
static void fifo_delete(fifo_t * f)
{
free(f->data);
}
static void fifo_create(fifo_t * f, FIFO_SIZE_T item_size)
{
f->item_size = item_size;
f->allocation = FIFO_MIN;
f->data = (char *)malloc(f->allocation);
f->data.reinit(f->allocation);
fifo_clear(f);
}
typedef struct {
size_t size;
float * buffer, * ptr;
ArrayOf<float> buffer;
float * ptr;
float store;
} filter_t;
@ -199,23 +194,13 @@ static void filter_array_process(filter_array_t * p,
}
}
static void filter_array_delete(filter_array_t * p)
{
size_t i;
for (i = 0; i < array_length(allpass_lengths); ++i)
filter_delete(&p->allpass[i]);
for (i = 0; i < array_length(comb_lengths); ++i)
filter_delete(&p->comb[i]);
}
typedef struct {
float feedback;
float hf_damping;
float gain;
fifo_t input_fifo;
float feedback {};
float hf_damping {};
float gain {};
fifo_t input_fifo {};
filter_array_t chan[2];
float * out[2];
ArrayOf<float> out[2];
} reverb_t;
static void reverb_create(reverb_t * p, double sample_rate_Hz,
@ -254,17 +239,7 @@ static void reverb_process(reverb_t * p, size_t length)
{
size_t i;
for (i = 0; i < 2 && p->out[i]; ++i)
filter_array_process(p->chan + i, length, (float *) fifo_read_ptr(&p->input_fifo), p->out[i], &p->feedback, &p->hf_damping, &p->gain);
filter_array_process(p->chan + i, length, (float *) fifo_read_ptr(&p->input_fifo), p->out[i].get(), &p->feedback, &p->hf_damping, &p->gain);
fifo_read(&p->input_fifo, length, NULL);
}
static void reverb_delete(reverb_t * p)
{
size_t i;
for (i = 0; i < 2 && p->out[i]; ++i) {
free(p->out[i]);
filter_array_delete(p->chan + i);
}
fifo_delete(&p->input_fifo);
}

View File

@ -33,38 +33,29 @@ public:
ResampleBuf()
{
processed = 0;
buf = NULL;
leftBuffer = NULL;
rightBuffer = NULL;
SBSMSBuf = NULL;
outputLeftTrack = NULL;
outputRightTrack = NULL;
}
~ResampleBuf()
{
if(buf) free(buf);
if(leftBuffer) free(leftBuffer);
if(rightBuffer) free(rightBuffer);
if(SBSMSBuf) free(SBSMSBuf);
}
bool bPitch;
audio *buf;
ArrayOf<audio> buf;
double ratio;
sampleCount processed;
size_t blockSize;
long SBSMSBlockSize;
sampleCount offset;
sampleCount end;
float *leftBuffer;
float *rightBuffer;
ArrayOf<float> leftBuffer;
ArrayOf<float> rightBuffer;
WaveTrack *leftTrack;
WaveTrack *rightTrack;
std::unique_ptr<SBSMS> sbsms;
std::unique_ptr<SBSMSInterface> iface;
audio *SBSMSBuf;
ArrayOf<audio> SBSMSBuf;
// Not required by callbacks, but makes for easier cleanup
std::unique_ptr<Resampler> resampler;
@ -104,8 +95,8 @@ long resampleCB(void *cb_data, SBSMSFrame *data)
);
// Get the samples from the tracks and put them in the buffers.
r->leftTrack->Get((samplePtr)(r->leftBuffer), floatSample, r->offset, blockSize);
r->rightTrack->Get((samplePtr)(r->rightBuffer), floatSample, r->offset, blockSize);
r->leftTrack->Get((samplePtr)(r->leftBuffer.get()), floatSample, r->offset, blockSize);
r->rightTrack->Get((samplePtr)(r->rightBuffer.get()), floatSample, r->offset, blockSize);
// convert to sbsms audio format
for(decltype(blockSize) i=0; i<blockSize; i++) {
@ -113,7 +104,7 @@ long resampleCB(void *cb_data, SBSMSFrame *data)
r->buf[i][1] = r->rightBuffer[i];
}
data->buf = r->buf;
data->buf = r->buf.get();
data->size = blockSize;
if(r->bPitch) {
float t0 = r->processed.as_float() / r->iface->getSamplesToInput();
@ -132,8 +123,8 @@ long resampleCB(void *cb_data, SBSMSFrame *data)
long postResampleCB(void *cb_data, SBSMSFrame *data)
{
ResampleBuf *r = (ResampleBuf*) cb_data;
auto count = r->sbsms->read(r->iface.get(), r->SBSMSBuf, r->SBSMSBlockSize);
data->buf = r->SBSMSBuf;
auto count = r->sbsms->read(r->iface.get(), r->SBSMSBuf.get(), r->SBSMSBlockSize);
data->buf = r->SBSMSBuf.get();
data->size = count;
data->ratio0 = 1.0 / r->ratio;
data->ratio1 = 1.0 / r->ratio;
@ -285,11 +276,11 @@ bool EffectSBSMS::Process()
ResampleBuf rb;
auto maxBlockSize = leftTrack->GetMaxBlockSize();
rb.blockSize = maxBlockSize;
rb.buf = (audio*)calloc(rb.blockSize,sizeof(audio));
rb.buf.reinit(rb.blockSize, true);
rb.leftTrack = leftTrack;
rb.rightTrack = rightTrack?rightTrack:leftTrack;
rb.leftBuffer = (float*)calloc(maxBlockSize,sizeof(float));
rb.rightBuffer = (float*)calloc(maxBlockSize,sizeof(float));
rb.leftBuffer.reinit(maxBlockSize, true);
rb.rightBuffer.reinit(maxBlockSize, true);
// Samples in selection
auto samplesIn = end - start;
@ -325,7 +316,7 @@ bool EffectSBSMS::Process()
rb.resampler = std::make_unique<Resampler>(resampleCB, &rb, srProcess==srTrack?SlideIdentity:SlideConstant);
rb.sbsms = std::make_unique<SBSMS>(rightTrack ? 2 : 1, rb.quality.get(), true);
rb.SBSMSBlockSize = rb.sbsms->getInputFrameSize();
rb.SBSMSBuf = (audio*)calloc(rb.SBSMSBlockSize,sizeof(audio));
rb.SBSMSBuf.reinit(static_cast<size_t>(rb.SBSMSBlockSize), true);
// Note: width of getMaxPresamples() is only long. Widen it
decltype(start) processPresamples = rb.quality->getMaxPresamples();

View File

@ -277,7 +277,8 @@ void AUControl::CreateCocoa()
return;
}
AudioUnitCocoaViewInfo *viewInfo = (AudioUnitCocoaViewInfo *) malloc(dataSize);
ArrayOf<char> buffer{ dataSize };
auto viewInfo = (AudioUnitCocoaViewInfo *) buffer.get();
if (viewInfo == NULL)
{
return;
@ -331,8 +332,6 @@ void AUControl::CreateCocoa()
}
}
free(viewInfo);
if (!mView)
{
return;
@ -474,7 +473,8 @@ void AUControl::CreateCarbon()
return;
}
AudioComponentDescription *compList = (AudioComponentDescription *) malloc(dataSize);
ArrayOf<char> buffer{ dataSize };
auto compList = (AudioComponentDescription *) buffer.get();
if (compList == NULL)
{
return;
@ -488,11 +488,7 @@ void AUControl::CreateCarbon()
compList,
&dataSize);
if (result != noErr)
{
free(compList);
return;
}
// Get the component
AudioComponent comp = AudioComponentFindNext(NULL, &compList[0]);
@ -500,9 +496,6 @@ void AUControl::CreateCarbon()
// Try to create an instance
result = AudioComponentInstanceNew(comp, &mInstance);
// Done with the list
free(compList);
if (result != noErr)
{
return;

View File

@ -2187,7 +2187,8 @@ void AudioUnitEffect::GetChannelCounts()
return;
}
AUChannelInfo *info = (AUChannelInfo *) malloc(dataSize);
ArrayOf<char> buffer{ dataSize };
auto info = (AUChannelInfo *) buffer.get();
// Retrieve the channel info
result = AudioUnitGetProperty(mUnit,
@ -2202,7 +2203,6 @@ void AudioUnitEffect::GetChannelCounts()
mAudioIns = 2;
mAudioOuts = 2;
free(info);
return;
}

View File

@ -316,11 +316,6 @@ LV2Effect::LV2Effect(const LilvPlugin *plug)
mDialog = NULL;
mURIMap = NULL;
mNumURIMap = 0;
mOptions = NULL;
mNumOptions = 0;
mIdleFeature = NULL;
mOptionsInterface = NULL;
@ -329,19 +324,6 @@ LV2Effect::LV2Effect(const LilvPlugin *plug)
LV2Effect::~LV2Effect()
{
if (mURIMap)
{
for (int i = 0; i < mNumURIMap; i++)
{
free(mURIMap[i]);
}
free(mURIMap);
}
if (mOptions)
{
free(mOptions);
}
}
// ============================================================================
@ -675,7 +657,7 @@ bool LV2Effect::SetHost(EffectHostInterface *host)
AddFeature(LV2_UI_PREFIX "makeResident", NULL);
AddFeature(LV2_UI__noUserResize, NULL);
AddFeature(LV2_BUF_SIZE__boundedBlockLength, NULL);
AddFeature(LV2_OPTIONS__options, mOptions);
AddFeature(LV2_OPTIONS__options, mOptions.data());
AddFeature(LV2_URI_MAP_URI, &mUriMapFeature);
AddFeature(LV2_URID__map, &mURIDMapFeature);
AddFeature(LV2_URID__unmap, &mURIDUnmapFeature);
@ -1302,10 +1284,9 @@ bool LV2Effect::SaveParameters(const wxString & group)
size_t LV2Effect::AddOption(const char *key, uint32_t size, const char *type, void *value)
{
int ndx = mNumOptions;
int ndx = mOptions.size();
mNumOptions += 1;
mOptions = (LV2_Options_Option *) realloc(mOptions, mNumOptions * sizeof(LV2_Options_Option));
mOptions.resize(1 + mOptions.size());
memset(&mOptions[ndx], 0, sizeof(mOptions[ndx]));
if (key != NULL)
@ -1323,26 +1304,24 @@ size_t LV2Effect::AddOption(const char *key, uint32_t size, const char *type, vo
LV2_Feature *LV2Effect::AddFeature(const char *uri, void *data)
{
mFeatures.resize(mFeatures.size() + 1);
auto &pFeature = mFeatures.back();
size_t ndx = mFeatures.size();
mFeatures.resize(1 + mFeatures.size());
if (uri != NULL)
{
pFeature = make_movable<LV2_Feature>();
pFeature->URI = uri;
pFeature->data = data;
mFeatures[ndx].reset( safenew LV2_Feature );
mFeatures[ndx]->URI = uri;
mFeatures[ndx]->data = data;
}
mFeaturePtrs.push_back(pFeature.get());
return pFeature.get();
return mFeatures[ndx].get();
}
LilvInstance *LV2Effect::InitInstance(float sampleRate)
{
LilvInstance *handle = lilv_plugin_instantiate(mPlug,
sampleRate,
mFeaturePtrs.data());
LilvInstance *handle = lilv_plugin_instantiate(
mPlug, sampleRate,
reinterpret_cast<const LV2_Feature *const *>(mFeatures.data()));
if (!handle)
{
return NULL;
@ -1478,7 +1457,7 @@ bool LV2Effect::BuildFancy()
lilv_node_as_uri(uiType),
lilv_uri_to_path(lilv_node_as_uri(lilv_ui_get_bundle_uri(ui))),
lilv_uri_to_path(lilv_node_as_uri(lilv_ui_get_binary_uri(ui))),
mFeaturePtrs.data());
reinterpret_cast<const LV2_Feature *const *>(mFeatures.data()));
lilv_uis_free(uis);
@ -2033,19 +2012,19 @@ LV2_URID LV2Effect::urid_map(LV2_URID_Map_Handle handle, const char *uri)
LV2_URID LV2Effect::URID_Map(const char *uri)
{
for (int i = 0; i < mNumURIMap; i++)
size_t ndx = mURIMap.size();
for (int i = 0; i < ndx; i++)
{
if (strcmp(mURIMap[i], uri) == 0)
if (strcmp(mURIMap[i].get(), uri) == 0)
{
return i + 1;
}
}
mNumURIMap += 1;
mURIMap = (char **) realloc(mURIMap, mNumURIMap * sizeof(char*));
mURIMap[mNumURIMap - 1] = strdup(uri);
mURIMap.resize(1 + mURIMap.size());
mURIMap[ndx].reset( strdup(uri) );
return mNumURIMap;
return ndx + 1;
}
// static callback
@ -2056,9 +2035,9 @@ const char *LV2Effect::urid_unmap(LV2_URID_Unmap_Handle handle, LV2_URID urid)
const char *LV2Effect::URID_Unmap(LV2_URID urid)
{
if (urid > 0 && urid <= (LV2_URID) mNumURIMap)
if (urid > 0 && urid <= (LV2_URID) mURIMap.size())
{
return mURIMap[urid - 1];
return mURIMap[urid - 1].get();
}
return NULL;

View File

@ -15,7 +15,6 @@
#include "../../MemoryX.h"
#include <vector>
#include <wx/checkbox.h>
#include <wx/dialog.h>
#include <wx/dynarray.h>
@ -289,8 +288,7 @@ private:
bool mUseGUI;
char **mURIMap;
int mNumURIMap;
std::vector< movable_ptr_with_deleter<char, freer> > mURIMap;
LV2_URI_Map_Feature mUriMapFeature;
LV2_URID_Map mURIDMapFeature;
@ -302,11 +300,9 @@ private:
size_t mSampleRateOption;
LV2_Options_Interface *mOptionsInterface;
LV2_Options_Option *mOptions;
int mNumOptions;
std::vector<LV2_Options_Option> mOptions;
std::vector<movable_ptr<LV2_Feature>> mFeatures;
std::vector<LV2_Feature*> mFeaturePtrs;
LV2_Feature *mInstanceAccessFeature;
LV2_Feature *mParentFeature;

View File

@ -240,7 +240,7 @@ wxWindow *ExportPlugin::OptionsCreate(wxWindow *parent, int WXUNUSED(format))
std::unique_ptr<Mixer> ExportPlugin::CreateMixer(const WaveTrackConstArray &inputTracks,
const TimeTrack *timeTrack,
double startTime, double stopTime,
unsigned numOutChannels, int outBufferSize, bool outInterleaved,
unsigned numOutChannels, size_t outBufferSize, bool outInterleaved,
double outRate, sampleFormat outFormat,
bool highQuality, MixerSpec *mixerSpec)
{

View File

@ -123,7 +123,7 @@ protected:
std::unique_ptr<Mixer> CreateMixer(const WaveTrackConstArray &inputTracks,
const TimeTrack *timeTrack,
double startTime, double stopTime,
unsigned numOutChannels, int outBufferSize, bool outInterleaved,
unsigned numOutChannels, size_t outBufferSize, bool outInterleaved,
double outRate, sampleFormat outFormat,
bool highQuality = true, MixerSpec *mixerSpec = NULL);

View File

@ -857,7 +857,7 @@ ProgressResult ExportFFmpeg::Export(AudacityProject *project,
if (!ret)
return ProgressResult::Cancelled;
int pcmBufferSize = 1024;
size_t pcmBufferSize = 1024;
const WaveTrackConstArray waveTracks =
tracks->GetWaveTrackConstArray(selectionOnly, false);
auto mixer = CreateMixer(waveTracks,

View File

@ -173,6 +173,14 @@ static struct
//----------------------------------------------------------------------------
struct FLAC__StreamMetadataDeleter {
void operator () (FLAC__StreamMetadata *p) const
{ if (p) ::FLAC__metadata_object_delete(p); }
};
using FLAC__StreamMetadataHandle = std::unique_ptr<
FLAC__StreamMetadata, FLAC__StreamMetadataDeleter
>;
class ExportFLAC final : public ExportPlugin
{
public:
@ -196,7 +204,7 @@ private:
bool GetMetadata(AudacityProject *project, const Tags *tags);
FLAC__StreamMetadata *mMetadata;
FLAC__StreamMetadataHandle mMetadata;
};
//----------------------------------------------------------------------------
@ -248,7 +256,10 @@ ProgressResult ExportFLAC::Export(AudacityProject *project,
}
if (mMetadata) {
encoder.set_metadata(&mMetadata, 1);
// set_metadata expects an array of pointers to metadata and a size.
// The size is 1.
FLAC__StreamMetadata *p = mMetadata.get();
encoder.set_metadata(&p, 1);
}
sampleFormat format;
@ -299,9 +310,7 @@ ProgressResult ExportFLAC::Export(AudacityProject *project,
}
#endif
if (mMetadata) {
::FLAC__metadata_object_delete(mMetadata);
}
mMetadata.reset();
const WaveTrackConstArray waveTracks =
tracks->GetWaveTrackConstArray(selectionOnly, false);
@ -367,7 +376,7 @@ bool ExportFLAC::GetMetadata(AudacityProject *project, const Tags *tags)
if (tags == NULL)
tags = project->GetTags();
mMetadata = ::FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT);
mMetadata.reset(::FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT));
wxString n;
for (const auto &pair : tags->GetRange()) {
@ -378,7 +387,7 @@ bool ExportFLAC::GetMetadata(AudacityProject *project, const Tags *tags)
}
FLAC::Metadata::VorbisComment::Entry entry(n.mb_str(wxConvUTF8),
v.mb_str(wxConvUTF8));
::FLAC__metadata_object_vorbiscomment_append_comment(mMetadata,
::FLAC__metadata_object_vorbiscomment_append_comment(mMetadata.get(),
entry.get_entry(),
true);
}

View File

@ -185,7 +185,7 @@ public:
private:
int AddTags(AudacityProject *project, char **buffer, bool *endOfFile, const Tags *tags);
int AddTags(AudacityProject *project, ArrayOf<char> &buffer, bool *endOfFile, const Tags *tags);
#ifdef USE_LIBID3TAG
void AddFrame(struct id3_tag *tp, const wxString & n, const wxString & v, const char *name);
#endif
@ -242,15 +242,15 @@ ProgressResult ExportMP2::Export(AudacityProject *project,
return ProgressResult::Cancelled;
}
char *id3buffer = NULL;
ArrayOf<char> id3buffer;
int id3len;
bool endOfFile;
id3len = AddTags(project, &id3buffer, &endOfFile, metadata);
id3len = AddTags(project, id3buffer, &endOfFile, metadata);
if (id3len && !endOfFile)
outFile.Write(id3buffer, id3len);
outFile.Write(id3buffer.get(), id3len);
// Values taken from the twolame simple encoder sample
const int pcmBufferSize = 9216 / 2; // number of samples
const size_t pcmBufferSize = 9216 / 2; // number of samples
const size_t mp2BufferSize = 16384u; // bytes
// We allocate a buffer which is twice as big as the
@ -307,11 +307,7 @@ ProgressResult ExportMP2::Export(AudacityProject *project,
/* Write ID3 tag if it was supposed to be at the end of the file */
if (id3len && endOfFile)
outFile.Write(id3buffer, id3len);
if (id3buffer) {
free(id3buffer);
}
outFile.Write(id3buffer.get(), id3len);
/* Close file */
@ -326,11 +322,16 @@ wxWindow *ExportMP2::OptionsCreate(wxWindow *parent, int format)
return safenew ExportMP2Options(parent, format);
}
struct id3_tag_deleter {
void operator () (id3_tag *p) const { if (p) id3_tag_delete(p); }
};
using id3_tag_holder = std::unique_ptr<id3_tag, id3_tag_deleter>;
// returns buffer len; caller frees
int ExportMP2::AddTags(AudacityProject * WXUNUSED(project), char **buffer, bool *endOfFile, const Tags *tags)
int ExportMP2::AddTags(AudacityProject * WXUNUSED(project), ArrayOf<char> &buffer, bool *endOfFile, const Tags *tags)
{
#ifdef USE_LIBID3TAG
struct id3_tag *tp = id3_tag_new();
id3_tag_holder tp { id3_tag_new() };
for (const auto &pair : tags->GetRange()) {
const auto &n = pair.first;
@ -349,7 +350,7 @@ int ExportMP2::AddTags(AudacityProject * WXUNUSED(project), char **buffer, bool
else if (n.CmpNoCase(TAG_YEAR) == 0) {
// LLL: Some apps do not like the newer frame ID (ID3_FRAME_YEAR),
// so we add old one as well.
AddFrame(tp, n, v, "TYER");
AddFrame(tp.get(), n, v, "TYER");
name = ID3_FRAME_YEAR;
}
else if (n.CmpNoCase(TAG_GENRE) == 0) {
@ -362,7 +363,7 @@ int ExportMP2::AddTags(AudacityProject * WXUNUSED(project), char **buffer, bool
name = ID3_FRAME_TRACK;
}
AddFrame(tp, n, v, name);
AddFrame(tp.get(), n, v, name);
}
tp->options &= (~ID3_TAG_OPTION_COMPRESSION); // No compression
@ -378,11 +379,10 @@ int ExportMP2::AddTags(AudacityProject * WXUNUSED(project), char **buffer, bool
id3_length_t len;
len = id3_tag_render(tp, 0);
*buffer = (char *)malloc(len);
len = id3_tag_render(tp, (id3_byte_t *)*buffer);
len = id3_tag_render(tp.get(), 0);
buffer.reinit(len);
len = id3_tag_render(tp.get(), (id3_byte_t *)buffer.get());
id3_tag_delete(tp);
return len;
#else //ifdef USE_LIBID3TAG
@ -402,8 +402,8 @@ void ExportMP2::AddFrame(struct id3_tag *tp, const wxString & n, const wxString
id3_field_settextencoding(id3_frame_field(frame, 0), ID3_FIELD_TEXTENCODING_ISO_8859_1);
}
id3_ucs4_t *ucs4 =
id3_utf8_ucs4duplicate((id3_utf8_t *) (const char *) v.mb_str(wxConvUTF8));
MallocString<id3_ucs4_t> ucs4 {
id3_utf8_ucs4duplicate((id3_utf8_t *) (const char *) v.mb_str(wxConvUTF8)) };
if (strcmp(name, ID3_FRAME_COMMENT) == 0) {
// A hack to get around iTunes not recognizing the comment. The
@ -413,22 +413,20 @@ void ExportMP2::AddFrame(struct id3_tag *tp, const wxString & n, const wxString
// way of clearing the field, so do it directly.
id3_field *f = id3_frame_field(frame, 1);
memset(f->immediate.value, 0, sizeof(f->immediate.value));
id3_field_setfullstring(id3_frame_field(frame, 3), ucs4);
id3_field_setfullstring(id3_frame_field(frame, 3), ucs4.get());
}
else if (strcmp(name, "TXXX") == 0) {
id3_field_setstring(id3_frame_field(frame, 2), ucs4);
free(ucs4);
id3_field_setstring(id3_frame_field(frame, 2), ucs4.get());
ucs4 = id3_utf8_ucs4duplicate((id3_utf8_t *) (const char *) n.mb_str(wxConvUTF8));
ucs4.reset(id3_utf8_ucs4duplicate((id3_utf8_t *) (const char *) n.mb_str(wxConvUTF8)));
id3_field_setstring(id3_frame_field(frame, 1), ucs4);
id3_field_setstring(id3_frame_field(frame, 1), ucs4.get());
}
else {
id3_field_setstrings(id3_frame_field(frame, 1), 1, &ucs4);
auto addr = ucs4.get();
id3_field_setstrings(id3_frame_field(frame, 1), 1, &addr);
}
free(ucs4);
id3_tag_attachframe(tp, frame);
}
#endif

View File

@ -1617,7 +1617,7 @@ private:
int FindValue(CHOICES *choices, int cnt, int needle, int def);
wxString FindName(CHOICES *choices, int cnt, int needle);
int AskResample(int bitrate, int rate, int lowrate, int highrate);
int AddTags(AudacityProject *project, char **buffer, bool *endOfFile, const Tags *tags);
int AddTags(AudacityProject *project, ArrayOf<char> &buffer, bool *endOfFile, const Tags *tags);
#ifdef USE_LIBID3TAG
void AddFrame(struct id3_tag *tp, const wxString & n, const wxString & v, const char *name);
#endif
@ -1796,12 +1796,12 @@ ProgressResult ExportMP3::Export(AudacityProject *project,
return ProgressResult::Cancelled;
}
char *id3buffer = NULL;
ArrayOf<char> id3buffer;
int id3len;
bool endOfFile;
id3len = AddTags(project, &id3buffer, &endOfFile, metadata);
id3len = AddTags(project, id3buffer, &endOfFile, metadata);
if (id3len && !endOfFile) {
outFile.Write(id3buffer, id3len);
outFile.Write(id3buffer.get(), id3len);
}
wxFileOffset pos = outFile.Tell();
@ -1890,11 +1890,7 @@ ProgressResult ExportMP3::Export(AudacityProject *project,
// Write ID3 tag if it was supposed to be at the end of the file
if (id3len && endOfFile) {
outFile.Write(id3buffer, id3len);
}
if (id3buffer) {
free(id3buffer);
outFile.Write(id3buffer.get(), id3len);
}
// Always write the info (Xing/Lame) tag. Until we stop supporting Lame
@ -2008,11 +2004,16 @@ int ExportMP3::AskResample(int bitrate, int rate, int lowrate, int highrate)
return wxAtoi(choice->GetStringSelection());
}
struct id3_tag_deleter {
void operator () (id3_tag *p) const { if (p) id3_tag_delete(p); }
};
using id3_tag_holder = std::unique_ptr<id3_tag, id3_tag_deleter>;
// returns buffer len; caller frees
int ExportMP3::AddTags(AudacityProject *WXUNUSED(project), char **buffer, bool *endOfFile, const Tags *tags)
int ExportMP3::AddTags(AudacityProject *WXUNUSED(project), ArrayOf<char> &buffer, bool *endOfFile, const Tags *tags)
{
#ifdef USE_LIBID3TAG
struct id3_tag *tp = id3_tag_new();
id3_tag_holder tp { id3_tag_new() };
for (const auto &pair : tags->GetRange()) {
const auto &n = pair.first;
@ -2031,7 +2032,7 @@ int ExportMP3::AddTags(AudacityProject *WXUNUSED(project), char **buffer, bool *
else if (n.CmpNoCase(TAG_YEAR) == 0) {
// LLL: Some apps do not like the newer frame ID (ID3_FRAME_YEAR),
// so we add old one as well.
AddFrame(tp, n, v, "TYER");
AddFrame(tp.get(), n, v, "TYER");
name = ID3_FRAME_YEAR;
}
else if (n.CmpNoCase(TAG_GENRE) == 0) {
@ -2044,7 +2045,7 @@ int ExportMP3::AddTags(AudacityProject *WXUNUSED(project), char **buffer, bool *
name = ID3_FRAME_TRACK;
}
AddFrame(tp, n, v, name);
AddFrame(tp.get(), n, v, name);
}
tp->options &= (~ID3_TAG_OPTION_COMPRESSION); // No compression
@ -2060,11 +2061,9 @@ int ExportMP3::AddTags(AudacityProject *WXUNUSED(project), char **buffer, bool *
id3_length_t len;
len = id3_tag_render(tp, 0);
*buffer = (char *)malloc(len);
len = id3_tag_render(tp, (id3_byte_t *)*buffer);
id3_tag_delete(tp);
len = id3_tag_render(tp.get(), 0);
buffer.reinit(len);
len = id3_tag_render(tp.get(), (id3_byte_t *)buffer.get());
return len;
#else //ifdef USE_LIBID3TAG
@ -2084,8 +2083,8 @@ void ExportMP3::AddFrame(struct id3_tag *tp, const wxString & n, const wxString
id3_field_settextencoding(id3_frame_field(frame, 0), ID3_FIELD_TEXTENCODING_ISO_8859_1);
}
id3_ucs4_t *ucs4 =
id3_utf8_ucs4duplicate((id3_utf8_t *) (const char *) v.mb_str(wxConvUTF8));
MallocString<id3_ucs4_t> ucs4{
id3_utf8_ucs4duplicate((id3_utf8_t *) (const char *) v.mb_str(wxConvUTF8)) };
if (strcmp(name, ID3_FRAME_COMMENT) == 0) {
// A hack to get around iTunes not recognizing the comment. The
@ -2094,27 +2093,25 @@ void ExportMP3::AddFrame(struct id3_tag *tp, const wxString & n, const wxString
// (which one???) or just clear it. Unfortunately, there's no supported
// way of clearing the field, so do it directly.
struct id3_frame *frame2 = id3_frame_new(name);
id3_field_setfullstring(id3_frame_field(frame2, 3), ucs4);
id3_field_setfullstring(id3_frame_field(frame2, 3), ucs4.get());
id3_field *f2 = id3_frame_field(frame2, 1);
memset(f2->immediate.value, 0, sizeof(f2->immediate.value));
id3_tag_attachframe(tp, frame2);
// Now install a second frame with the standard default language = "XXX"
id3_field_setfullstring(id3_frame_field(frame, 3), ucs4);
id3_field_setfullstring(id3_frame_field(frame, 3), ucs4.get());
}
else if (strcmp(name, "TXXX") == 0) {
id3_field_setstring(id3_frame_field(frame, 2), ucs4);
free(ucs4);
id3_field_setstring(id3_frame_field(frame, 2), ucs4.get());
ucs4 = id3_utf8_ucs4duplicate((id3_utf8_t *) (const char *) n.mb_str(wxConvUTF8));
ucs4.reset(id3_utf8_ucs4duplicate((id3_utf8_t *) (const char *) n.mb_str(wxConvUTF8)));
id3_field_setstring(id3_frame_field(frame, 1), ucs4);
id3_field_setstring(id3_frame_field(frame, 1), ucs4.get());
}
else {
id3_field_setstrings(id3_frame_field(frame, 1), 1, &ucs4);
auto addr = ucs4.get();
id3_field_setstrings(id3_frame_field(frame, 1), 1, &addr);
}
free(ucs4);
id3_tag_attachframe(tp, frame);
}
#endif

View File

@ -121,7 +121,7 @@ bool ExportOGGOptions::TransferDataFromWindow()
// ExportOGG
//----------------------------------------------------------------------------
#define SAMPLES_PER_RUN 8192
#define SAMPLES_PER_RUN 8192u
class ExportOGG final : public ExportPlugin
{

View File

@ -28,6 +28,7 @@
#include "../FileFormats.h"
#include "../Internat.h"
#include "../MemoryX.h"
#include "../Mix.h"
#include "../Prefs.h"
#include "../Project.h"
@ -328,7 +329,7 @@ public:
private:
char *AdjustString(const wxString & wxStr, int sf_format);
ArrayOf<char> AdjustString(const wxString & wxStr, int sf_format);
bool AddStrings(AudacityProject *project, SNDFILE *sf, const Tags *tags, int sf_format);
void AddID3Chunk(wxString fName, const Tags *tags, int sf_format);
@ -472,7 +473,7 @@ ProgressResult ExportPCM::Export(AudacityProject *project,
else
format = int16Sample;
int maxBlockLen = 44100 * 5;
size_t maxBlockLen = 44100 * 5;
const WaveTrackConstArray waveTracks =
tracks->GetWaveTrackConstArray(selectionOnly, false);
@ -538,7 +539,7 @@ ProgressResult ExportPCM::Export(AudacityProject *project,
return updateResult;
}
char *ExportPCM::AdjustString(const wxString & wxStr, int sf_format)
ArrayOf<char> ExportPCM::AdjustString(const wxString & wxStr, int sf_format)
{
bool b_aiff = false;
if ((sf_format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AIFF)
@ -547,34 +548,26 @@ char *ExportPCM::AdjustString(const wxString & wxStr, int sf_format)
// We must convert the string to 7 bit ASCII
size_t sz = wxStr.length();
if(sz == 0)
return NULL;
// Size for secure malloc in case of local wide char usage
return {};
// Size for secure allocation in case of local wide char usage
size_t sr = (sz+4) * 2;
char *pDest = (char *)malloc(sr);
ArrayOf<char> pDest{ sr, true };
if (!pDest)
return NULL;
char *pSrc = (char *)malloc(sr);
return {};
ArrayOf<char> pSrc{ sr, true };
if (!pSrc)
{
free(pDest);
return NULL;
}
memset(pDest, 0, sr);
memset(pSrc, 0, sr);
return {};
if(wxStr.mb_str(wxConvISO8859_1))
strncpy(pSrc, wxStr.mb_str(wxConvISO8859_1), sz);
strncpy(pSrc.get(), wxStr.mb_str(wxConvISO8859_1), sz);
else if(wxStr.mb_str())
strncpy(pSrc, wxStr.mb_str(), sz);
else {
free(pDest);
free(pSrc);
return NULL;
}
strncpy(pSrc.get(), wxStr.mb_str(), sz);
else
return {};
char *pD = pDest;
char *pS = pSrc;
char *pD = pDest.get();
char *pS = pSrc.get();
unsigned char c;
// ISO Latin to 7 bit ascii conversion table (best approximation)
@ -622,13 +615,11 @@ char *ExportPCM::AdjustString(const wxString & wxStr, int sf_format)
}
*pD = '\0';
free(pSrc);
if(b_aiff) {
int len = (int)strlen(pDest);
int len = (int)strlen(pDest.get());
if((len % 2) != 0) {
// In case of an odd length string, add a space char
strcat(pDest, " ");
strcat(pDest.get(), " ");
}
}
@ -638,84 +629,80 @@ char *ExportPCM::AdjustString(const wxString & wxStr, int sf_format)
bool ExportPCM::AddStrings(AudacityProject * WXUNUSED(project), SNDFILE *sf, const Tags *tags, int sf_format)
{
if (tags->HasTag(TAG_TITLE)) {
char * ascii7Str = AdjustString(tags->GetTag(TAG_TITLE), sf_format);
auto ascii7Str = AdjustString(tags->GetTag(TAG_TITLE), sf_format);
if (ascii7Str) {
sf_set_string(sf, SF_STR_TITLE, ascii7Str);
free(ascii7Str);
sf_set_string(sf, SF_STR_TITLE, ascii7Str.get());
}
}
if (tags->HasTag(TAG_ALBUM)) {
char * ascii7Str = AdjustString(tags->GetTag(TAG_ALBUM), sf_format);
auto ascii7Str = AdjustString(tags->GetTag(TAG_ALBUM), sf_format);
if (ascii7Str) {
sf_set_string(sf, SF_STR_ALBUM, ascii7Str);
free(ascii7Str);
sf_set_string(sf, SF_STR_ALBUM, ascii7Str.get());
}
}
if (tags->HasTag(TAG_ARTIST)) {
char * ascii7Str = AdjustString(tags->GetTag(TAG_ARTIST), sf_format);
auto ascii7Str = AdjustString(tags->GetTag(TAG_ARTIST), sf_format);
if (ascii7Str) {
sf_set_string(sf, SF_STR_ARTIST, ascii7Str);
free(ascii7Str);
sf_set_string(sf, SF_STR_ARTIST, ascii7Str.get());
}
}
if (tags->HasTag(TAG_COMMENTS)) {
char * ascii7Str = AdjustString(tags->GetTag(TAG_COMMENTS), sf_format);
auto ascii7Str = AdjustString(tags->GetTag(TAG_COMMENTS), sf_format);
if (ascii7Str) {
sf_set_string(sf, SF_STR_COMMENT, ascii7Str);
free(ascii7Str);
sf_set_string(sf, SF_STR_COMMENT, ascii7Str.get());
}
}
if (tags->HasTag(TAG_YEAR)) {
char * ascii7Str = AdjustString(tags->GetTag(TAG_YEAR), sf_format);
auto ascii7Str = AdjustString(tags->GetTag(TAG_YEAR), sf_format);
if (ascii7Str) {
sf_set_string(sf, SF_STR_DATE, ascii7Str);
free(ascii7Str);
sf_set_string(sf, SF_STR_DATE, ascii7Str.get());
}
}
if (tags->HasTag(TAG_GENRE)) {
char * ascii7Str = AdjustString(tags->GetTag(TAG_GENRE), sf_format);
auto ascii7Str = AdjustString(tags->GetTag(TAG_GENRE), sf_format);
if (ascii7Str) {
sf_set_string(sf, SF_STR_GENRE, ascii7Str);
free(ascii7Str);
sf_set_string(sf, SF_STR_GENRE, ascii7Str.get());
}
}
if (tags->HasTag(TAG_COPYRIGHT)) {
char * ascii7Str = AdjustString(tags->GetTag(TAG_COPYRIGHT), sf_format);
auto ascii7Str = AdjustString(tags->GetTag(TAG_COPYRIGHT), sf_format);
if (ascii7Str) {
sf_set_string(sf, SF_STR_COPYRIGHT, ascii7Str);
free(ascii7Str);
sf_set_string(sf, SF_STR_COPYRIGHT, ascii7Str.get());
}
}
if (tags->HasTag(TAG_SOFTWARE)) {
char * ascii7Str = AdjustString(tags->GetTag(TAG_SOFTWARE), sf_format);
auto ascii7Str = AdjustString(tags->GetTag(TAG_SOFTWARE), sf_format);
if (ascii7Str) {
sf_set_string(sf, SF_STR_SOFTWARE, ascii7Str);
free(ascii7Str);
sf_set_string(sf, SF_STR_SOFTWARE, ascii7Str.get());
}
}
if (tags->HasTag(TAG_TRACK)) {
char * ascii7Str = AdjustString(tags->GetTag(TAG_TRACK), sf_format);
auto ascii7Str = AdjustString(tags->GetTag(TAG_TRACK), sf_format);
if (ascii7Str) {
sf_set_string(sf, SF_STR_TRACKNUMBER, ascii7Str);
free(ascii7Str);
sf_set_string(sf, SF_STR_TRACKNUMBER, ascii7Str.get());
}
}
return true;
}
struct id3_tag_deleter {
void operator () (id3_tag *p) const { if (p) id3_tag_delete(p); }
};
using id3_tag_holder = std::unique_ptr<id3_tag, id3_tag_deleter>;
void ExportPCM::AddID3Chunk(wxString fName, const Tags *tags, int sf_format)
{
#ifdef USE_LIBID3TAG
struct id3_tag *tp = id3_tag_new();
id3_tag_holder tp { id3_tag_new() };
for (const auto &pair : tags->GetRange()) {
const auto &n = pair.first;
@ -756,8 +743,8 @@ void ExportPCM::AddID3Chunk(wxString fName, const Tags *tags, int sf_format)
id3_field_settextencoding(id3_frame_field(frame, 0), ID3_FIELD_TEXTENCODING_ISO_8859_1);
}
id3_ucs4_t *ucs4 =
id3_utf8_ucs4duplicate((id3_utf8_t *) (const char *) v.mb_str(wxConvUTF8));
MallocString<id3_ucs4_t> ucs4{
id3_utf8_ucs4duplicate((id3_utf8_t *) (const char *) v.mb_str(wxConvUTF8)) };
if (strcmp(name, ID3_FRAME_COMMENT) == 0) {
// A hack to get around iTunes not recognizing the comment. The
@ -767,23 +754,21 @@ void ExportPCM::AddID3Chunk(wxString fName, const Tags *tags, int sf_format)
// way of clearing the field, so do it directly.
id3_field *f = id3_frame_field(frame, 1);
memset(f->immediate.value, 0, sizeof(f->immediate.value));
id3_field_setfullstring(id3_frame_field(frame, 3), ucs4);
id3_field_setfullstring(id3_frame_field(frame, 3), ucs4.get());
}
else if (strcmp(name, "TXXX") == 0) {
id3_field_setstring(id3_frame_field(frame, 2), ucs4);
free(ucs4);
id3_field_setstring(id3_frame_field(frame, 2), ucs4.get());
ucs4 = id3_utf8_ucs4duplicate((id3_utf8_t *) (const char *) n.mb_str(wxConvUTF8));
ucs4.reset(id3_utf8_ucs4duplicate((id3_utf8_t *) (const char *) n.mb_str(wxConvUTF8)));
id3_field_setstring(id3_frame_field(frame, 1), ucs4);
id3_field_setstring(id3_frame_field(frame, 1), ucs4.get());
}
else {
id3_field_setstrings(id3_frame_field(frame, 1), 1, &ucs4);
auto addr = ucs4.get();
id3_field_setstrings(id3_frame_field(frame, 1), 1, &addr);
}
free(ucs4);
id3_tag_attachframe(tp, frame);
id3_tag_attachframe(tp.get(), frame);
}
tp->options &= (~ID3_TAG_OPTION_COMPRESSION); // No compression
@ -797,24 +782,19 @@ void ExportPCM::AddID3Chunk(wxString fName, const Tags *tags, int sf_format)
id3_length_t len;
len = id3_tag_render(tp, 0);
if (len == 0) {
id3_tag_delete(tp);
len = id3_tag_render(tp.get(), 0);
if (len == 0)
return;
}
if ((len % 2) != 0) len++; // Length must be even.
id3_byte_t *buffer = (id3_byte_t *)malloc(len);
if (buffer == NULL) {
id3_tag_delete(tp);
ArrayOf<id3_byte_t> buffer { len, true };
if (buffer == NULL)
return;
}
// Zero all locations, for ending odd UTF16 content
// correctly, i.e., two '\0's at the end.
memset(buffer, 0, len);
id3_tag_render(tp, buffer);
id3_tag_delete(tp);
id3_tag_render(tp.get(), buffer.get());
wxFFile f(fName, wxT("r+b"));
// FIXME: TRAP_ERR wxFFILE ops in Export PCM ID3 could fail.
@ -831,7 +811,7 @@ void ExportPCM::AddID3Chunk(wxString fName, const Tags *tags, int sf_format)
}
f.Write(&sz, 4);
f.Write(buffer, len);
f.Write(buffer.get(), len);
sz = (wxUint32) f.Tell() - 8;
if ((sf_format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AIFF)
@ -842,8 +822,6 @@ void ExportPCM::AddID3Chunk(wxString fName, const Tags *tags, int sf_format)
f.Close();
}
free(buffer);
#endif
return;
}

View File

@ -732,13 +732,10 @@ ProgressResult FFmpegImportFileHandle::WriteData(streamContext *sc)
}
// Allocate the buffer to store audio.
int insamples = sc->m_decodedAudioSamplesValidSiz / sc->m_samplesize;
int nChannels = sc->m_stream->codec->channels < sc->m_initialchannels ? sc->m_stream->codec->channels : sc->m_initialchannels;
uint8_t **tmp = (uint8_t **) malloc(sizeof(uint8_t *) * nChannels);
for (int chn = 0; chn < nChannels; chn++)
{
tmp[chn] = (uint8_t *) malloc(sc->m_osamplesize * (insamples / nChannels));
}
auto insamples = sc->m_decodedAudioSamplesValidSiz / sc->m_samplesize;
size_t nChannels = std::min(sc->m_stream->codec->channels, sc->m_initialchannels);
ArraysOf<uint8_t> tmp{ nChannels, sc->m_osamplesize * (insamples / nChannels) };
// Separate the channels and convert input sample format to 16-bit
uint8_t *in = sc->m_decodedAudioSamples.get();
@ -754,36 +751,31 @@ ProgressResult FFmpegImportFileHandle::WriteData(streamContext *sc)
{
case AV_SAMPLE_FMT_U8:
case AV_SAMPLE_FMT_U8P:
((int16_t *)tmp[chn])[index] = (int16_t) (*(uint8_t *)in - 0x80) << 8;
((int16_t *)tmp[chn].get())[index] = (int16_t) (*(uint8_t *)in - 0x80) << 8;
break;
case AV_SAMPLE_FMT_S16:
case AV_SAMPLE_FMT_S16P:
((int16_t *)tmp[chn])[index] = (int16_t) *(int16_t *)in;
((int16_t *)tmp[chn].get())[index] = (int16_t) *(int16_t *)in;
break;
case AV_SAMPLE_FMT_S32:
case AV_SAMPLE_FMT_S32P:
((float *)tmp[chn])[index] = (float) *(int32_t *)in * (1.0 / (1u << 31));
((float *)tmp[chn].get())[index] = (float) *(int32_t *)in * (1.0 / (1u << 31));
break;
case AV_SAMPLE_FMT_FLT:
case AV_SAMPLE_FMT_FLTP:
((float *)tmp[chn])[index] = (float) *(float *)in;
((float *)tmp[chn].get())[index] = (float) *(float *)in;
break;
case AV_SAMPLE_FMT_DBL:
case AV_SAMPLE_FMT_DBLP:
((float *)tmp[chn])[index] = (float) *(double *)in;
((float *)tmp[chn].get())[index] = (float) *(double *)in;
break;
default:
wxLogError(wxT("Stream %d has unrecognized sample format %d."), streamid, sc->m_samplefmt);
for (int chn=0; chn < nChannels; chn++)
{
free(tmp[chn]);
}
free(tmp);
return ProgressResult::Success;
break;
}
@ -798,12 +790,9 @@ ProgressResult FFmpegImportFileHandle::WriteData(streamContext *sc)
auto iter2 = iter->begin();
for (int chn=0; chn < nChannels; ++iter2, ++chn)
{
iter2->get()->Append((samplePtr)tmp[chn],sc->m_osamplefmt,index);
free(tmp[chn]);
iter2->get()->Append((samplePtr)tmp[chn].get(), sc->m_osamplefmt, index);
}
free(tmp);
// Try to update the progress indicator (and see if user wants to cancel)
auto updateResult = ProgressResult::Success;
int64_t filesize = avio_size(mFormatContext->pb);

View File

@ -356,9 +356,8 @@ void MP3ImportFileHandle::ImportID3(Tags *tags)
else if (frame->nfields == 3) {
ustr = id3_field_getstring(&frame->fields[1]);
if (ustr) {
char *str = (char *)id3_ucs4_utf8duplicate(ustr);
n = UTF8CTOWX(str);
free(str);
MallocString<> str{ (char *)id3_ucs4_utf8duplicate(ustr) };
n = UTF8CTOWX(str.get());
}
ustr = id3_field_getstring(&frame->fields[2]);
@ -368,9 +367,8 @@ void MP3ImportFileHandle::ImportID3(Tags *tags)
}
if (ustr) {
char *str = (char *)id3_ucs4_utf8duplicate(ustr);
v = UTF8CTOWX(str);
free(str);
MallocString<> str{ (char *)id3_ucs4_utf8duplicate(ustr) };
v = UTF8CTOWX(str.get());
}
if (!n.IsEmpty() && !v.IsEmpty()) {

View File

@ -324,6 +324,11 @@ How do you want to import the current file(s)?"), oldCopyPref == wxT("copy") ? _
return oldCopyPref;
}
struct id3_tag_deleter {
void operator () (id3_tag *p) const { if (p) id3_tag_delete(p); }
};
using id3_tag_holder = std::unique_ptr<id3_tag, id3_tag_deleter>;
ProgressResult PCMImportFileHandle::Import(TrackFactory *trackFactory,
TrackHolders &outTracks,
Tags *tags)
@ -584,14 +589,17 @@ ProgressResult PCMImportFileHandle::Import(TrackFactory *trackFactory,
continue;
}
id3_byte_t *buffer = (id3_byte_t *)malloc(len);
if (!buffer) {
break;
}
f.Read(buffer, len);
struct id3_tag *tp = id3_tag_parse(buffer, len);
free(buffer);
id3_tag_holder tp;
{
ArrayOf<id3_byte_t> buffer{ len };
if (!buffer) {
break;
}
f.Read(buffer.get(), len);
tp.reset( id3_tag_parse(buffer.get(), len) );
}
if (!tp) {
break;
@ -662,9 +670,8 @@ ProgressResult PCMImportFileHandle::Import(TrackFactory *trackFactory,
else if (frame->nfields == 3) {
ustr = id3_field_getstring(&frame->fields[1]);
if (ustr) {
char *str = (char *)id3_ucs4_utf8duplicate(ustr);
n = UTF8CTOWX(str);
free(str);
MallocString<> str{ (char *)id3_ucs4_utf8duplicate(ustr) };
n = UTF8CTOWX(str.get());
}
ustr = id3_field_getstring(&frame->fields[2]);
@ -674,9 +681,8 @@ ProgressResult PCMImportFileHandle::Import(TrackFactory *trackFactory,
}
if (ustr) {
char *str = (char *)id3_ucs4_utf8duplicate(ustr);
v = UTF8CTOWX(str);
free(str);
MallocString<> str{ (char *)id3_ucs4_utf8duplicate(ustr) };
v = UTF8CTOWX(str.get());
}
if (!n.IsEmpty() && !v.IsEmpty()) {
@ -692,7 +698,6 @@ ProgressResult PCMImportFileHandle::Import(TrackFactory *trackFactory,
}
}
id3_tag_delete(tp);
break;
}

View File

@ -319,18 +319,22 @@ ProgressResult QTImportFileHandle::Import(TrackFactory *trackFactory,
format = floatSample;
break;
}
AudioBufferList *abl = (AudioBufferList *)
calloc(1, offsetof(AudioBufferList, mBuffers) + (sizeof(AudioBuffer) * numchan));
std::unique_ptr<AudioBufferList, freer> abl
{ static_cast<AudioBufferList *>
(calloc(1, offsetof(AudioBufferList, mBuffers) +
(sizeof(AudioBuffer) * numchan))) };
abl->mNumberBuffers = numchan;
TrackHolders channels{ numchan };
ArraysOf<unsigned char> holders{ numchan, sizeof(float) * bufsize };
int c;
for (c = 0; c < numchan; c++) {
abl->mBuffers[c].mNumberChannels = 1;
abl->mBuffers[c].mDataByteSize = sizeof(float) * bufsize;
abl->mBuffers[c].mData = malloc(abl->mBuffers[c].mDataByteSize);
abl->mBuffers[c].mData = holders[c].get();
channels[c] = trackFactory->NewWaveTrack(format);
channels[c]->SetRate(desc.mSampleRate);
@ -352,7 +356,7 @@ ProgressResult QTImportFileHandle::Import(TrackFactory *trackFactory,
err = MovieAudioExtractionFillBuffer(maer,
&numFrames,
abl,
abl.get(),
&flags);
if (err != noErr) {
wxMessageBox(_("Unable to get fill buffer"));
@ -383,12 +387,7 @@ ProgressResult QTImportFileHandle::Import(TrackFactory *trackFactory,
outTracks.swap(channels);
}
for (c = 0; c < numchan; c++) {
free(abl->mBuffers[c].mData);
}
free(abl);
//
// Extract any metadata
//
@ -463,7 +462,6 @@ void QTImportFileHandle::AddMetadata(Tags *tags)
continue;
}
QTPropertyValuePtr outValPtr = nil;
QTPropertyValueType outPropType;
::ByteCount outPropValueSize;
::ByteCount outPropValueSizeUsed = 0;
@ -495,7 +493,7 @@ void QTImportFileHandle::AddMetadata(Tags *tags)
}
// Alloc memory for it
outValPtr = malloc(outPropValueSize);
ArrayOf<char> outVals{ outPropValueSize };
// Retrieve the data
err = QTMetaDataGetItemProperty(metaDataRef,
@ -503,24 +501,22 @@ void QTImportFileHandle::AddMetadata(Tags *tags)
kPropertyClass_MetaDataItem,
kQTMetaDataItemPropertyID_Value,
outPropValueSize,
outValPtr,
outVals.get(),
&outPropValueSizeUsed);
if (err != noErr) {
free(outValPtr);
if (err != noErr)
continue;
}
wxString v = wxT("");
switch (dataType)
{
case kQTMetaDataTypeUTF8:
v = wxString((char *)outValPtr, wxConvUTF8);
v = wxString(outVals.get(), wxConvUTF8);
break;
case kQTMetaDataTypeUTF16BE:
{
wxMBConvUTF16BE conv;
v = wxString((char *)outValPtr, conv);
v = wxString(outVals.get(), conv);
}
break;
}
@ -528,8 +524,6 @@ void QTImportFileHandle::AddMetadata(Tags *tags)
if (!v.IsEmpty()) {
tags->SetTag(names[i].name, v);
}
free(outValPtr);
}
// we are done so release our metadata object

View File

@ -13,7 +13,9 @@
**********************************************************************/
#include "../Audacity.h"
#include "RawAudioGuess.h"
#include "../MemoryX.h"
#include <stdio.h>
#include <stdlib.h>
@ -31,10 +33,9 @@
static FILE *g_raw_debug_file = NULL;
#endif
static float AmpStat(float *data, int len)
static float AmpStat(float *data, size_t len)
{
float sum, sumofsquares, avg, variance, dev;
int i;
if (len == 0)
return 1.0;
@ -44,7 +45,7 @@ static float AmpStat(float *data, int len)
sum = 0.0;
sumofsquares = 0.0;
for (i = 0; i < len; i++) {
for (size_t i = 0; i < len; i++) {
float x = fabs(data[i]);
sum += x;
sumofsquares += x * x;
@ -58,31 +59,29 @@ static float AmpStat(float *data, int len)
return dev;
}
static float JumpStat(float *data, int len)
static float JumpStat(float *data, size_t len)
{
float avg;
int i;
/* Calculate 1.0 - avg jump
* A score near 1.0 means avg jump is pretty small
*/
avg = 0.0;
for (i = 0; i < len - 1; i++)
for (size_t i = 0; i + 1 < len; i++)
avg += fabs(data[i + 1] - data[i]);
avg = 1.0 - (avg / (len - 1) / 2.0);
return avg;
}
static float SecondDStat(float *data, int len)
static float SecondDStat(float *data, size_t len)
{
int i;
float v1=0, v2=0;
float a1=0, a2=0;
float sum=0;
for (i = 1; i < len; i++) {
for (size_t i = 1; i < len; i++) {
a2 = a1;
v2 = v1;
v1 = data[i]-data[i-1];
@ -93,12 +92,11 @@ static float SecondDStat(float *data, int len)
return sum/len;
}
static float RedundantStereo(float *data, int len)
static float RedundantStereo(float *data, size_t len)
{
int i;
int c = 0;
for (i = 1; i < len - 1; i += 2)
for (size_t i = 1; i + 1 < len; i += 2)
if (fabs(data[i + 1] - data[i]) > 2*fabs(data[i] - data[i - 1]) ||
2*fabs(data[i + 1] - data[i]) < fabs(data[i] - data[i - 1]))
c++;
@ -109,14 +107,13 @@ static float RedundantStereo(float *data, int len)
static void ExtractFloats(bool doublePrec,
bool bigendian,
bool stereo,
int offset,
char *rawData, int dataSize,
float *data1, float *data2, int *len1, int *len2)
size_t offset,
char *rawData, size_t dataSize,
float *data1, float *data2, size_t *len1, size_t *len2)
{
int rawCount = 0;
int dataCount1 = 0;
int dataCount2 = 0;
int i;
size_t rawCount = 0;
size_t dataCount1 = 0;
size_t dataCount2 = 0;
bool swap;
*len1 = 0;
@ -124,7 +121,7 @@ static void ExtractFloats(bool doublePrec,
if (offset) {
rawData += offset;
dataSize -= offset;
dataSize -= std::min(dataSize, offset);
}
#if WORDS_BIGENDIAN
@ -142,10 +139,10 @@ static void ExtractFloats(bool doublePrec,
u.d = 0.0f;
while (rawCount + 7 < dataSize) {
if (swap)
for(i=0; i<8; i++)
for(size_t i = 0; i < 8; i++)
u.c[7-i] = rawData[rawCount+i];
else
for(i=0; i<8; i++)
for(size_t i = 0; i < 8; i++)
u.c[i] = rawData[rawCount+i];
data1[dataCount1] = (float)u.d;
dataCount1++;
@ -161,10 +158,10 @@ static void ExtractFloats(bool doublePrec,
u.f = 0.0f;
while (rawCount + 3 < dataSize) {
if (swap)
for(i=0; i<4; i++)
for(size_t i = 0; i < 4; i++)
u.c[3-i] = rawData[rawCount+i];
else
for(i=0; i<4; i++)
for(size_t i = 0; i < 4; i++)
u.c[i] = rawData[rawCount+i];
data1[dataCount1] = u.f;
dataCount1++;
@ -174,7 +171,7 @@ static void ExtractFloats(bool doublePrec,
if (stereo) {
dataCount1 /= 2;
for(i=0; i<dataCount1; i++) {
for(size_t i = 0; i < dataCount1; i++) {
data2[i] = data1[2*i+1];
data1[i] = data1[2*i];
}
@ -191,12 +188,11 @@ static void Extract(bool bits16,
bool bigendian,
bool offset,
char *rawData, int dataSize,
float *data1, float *data2, int *len1, int *len2)
float *data1, float *data2, size_t *len1, size_t *len2)
{
int rawCount = 0;
int dataCount1 = 0;
int dataCount2 = 0;
int i;
size_t rawCount = 0;
size_t dataCount1 = 0;
size_t dataCount2 = 0;
*len1 = 0;
*len2 = 0;
@ -275,7 +271,7 @@ static void Extract(bool bits16,
if (stereo) {
dataCount1 /= 2;
for(i=0; i<dataCount1; i++) {
for(size_t i = 0; i < dataCount1; i++) {
data2[i] = data1[2*i+1];
data1[i] = data1[2*i];
}
@ -286,33 +282,27 @@ static void Extract(bool bits16,
*len2 = dataCount2;
}
static int GuessFloatFormats(int numTests, char **rawData, int dataSize,
int *out_offset, unsigned *out_channels)
static int GuessFloatFormats(unsigned numTests, const ArrayOf<char> rawData[], size_t dataSize,
size_t *out_offset, unsigned *out_channels)
{
int format;
int bestOffset = 0;
size_t bestOffset = 0;
int bestEndian = 0;
int bestPrec = 0;
float bestSmoothAvg = 1000.0;
int offset;
int endian;
int prec;
float *data1, *data2;
int len1;
int len2;
int test;
int i;
size_t len1;
size_t len2;
bool guessStereo = false;
int stereoVotes = 0;
int monoVotes = 0;
unsigned stereoVotes = 0;
unsigned monoVotes = 0;
#if RAW_GUESS_DEBUG
FILE *af = g_raw_debug_file;
fprintf(af, "Testing float\n");
#endif
data1 = (float *)malloc((dataSize + 4) * sizeof(float));
data2 = (float *)malloc((dataSize + 4) * sizeof(float));
ArrayOf<float> data1{ dataSize + 4 };
ArrayOf<float> data2{ dataSize + 4 };
/*
* First determine if it is possibly in a floating-point
@ -332,28 +322,29 @@ static int GuessFloatFormats(int numTests, char **rawData, int dataSize,
* floats with a 1-byte offset.
*/
for(prec=0; prec<2; prec++) {
for(endian=0; endian<2; endian++) {
for(offset=0; offset<(4*prec+4); offset++) {
int finiteVotes = 0;
int maxminVotes = 0;
for(int prec = 0; prec < 2; prec++) {
for(int endian = 0; endian < 2; endian++) {
for(size_t offset = 0; offset < (4 * prec + 4); offset++) {
unsigned finiteVotes = 0;
unsigned maxminVotes = 0;
float smoothAvg = 0;
#if RAW_GUESS_DEBUG
fprintf(af, "prec=%d endian=%d offset=%d\n",
prec, endian, offset);
prec, endian, (int)offset);
#endif
for(test=0; test<numTests; test++) {
for(unsigned test = 0; test < numTests; test++) {
float min, max;
ExtractFloats(prec?true:false, endian?true:false,
ExtractFloats(prec == 1, endian == 1,
true, /* stereo */
offset,
rawData[test], dataSize,
data1, data2, &len1, &len2);
rawData[test].get(), dataSize,
data1.get(), data2.get(), &len1, &len2);
for(i=0; i<len1; i++)
size_t i = 0;
for(; i < len1; i++)
if (!(data1[i]>=0 || data1[i]<=0) ||
!(data2[i]>=0 || data2[i]<=0))
break;
@ -362,13 +353,13 @@ static int GuessFloatFormats(int numTests, char **rawData, int dataSize,
min = data1[0];
max = data1[0];
for(i=1; i<len1; i++) {
for(i = 1; i < len1; i++) {
if (data1[i]<min)
min = data1[i];
if (data1[i]>max)
max = data1[i];
}
for(i=1; i<len2; i++) {
for(i = 1; i < len2; i++) {
if (data2[i]<min)
min = data2[i];
if (data2[i]>max)
@ -379,13 +370,13 @@ static int GuessFloatFormats(int numTests, char **rawData, int dataSize,
max > 0.01 && max <= 100000)
maxminVotes++;
smoothAvg += SecondDStat(data1, len1) / max;
smoothAvg += SecondDStat(data1.get(), len1) / max;
}
smoothAvg /= numTests;
#if RAW_GUESS_DEBUG
fprintf(af, "finite: %d/%d maxmin: %d/%d smooth: %f\n",
fprintf(af, "finite: %ud/%ud maxmin: %ud/%ud smooth: %f\n",
finiteVotes, numTests, maxminVotes, numTests,
smoothAvg);
#endif
@ -410,11 +401,8 @@ static int GuessFloatFormats(int numTests, char **rawData, int dataSize,
* main function will try guessing an integer format.
*/
if (bestSmoothAvg >= 1000.0) {
free(data1);
free(data2);
if (bestSmoothAvg >= 1000.0)
return 0;
}
/*
* We still have to test for mono/stereo. For an explanation
@ -422,22 +410,22 @@ static int GuessFloatFormats(int numTests, char **rawData, int dataSize,
* tests for 8-bit or 16-bit data.
*/
for (test = 0; test < numTests; test++) {
for (unsigned test = 0; test < numTests; test++) {
float leftChannel, rightChannel, combinedChannel;
ExtractFloats(bestPrec?true:false, bestEndian?true:false,
ExtractFloats(bestPrec == 1, bestEndian == 1,
true, /* stereo */
bestOffset,
rawData[test], dataSize,
data1, data2, &len1, &len2);
leftChannel = JumpStat(data1, len1);
rightChannel = JumpStat(data2, len2);
ExtractFloats(bestPrec?true:false, bestEndian?true:false,
rawData[test].get(), dataSize,
data1.get(), data2.get(), &len1, &len2);
leftChannel = JumpStat(data1.get(), len1);
rightChannel = JumpStat(data2.get(), len2);
ExtractFloats(bestPrec == 1, bestEndian == 1,
false, /* stereo */
bestOffset,
rawData[test], dataSize,
data1, data2, &len1, &len2);
combinedChannel = JumpStat(data1, len1);
rawData[test].get(), dataSize,
data1.get(), data2.get(), &len1, &len2);
combinedChannel = JumpStat(data1.get(), len1);
if (leftChannel > combinedChannel
&& rightChannel > combinedChannel)
@ -447,30 +435,27 @@ static int GuessFloatFormats(int numTests, char **rawData, int dataSize,
}
#if RAW_GUESS_DEBUG
fprintf(af, "stereo: %d mono: %d\n", stereoVotes, monoVotes);
fprintf(af, "stereo: %ud mono: %ud\n", stereoVotes, monoVotes);
#endif
if (stereoVotes > monoVotes)
guessStereo = true;
else
guessStereo = false;
guessStereo = (stereoVotes > monoVotes);
if (guessStereo == false) {
if (!guessStereo) {
/* test for repeated-byte, redundant stereo */
int rstereoVotes = 0;
int rmonoVotes = 0;
unsigned rstereoVotes = 0;
unsigned rmonoVotes = 0;
for (test = 0; test < numTests; test++) {
for (unsigned test = 0; test < numTests; test++) {
float redundant;
ExtractFloats(bestPrec?true:false, bestEndian?true:false,
ExtractFloats(bestPrec == 1, bestEndian == 1,
false, /* stereo */
bestOffset,
rawData[test], dataSize,
data1, data2, &len1, &len2);
redundant = RedundantStereo(data1, len1);
rawData[test].get(), dataSize,
data1.get(), data2.get(), &len1, &len2);
redundant = RedundantStereo(data1.get(), len1);
#if RAW_GUESS_DEBUG
fprintf(af, "redundant: %f\n", redundant);
@ -483,11 +468,10 @@ static int GuessFloatFormats(int numTests, char **rawData, int dataSize,
}
#if RAW_GUESS_DEBUG
fprintf(af, "rstereo: %d rmono: %d\n", rstereoVotes, rmonoVotes);
fprintf(af, "rstereo: %ud rmono: %ud\n", rstereoVotes, rmonoVotes);
#endif
if (rstereoVotes > rmonoVotes)
guessStereo = true;
guessStereo = (rstereoVotes > rmonoVotes);
}
@ -515,25 +499,22 @@ static int GuessFloatFormats(int numTests, char **rawData, int dataSize,
else
format |= SF_ENDIAN_LITTLE;
free(data1);
free(data2);
return format;
}
static int Guess8Bit(int numTests, char **rawData, int dataSize, unsigned *out_channels)
static int Guess8Bit(unsigned numTests, const ArrayOf<char> rawData[], size_t dataSize, unsigned *out_channels)
{
bool guessSigned = false;
bool guessStereo = false;
int signvotes = 0;
int unsignvotes = 0;
int stereoVotes = 0;
int monoVotes = 0;
float *data1 = (float *)malloc((dataSize + 4) * sizeof(float));
float *data2 = (float *)malloc((dataSize + 4) * sizeof(float));
int len1;
int len2;
int test;
unsigned signvotes = 0;
unsigned unsignvotes = 0;
unsigned stereoVotes = 0;
unsigned monoVotes = 0;
ArrayOf<float> data1 { dataSize + 4 };
ArrayOf<float> data2 { dataSize + 4 };
size_t len1;
size_t len2;
#if RAW_GUESS_DEBUG
FILE *af = g_raw_debug_file;
@ -551,19 +532,19 @@ static int Guess8Bit(int numTests, char **rawData, int dataSize, unsigned *out_c
* and returns a value 0-1. 0 is maximally discontinuous, 1 is smooth.
*/
for (test = 0; test < numTests; test++) {
for (unsigned test = 0; test < numTests; test++) {
float signL, signR, unsignL, unsignR;
Extract(0, 1, 1, 0, /* 8-bit signed stereo */
false, rawData[test], dataSize,
data1, data2, &len1, &len2);
signL = JumpStat(data1, len1);
signR = JumpStat(data2, len2);
false, rawData[test].get(), dataSize,
data1.get(), data2.get(), &len1, &len2);
signL = JumpStat(data1.get(), len1);
signR = JumpStat(data2.get(), len2);
Extract(0, 0, 1, 0, /* 8-bit unsigned stereo */
false, rawData[test], dataSize,
data1, data2, &len1, &len2);
unsignL = JumpStat(data1, len1);
unsignR = JumpStat(data2, len2);
false, rawData[test].get(), dataSize,
data1.get(), data2.get(), &len1, &len2);
unsignL = JumpStat(data1.get(), len1);
unsignR = JumpStat(data2.get(), len2);
if (signL > unsignL)
signvotes++;
@ -577,13 +558,10 @@ static int Guess8Bit(int numTests, char **rawData, int dataSize, unsigned *out_c
}
#if RAW_GUESS_DEBUG
fprintf(af, "sign: %d unsign: %d\n", signvotes, unsignvotes);
fprintf(af, "sign: %ud unsign: %ud\n", signvotes, unsignvotes);
#endif
if (signvotes > unsignvotes)
guessSigned = true;
else
guessSigned = false;
guessSigned = (signvotes > unsignvotes);
#if RAW_GUESS_DEBUG
if (guessSigned)
@ -598,16 +576,16 @@ static int Guess8Bit(int numTests, char **rawData, int dataSize, unsigned *out_c
* the entire stream interpreted as one channel.
*/
for (test = 0; test < numTests; test++) {
for (unsigned test = 0; test < numTests; test++) {
float leftChannel, rightChannel, combinedChannel;
Extract(0, guessSigned, 1, 0, 0, rawData[test], dataSize, data1,
data2, &len1, &len2);
leftChannel = JumpStat(data1, len1);
rightChannel = JumpStat(data2, len2);
Extract(0, guessSigned, 0, 0, 0, rawData[test], dataSize, data1,
data2, &len1, &len2);
combinedChannel = JumpStat(data1, len1);
Extract(0, guessSigned, 1, 0, 0, rawData[test].get(), dataSize, data1.get(),
data2.get(), &len1, &len2);
leftChannel = JumpStat(data1.get(), len1);
rightChannel = JumpStat(data2.get(), len2);
Extract(0, guessSigned, 0, 0, 0, rawData[test].get(), dataSize, data1.get(),
data2.get(), &len1, &len2);
combinedChannel = JumpStat(data1.get(), len1);
if (leftChannel > combinedChannel
&& rightChannel > combinedChannel)
@ -617,27 +595,24 @@ static int Guess8Bit(int numTests, char **rawData, int dataSize, unsigned *out_c
}
#if RAW_GUESS_DEBUG
fprintf(af, "stereo: %d mono: %d\n", stereoVotes, monoVotes);
fprintf(af, "stereo: %ud mono: %ud\n", stereoVotes, monoVotes);
#endif
if (stereoVotes > monoVotes)
guessStereo = true;
else
guessStereo = false;
guessStereo = (stereoVotes > monoVotes);
if (guessStereo == false) {
if (!guessStereo) {
/* test for repeated-byte, redundant stereo */
int rstereoVotes = 0;
int rmonoVotes = 0;
unsigned rstereoVotes = 0;
unsigned rmonoVotes = 0;
for (test = 0; test < numTests; test++) {
for (unsigned test = 0; test < numTests; test++) {
float redundant;
Extract(0, guessSigned, 0, 0, 0, rawData[test], dataSize,
data1, data2, &len1, &len2);
redundant = RedundantStereo(data1, len1);
Extract(0, guessSigned, 0, 0, 0, rawData[test].get(), dataSize,
data1.get(), data2.get(), &len1, &len2);
redundant = RedundantStereo(data1.get(), len1);
#if RAW_GUESS_DEBUG
fprintf(af, "redundant: %f\n", redundant);
@ -650,11 +625,10 @@ static int Guess8Bit(int numTests, char **rawData, int dataSize, unsigned *out_c
}
#if RAW_GUESS_DEBUG
fprintf(af, "rstereo: %d rmono: %d\n", rstereoVotes, rmonoVotes);
fprintf(af, "rstereo: %ud rmono: %ud\n", rstereoVotes, rmonoVotes);
#endif
if (rstereoVotes > rmonoVotes)
guessStereo = true;
guessStereo = (rstereoVotes > rmonoVotes);
}
@ -665,9 +639,6 @@ static int Guess8Bit(int numTests, char **rawData, int dataSize, unsigned *out_c
fprintf(af, "mono\n");
#endif
free(data1);
free(data2);
if (guessStereo)
*out_channels = 2;
else
@ -679,27 +650,26 @@ static int Guess8Bit(int numTests, char **rawData, int dataSize, unsigned *out_c
return SF_FORMAT_RAW | SF_FORMAT_PCM_U8;
}
static int Guess16Bit(int numTests, char **rawData,
int dataSize, bool evenMSB,
int *out_offset, unsigned *out_channels)
static int Guess16Bit(unsigned numTests, const ArrayOf<char> rawData[],
size_t dataSize, bool evenMSB,
size_t *out_offset, unsigned *out_channels)
{
int format;
bool guessSigned = false;
bool guessStereo = false;
bool guessBigEndian = false;
bool guessOffset = false;
int signvotes = 0;
int unsignvotes = 0;
int stereoVotes = 0;
int monoVotes = 0;
int formerVotes = 0;
int latterVotes = 0;
char *rawData2 = (char *)malloc(dataSize + 4);
float *data1 = (float *)malloc((dataSize + 4) * sizeof(float));
float *data2 = (float *)malloc((dataSize + 4) * sizeof(float));
int len1;
int len2;
int test;
unsigned signvotes = 0;
unsigned unsignvotes = 0;
unsigned stereoVotes = 0;
unsigned monoVotes = 0;
unsigned formerVotes = 0;
unsigned latterVotes = 0;
ArrayOf<char> rawData2{ dataSize + 4 };
ArrayOf<float> data1{ dataSize + 4 };
ArrayOf<float> data2{ dataSize + 4 };
size_t len1;
size_t len2;
#if RAW_GUESS_DEBUG
FILE *af = g_raw_debug_file;
@ -710,26 +680,25 @@ static int Guess16Bit(int numTests, char **rawData,
* Do the signed/unsigned test by using only the MSB.
*/
for (test = 0; test < numTests; test++) {
for (unsigned test = 0; test < numTests; test++) {
float signL, signR, unsignL, unsignR;
int i;
/* Extract a NEW array of the MSBs only: */
for (i = 0; i < dataSize / 2; i++)
for (size_t i = 0; i < dataSize / 2; i++)
rawData2[i] = rawData[test][2 * i + (evenMSB ? 0 : 1)];
/* Test signed/unsigned of the MSB */
Extract(0, 1, 1, 0, /* 8-bit signed stereo */
0, rawData2, dataSize / 2, data1, data2, &len1, &len2);
signL = JumpStat(data1, len1);
signR = JumpStat(data2, len2);
0, rawData2.get(), dataSize / 2, data1.get(), data2.get(), &len1, &len2);
signL = JumpStat(data1.get(), len1);
signR = JumpStat(data2.get(), len2);
Extract(0, 0, 1, 0, /* 8-bit unsigned stereo */
0, rawData2, dataSize / 2, data1, data2, &len1, &len2);
unsignL = JumpStat(data1, len1);
unsignR = JumpStat(data2, len2);
0, rawData2.get(), dataSize / 2, data1.get(), data2.get(), &len1, &len2);
unsignL = JumpStat(data1.get(), len1);
unsignR = JumpStat(data2.get(), len2);
if (signL > unsignL)
signvotes++;
@ -743,13 +712,10 @@ static int Guess16Bit(int numTests, char **rawData,
}
#if RAW_GUESS_DEBUG
fprintf(af, "sign: %d unsign: %d\n", signvotes, unsignvotes);
fprintf(af, "sign: %ud unsign: %ud\n", signvotes, unsignvotes);
#endif
if (signvotes > unsignvotes)
guessSigned = true;
else
guessSigned = false;
guessSigned = (signvotes > unsignvotes);
#if RAW_GUESS_DEBUG
if (guessSigned)
@ -762,22 +728,21 @@ static int Guess16Bit(int numTests, char **rawData,
* Test mono/stereo using only the MSB
*/
for (test = 0; test < numTests; test++) {
for (unsigned test = 0; test < numTests; test++) {
float leftChannel, rightChannel, combinedChannel;
int i;
/* Extract a NEW array of the MSBs only: */
for (i = 0; i < dataSize / 2; i++)
for (size_t i = 0; i < dataSize / 2; i++)
rawData2[i] = rawData[test][2 * i + (evenMSB ? 0 : 1)];
Extract(0, guessSigned, 1, 0, 0,
rawData2, dataSize / 2, data1, data2, &len1, &len2);
leftChannel = JumpStat(data1, len1);
rightChannel = JumpStat(data2, len2);
rawData2.get(), dataSize / 2, data1.get(), data2.get(), &len1, &len2);
leftChannel = JumpStat(data1.get(), len1);
rightChannel = JumpStat(data2.get(), len2);
Extract(0, guessSigned, 0, 0, 0,
rawData2, dataSize / 2, data1, data2, &len1, &len2);
combinedChannel = JumpStat(data1, len1);
rawData2.get(), dataSize / 2, data1.get(), data2.get(), &len1, &len2);
combinedChannel = JumpStat(data1.get(), len1);
if (leftChannel > combinedChannel
&& rightChannel > combinedChannel)
@ -787,35 +752,31 @@ static int Guess16Bit(int numTests, char **rawData,
}
#if RAW_GUESS_DEBUG
fprintf(af, "stereoVotes: %d monoVotes: %d\n", stereoVotes, monoVotes);
fprintf(af, "stereoVotes: %ud monoVotes: %ud\n", stereoVotes, monoVotes);
#endif
if (stereoVotes > monoVotes)
guessStereo = true;
else
guessStereo = false;
guessStereo = (stereoVotes > monoVotes);
if (guessStereo == false) {
if (!guessStereo) {
/* Test for repeated-byte, redundant stereo */
int rstereoVotes = 0;
int rmonoVotes = 0;
unsigned rstereoVotes = 0;
unsigned rmonoVotes = 0;
for (test = 0; test < numTests; test++) {
for (unsigned test = 0; test < numTests; test++) {
float redundant;
int i;
/* Extract a NEW array of the MSBs only: */
for (i = 0; i < dataSize / 2; i++)
for (size_t i = 0; i < dataSize / 2; i++)
rawData2[i] = rawData[test][2 * i + (evenMSB ? 0 : 1)];
Extract(0, guessSigned, 0, 0, 0, rawData2, dataSize / 2,
data1, data2, &len1, &len2);
Extract(0, guessSigned, 0, 0, 0, rawData2.get(), dataSize / 2,
data1.get(), data2.get(), &len1, &len2);
redundant = RedundantStereo(data1, len1);
redundant = RedundantStereo(data1.get(), len1);
if (redundant > 0.8)
rstereoVotes++;
@ -824,12 +785,11 @@ static int Guess16Bit(int numTests, char **rawData,
}
#if RAW_GUESS_DEBUG
fprintf(af, "rstereoVotes: %d rmonoVotes: %d\n",
fprintf(af, "rstereoVotes: %ud rmonoVotes: %ud\n",
rstereoVotes, rmonoVotes);
#endif
if (rstereoVotes > rmonoVotes)
guessStereo = true;
guessStereo = (rstereoVotes > rmonoVotes);
}
@ -854,29 +814,29 @@ static int Guess16Bit(int numTests, char **rawData,
fprintf(af, "evenMSB: %d BE: %d\n", evenMSB, guessBigEndian);
#endif
for (test = 0; test < numTests; test++) {
for (unsigned test = 0; test < numTests; test++) {
float former, latter;
int i, offs;
int offs;
/* Extract a NEW array of the MSBs only: */
if (guessStereo)
for (i = 0; i < (dataSize/4)-1; i++)
for (size_t i = 0; i + 1 < (dataSize / 4); i++)
rawData2[i] =
rawData[test][4 * i + (evenMSB ? 0 : 1)];
else
for (i = 0; i < (dataSize/2)-1; i++)
for (size_t i = 0; i + 1 < (dataSize / 2); i++)
rawData2[i] =
rawData[test][2 * i + (evenMSB ? 0 : 1)];
former = 0.0;
Extract(1, guessSigned, guessStereo, guessBigEndian, guessOffset,
rawData[test], dataSize-4, data1, data2, &len1, &len2);
rawData[test].get(), dataSize-4, data1.get(), data2.get(), &len1, &len2);
offs=(!guessBigEndian);
for(i=3; i<len1-4; i++) {
for(size_t i = 3; i + 4 < len1; i++) {
if (rawData2[offs+i-2]==rawData2[offs+i-1] &&
rawData2[offs+i]==rawData2[offs+i-1]+1 &&
rawData2[offs+i]==rawData2[offs+i+1]) {
@ -886,12 +846,12 @@ static int Guess16Bit(int numTests, char **rawData,
latter = 0.0;
Extract(1, guessSigned, guessStereo, !guessBigEndian,
!guessOffset, rawData[test], dataSize, data1, data2,
!guessOffset, rawData[test].get(), dataSize, data1.get(), data2.get(),
&len1, &len2);
offs=(guessBigEndian);
for(i=3; i<len1-4; i++) {
for(size_t i = 3; i + 4 < len1; i++) {
if (rawData2[offs+i-2]==rawData2[offs+i-1] &&
rawData2[offs+i]==rawData2[offs+i-1]+1 &&
rawData2[offs+i]==rawData2[offs+i+1]) {
@ -911,7 +871,7 @@ static int Guess16Bit(int numTests, char **rawData,
}
#if RAW_GUESS_DEBUG
fprintf(af, "former (BE/LE): %d latter (LE+/BE+): %d\n",
fprintf(af, "former (BE/LE): %ud latter (LE+/BE+): %ud\n",
formerVotes, latterVotes);
#endif
@ -950,29 +910,23 @@ static int Guess16Bit(int numTests, char **rawData,
else
*out_channels = 1;
free(rawData2);
free(data1);
free(data2);
return format;
}
static int GuessIntFormats(int numTests, char **rawData, int dataSize,
int *out_offset, unsigned *out_channels)
static int GuessIntFormats(unsigned numTests, const ArrayOf<char> rawData[], size_t dataSize,
size_t *out_offset, unsigned *out_channels)
{
int format = SF_FORMAT_RAW;
bool guess16bit = false;
bool evenMSB;
float *data1 = (float *)malloc((dataSize + 4) * sizeof(float));
float *data2 = (float *)malloc((dataSize + 4) * sizeof(float));
int len1;
int len2;
int vote8 = 0;
int vote16 = 0;
int evenMSBVotes = 0;
int oddMSBVotes = 0;
int test;
ArrayOf<float> data1{ dataSize + 4 };
ArrayOf<float> data2{ dataSize + 4 };
size_t len1;
size_t len2;
unsigned vote8 = 0;
unsigned vote16 = 0;
unsigned evenMSBVotes = 0;
unsigned oddMSBVotes = 0;
#if RAW_GUESS_DEBUG
FILE *af = g_raw_debug_file;
@ -993,14 +947,14 @@ static int GuessIntFormats(int numTests, char **rawData, int dataSize,
* with mono or stereo data.
*/
for (test = 0; test < numTests; test++) {
for (unsigned test = 0; test < numTests; test++) {
float even, odd;
Extract(0, 1, 1, 0, /* 8-bit signed stereo */
false, rawData[test], dataSize,
data1, data2, &len1, &len2);
even = AmpStat(data1, len1);
odd = AmpStat(data2, len2);
false, rawData[test].get(), dataSize,
data1.get(), data2.get(), &len1, &len2);
even = AmpStat(data1.get(), len1);
odd = AmpStat(data2.get(), len2);
if ((even > 0.15) && (odd > 0.15)) {
#if RAW_GUESS_DEBUG
fprintf(af, "Both appear random: %.2f, %.2f.\n", even, odd);
@ -1021,15 +975,12 @@ static int GuessIntFormats(int numTests, char **rawData, int dataSize,
evenMSB = (evenMSBVotes > oddMSBVotes);
#if RAW_GUESS_DEBUG
fprintf(af, "evenMSBVote: %d oddMSBVote: %d\n",
fprintf(af, "evenMSBVote: %ud oddMSBVote: %ud\n",
evenMSBVotes, oddMSBVotes);
fprintf(af, "vote8: %d vote16: %d\n", vote8, vote16);
fprintf(af, "vote8: %ud vote16: %ud\n", vote8, vote16);
#endif
if (vote8 > vote16)
guess16bit = false;
else
guess16bit = true;
guess16bit = (vote8 <= vote16);
if (!guess16bit)
format = Guess8Bit(numTests, rawData, dataSize, out_channels);
@ -1038,23 +989,18 @@ static int GuessIntFormats(int numTests, char **rawData, int dataSize,
dataSize, evenMSB,
out_offset, out_channels);
free(data1);
free(data2);
return format;
}
int RawAudioGuess(const wxString &in_fname,
int *out_offset, unsigned *out_channels)
size_t *out_offset, unsigned *out_channels)
{
const int numTests = 11;
const unsigned numTests = 11;
size_t headerSkipSize = 64;
size_t dataSize = 16384;
int format = SF_FORMAT_RAW;
FILE *inf;
size_t fileLen;
char *rawData[numTests];
int test;
size_t read_data;
#if RAW_GUESS_DEBUG
@ -1095,10 +1041,14 @@ int RawAudioGuess(const wxString &in_fname,
if (fileLen < dataSize)
dataSize = fileLen / 2;
for (test = 0; test < numTests; test++) {
wxASSERT( dataSize >= 4 );
wxASSERT( dataSize <= fileLen );
ArraysOf<char> rawData{ numTests, dataSize + 4 };
for (unsigned test = 0; test < numTests; test++) {
int startPoint;
rawData[test] = (char *)malloc(dataSize + 4);
startPoint = (fileLen - dataSize) * (test + 1) / (numTests + 2);
/* Make it a multiple of 16 (stereo double-precision) */
@ -1106,7 +1056,7 @@ int RawAudioGuess(const wxString &in_fname,
// FIXME: TRAP_ERR fseek return in MultiFormatReader unchecked.
fseek(inf, headerSkipSize + startPoint, SEEK_SET);
read_data = fread(rawData[test], 1, dataSize, inf);
read_data = fread(rawData[test].get(), 1, dataSize, inf);
if (read_data != dataSize && ferror(inf)) {
perror("fread error in RawAudioGuess");
}
@ -1121,17 +1071,18 @@ int RawAudioGuess(const wxString &in_fname,
* almost anything looks like it could be integer data...
*/
format = GuessFloatFormats(numTests, rawData, dataSize,
format = GuessFloatFormats(numTests,
rawData.get(),
dataSize,
out_offset, out_channels);
if (format == 0) {
format = GuessIntFormats(numTests, rawData, dataSize,
format = GuessIntFormats(numTests,
rawData.get(),
dataSize,
out_offset, out_channels);
}
for (test = 0; test < numTests; test++)
free(rawData[test]);
#if RAW_GUESS_DEBUG
fclose(af);
g_raw_debug_file = NULL;

View File

@ -25,4 +25,4 @@
SF_FORMAT value
*/
int RawAudioGuess(const wxString &in_fname,
int *out_offset, unsigned *out_channels);
unsigned *out_offset, unsigned *out_channels);

View File

@ -43,10 +43,7 @@ extern FFmpegLibs *FFmpegLibsInst();
//struct for caching the decoded samples to be used over multiple blockfiles
struct FFMpegDecodeCache
{
FFMpegDecodeCache() {}
~FFMpegDecodeCache() { free(samplePtr); }
uint8_t* samplePtr{};//interleaved samples
ArrayOf<uint8_t> samplePtr;//interleaved samples
sampleCount start;
size_t len;
unsigned numChannels;
@ -391,6 +388,7 @@ int ODFFmpegDecoder::Decode(SampleBuffer & data, sampleFormat & format, sampleCo
//if we've skipped over some samples, fill the gap with silence. This could happen often in the beginning of the file.
if(actualDecodeStart>start && firstpass) {
// find the number of samples for the leading silence
// UNSAFE_SAMPLE_COUNT_TRUNCATION
// -- but used only experimentally as of this writing
// Is there a proof size_t will not overflow size_t?
@ -402,7 +400,7 @@ int ODFFmpegDecoder::Decode(SampleBuffer & data, sampleFormat & format, sampleCo
//put it in the cache so the other channels can use it.
// wxASSERT(sc->m_stream->codec->channels > 0);
cache->numChannels = sc->m_stream->codec->channels;
cache->numChannels = std::max<unsigned>(0, sc->m_stream->codec->channels);
cache->len = amt;
cache->start=start;
// 8 bit and 16 bit audio output from ffmpeg means
@ -413,9 +411,7 @@ int ODFFmpegDecoder::Decode(SampleBuffer & data, sampleFormat & format, sampleCo
else
cache->samplefmt = AV_SAMPLE_FMT_FLT;
cache->samplePtr = (uint8_t*) malloc(amt * cache->numChannels * SAMPLE_SIZE(format));
memset(cache->samplePtr, 0, amt * cache->numChannels * SAMPLE_SIZE(format));
cache->samplePtr.reinit(amt * cache->numChannels * SAMPLE_SIZE(format), true);
InsertCache(std::move(cache));
}
@ -538,27 +534,27 @@ int ODFFmpegDecoder::FillDataFromCache(samplePtr & data, sampleFormat outFormat,
{
case AV_SAMPLE_FMT_U8:
//printf("u8 in %lu out %lu cachelen %lu outLen %lu\n", inIndex, outIndex, mDecodeCache[i]->len, len);
((int16_t *)outBuf)[outIndex] = (int16_t) (((uint8_t*)mDecodeCache[i]->samplePtr)[inIndex] - 0x80) << 8;
((int16_t *)outBuf)[outIndex] = (int16_t) (((uint8_t*)mDecodeCache[i]->samplePtr.get())[inIndex] - 0x80) << 8;
break;
case AV_SAMPLE_FMT_S16:
//printf("u16 in %lu out %lu cachelen %lu outLen % lu\n", inIndex, outIndex, mDecodeCache[i]->len, len);
((int16_t *)outBuf)[outIndex] = ((int16_t*)mDecodeCache[i]->samplePtr)[inIndex];
((int16_t *)outBuf)[outIndex] = ((int16_t*)mDecodeCache[i]->samplePtr.get())[inIndex];
break;
case AV_SAMPLE_FMT_S32:
//printf("s32 in %lu out %lu cachelen %lu outLen %lu\n", inIndex, outIndex, mDecodeCache[i]->len, len);
((float *)outBuf)[outIndex] = (float) ((int32_t*)mDecodeCache[i]->samplePtr)[inIndex] * (1.0 / (1u << 31));
((float *)outBuf)[outIndex] = (float) ((int32_t*)mDecodeCache[i]->samplePtr.get())[inIndex] * (1.0 / (1u << 31));
break;
case AV_SAMPLE_FMT_FLT:
//printf("f in %lu out %lu cachelen %lu outLen %lu\n", inIndex, outIndex, mDecodeCache[i]->len, len);
((float *)outBuf)[outIndex] = (float) ((float*)mDecodeCache[i]->samplePtr)[inIndex];
((float *)outBuf)[outIndex] = (float) ((float*)mDecodeCache[i]->samplePtr.get())[inIndex];
break;
case AV_SAMPLE_FMT_DBL:
//printf("dbl in %lu out %lu cachelen %lu outLen %lu\n", inIndex, outIndex, mDecodeCache[i]->len, len);
((float *)outBuf)[outIndex] = (float) ((double*)mDecodeCache[i]->samplePtr)[inIndex];
((float *)outBuf)[outIndex] = (float) ((double*)mDecodeCache[i]->samplePtr.get())[inIndex];
break;
default:
@ -614,13 +610,13 @@ int ODFFmpegDecoder::DecodeFrame(streamContext *sc, bool flushing)
auto cache = make_movable<FFMpegDecodeCache>();
//len is number of samples per channel
// wxASSERT(sc->m_stream->codec->channels > 0);
cache->numChannels = sc->m_stream->codec->channels;
cache->numChannels = std::max<unsigned>(0, sc->m_stream->codec->channels);
cache->len = (sc->m_decodedAudioSamplesValidSiz / sc->m_samplesize) / cache->numChannels;
cache->start = mCurrentPos;
cache->samplePtr = (uint8_t*) malloc(sc->m_decodedAudioSamplesValidSiz);
cache->samplePtr.reinit(sc->m_decodedAudioSamplesValidSiz);
cache->samplefmt = sc->m_samplefmt;
memcpy(cache->samplePtr, sc->m_decodedAudioSamples.get(), sc->m_decodedAudioSamplesValidSiz);
memcpy(cache->samplePtr.get(), sc->m_decodedAudioSamples.get(), sc->m_decodedAudioSamplesValidSiz);
InsertCache(std::move(cache));
}

View File

@ -110,7 +110,7 @@ class ODLock {
private:
friend class ODCondition; //needs friendship for wait()
pthread_mutex_t mutex ;
pthread_mutex_t mutex;
};
class ODCondition

View File

@ -348,10 +348,7 @@ SpectrogramSettings::~SpectrogramSettings()
void SpectrogramSettings::DestroyWindows()
{
if (hFFT != NULL) {
EndFFT(hFFT);
hFFT = NULL;
}
hFFT.reset();
window.reset();
dWindow.reset();
tWindow.reset();
@ -420,9 +417,7 @@ void SpectrogramSettings::CacheWindows() const
const auto fftLen = WindowSize() * ZeroPaddingFactor();
const auto padding = (WindowSize() * (zeroPaddingFactor - 1)) / 2;
if (hFFT != NULL)
EndFFT(hFFT);
hFFT = InitializeFFT(fftLen);
hFFT = GetFFT(fftLen);
RecreateWindow(window, WINDOW, fftLen, padding, windowType, windowSize, scale);
if (algorithm == algReassignment) {
RecreateWindow(tWindow, TWINDOW, fftLen, padding, windowType, windowSize, scale);

View File

@ -13,6 +13,7 @@ Paul Licameli
#include "../Experimental.h"
#include "../SampleFormat.h"
#include "../RealFFTf.h"
#undef SPECTRAL_SELECTION_GLOBAL_SWITCH
@ -153,7 +154,7 @@ public:
// Following fields are derived from preferences.
// Variables used for computing the spectrum
mutable FFTParam *hFFT{};
mutable HFFT hFFT;
mutable Floats window;
// Two other windows for computing reassigned spectrogram

View File

@ -48,7 +48,7 @@
\brief An array of these created by the Ruler is used to determine
what and where text annotations to the numbers on the Ruler get drawn.
\todo Check whether Ruler is costing too much time in malloc/free of
\todo Check whether Ruler is costing too much time in allocation/free of
array of Ruler::Label.
*//******************************************************************/