void FftClFft:: computeC2R( Tfr::ChunkData::Ptr input, DataStorage<float>::Ptr output ) { unsigned denseWidth = input->size().width; unsigned redundantWidth = output->size().width; EXCEPTION_ASSERT( denseWidth == redundantWidth/2+1 ); Tfr::ChunkData::Ptr redundantInput( new Tfr::ChunkData( redundantWidth, input->size().height )); { Tfr::ChunkElement* in = CpuMemoryStorage::ReadOnly<1>( input ).ptr(); Tfr::ChunkElement* out = CpuMemoryStorage::WriteAll<1>( redundantInput ).ptr(); unsigned x; for (x=0; x<denseWidth; ++x) out[x] = in[x]; for (; x<redundantWidth; ++x) out[x] = conj(in[redundantWidth - x]); } Tfr::ChunkData::Ptr complexoutput( new Tfr::ChunkData( output->size())); computeWithClFft(redundantInput, complexoutput, FftDirection_Inverse); ::stftDiscardImag( complexoutput, output ); }
void FftClFft:: computeR2C( DataStorage<float>::Ptr input, Tfr::ChunkData::Ptr output ) { unsigned denseWidth = output->size().width; unsigned redundantWidth = input->size().width; EXCEPTION_ASSERT( denseWidth == redundantWidth/2+1 ); // interleave input to complex data Tfr::ChunkData::Ptr complexinput( new Tfr::ChunkData( input->size())); ::stftToComplex( input, complexinput ); // make room for full output Tfr::ChunkData::Ptr redundantOutput( new Tfr::ChunkData( redundantWidth )); // compute computeWithClFft(complexinput, redundantOutput, FftDirection_Forward); // discard redundant output { Tfr::ChunkElement* in = CpuMemoryStorage::ReadOnly<1>( redundantOutput ).ptr(); Tfr::ChunkElement* out = CpuMemoryStorage::WriteAll<1>( output ).ptr(); unsigned x; for (x=0; x<denseWidth; ++x) out[x] = in[x]; } }
void FftClFft:: compute(DataStorage<float>::Ptr input, Tfr::ChunkData::Ptr output, DataStorageSize n ) { unsigned denseWidth = n.width/2+1; EXCEPTION_ASSERT( output->numberOfElements()/denseWidth == n.height ); EXCEPTION_ASSERT( input->numberOfElements()/n.width == n.height ); // interleave input to complex data Tfr::ChunkData::Ptr complexinput( new Tfr::ChunkData( input->size())); ::stftToComplex( input, complexinput ); // make room for full output Tfr::ChunkData::Ptr redundantOutput( new Tfr::ChunkData( n.width*n.height )); // compute computeWithClFft(complexinput, redundantOutput, n, FftDirection_Forward); // discard redundant output Tfr::ChunkElement* in = CpuMemoryStorage::ReadOnly<1>( redundantOutput ).ptr(); Tfr::ChunkElement* out = CpuMemoryStorage::WriteAll<1>( output ).ptr(); #pragma omp parallel for for (int i=0; i < (int)n.height; ++i) { unsigned x; for (x=0; x<denseWidth; ++x) out[i*denseWidth + x] = in[i*n.width + x]; } }
std::string DataStorageString:: printDataStorageStats(DataStorage<float>::ptr data) { std::stringstream ss; Statistics<float> s(data, false, true); ss << "size = " << data->size () << ", min = " << *s.getMin () << ", max = " << *s.getMax () << ", mean = " << s.getMean () << ", std = " << s.getStd (); return ss.str(); }
std::string DataStorageString:: printDataStorage(DataStorage<float>::ptr data) { EXCEPTION_ASSERT(data); std::stringstream ss; DataStorageSize sz = data->size (); ss << sz; float *p = sz.width ? data->getCpuMemory () : 0; if (sz.depth>1) { for (int z=0; z<sz.depth; ++z) { for (int y=0; y<sz.height; ++y) { ss << std::endl << "[z:" << z << ", y:" << y << "] = { "; float *q = p + y*sz.width + z*sz.height*sz.width; if (sz.width) ss << q[0]; for (int x=1; x<sz.width; ++x) ss << ", " << q[x]; ss << " }"; } } } else if (sz.height>1) { for (int y=0; y<sz.height; ++y) { ss << std::endl << "[y:" << y << "] = { "; float *q = p + y*sz.width; if (sz.width) ss << q[0]; for (int x=1; x<sz.width; ++x) ss << ", " << q[x]; ss << " }"; } } else { ss << " = { "; if (sz.width) ss << p[0]; for (int x=1; x<sz.width; ++x) ss << ", " << p[x]; ss << " }"; } return ss.str (); }
void FftClFft:: inverse(Tfr::ChunkData::Ptr input, DataStorage<float>::Ptr output, DataStorageSize n ) { unsigned denseWidth = n.width/2+1; unsigned redundantWidth = n.width; unsigned batchcount1 = output->numberOfElements()/redundantWidth, batchcount2 = input->numberOfElements()/denseWidth; EXCEPTION_ASSERT( batchcount1 == batchcount2 ); EXCEPTION_ASSERT( (denseWidth-1)*2 == redundantWidth ); EXCEPTION_ASSERT( redundantWidth*n.height == output->numberOfElements() ); Tfr::ChunkData::Ptr redundantInput( new Tfr::ChunkData( n.height*redundantWidth )); { Tfr::ChunkElement* in = CpuMemoryStorage::ReadOnly<1>( input ).ptr(); Tfr::ChunkElement* out = CpuMemoryStorage::WriteAll<1>( redundantInput ).ptr(); #pragma omp parallel for for (int i=0; i < (int)n.height; ++i) { unsigned x; for (x=0; x<denseWidth; ++x) out[i*redundantWidth + x] = in[i*denseWidth + x]; for (; x<redundantWidth; ++x) out[i*redundantWidth + x] = conj(in[i*denseWidth + redundantWidth - x]); } } Tfr::ChunkData::Ptr complexoutput( new Tfr::ChunkData( output->size())); computeWithClFft(redundantInput, complexoutput, DataStorageSize( redundantWidth, n.height), FftDirection_Inverse); ::stftDiscardImag( complexoutput, output ); TIME_STFT ComputationSynchronize(); }