Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <ipp.h>
- #include <cmath>
- #include <iostream>
- #include <fstream>
- #include <stdexcept>
- #include <memory>
- // Signal parameter.
- Ipp32s signal_frequency [5] = { 1, 5, 10, 200, 500 }; // in Hz.
- Ipp32s signal_amplitude = 20; // in levels.
- Ipp32s noise_amplitude = 10; // in levels.
- const Ipp32s sampling_frequency = 44100; // in Hz.
- // Free functor.
- struct freeIpps {
- inline void operator()(void *_p)
- {
- if(!_p) return;
- ippsFree(_p);
- }
- };
- // Type references.
- typedef std::unique_ptr<Ipp32f[], freeIpps> Ipp32f_ptr;
- typedef std::unique_ptr<Ipp8u[], freeIpps> Ipp8u_ptr;
- typedef std::unique_ptr<IppsFFTSpec_R_32f, freeIpps> IppsFFTSpec_R_32f_ptr;
- // Signal data.
- const Ipp32f time_step = 1;
- const Ipp32f log_2 = std::log(2);
- Ipp32f time_line[sampling_frequency];
- // Check function.
- inline bool ispwr_of_2(Ipp32s x)
- {
- return (x && !(x & (x - 1)));
- }
- inline Ipp32s topwr_of_2(Ipp32s x)
- {
- if(x > 0)
- {
- if(x & (x - 1))
- {
- --x;
- x |= x >> 1;
- x |= x >> 2;
- x |= x >> 4;
- x |= x >> 8;
- x |= x >> 16;
- ++x;
- }
- }
- return x;
- }
- void init_time()
- {
- time_line[0] = time_step;
- for(Ipp32u i = 1; i < sampling_frequency; ++i)
- time_line[i] = time_line[i-1] + time_step;
- }
- Ipp32f_ptr signal_gen(Ipp32s fi, Ipp32s &data_sz)
- {
- // The length of the vector transformed by the FFT must be a power of 2.
- data_sz = topwr_of_2(sampling_frequency);
- Ipp32f_ptr data(ippsMalloc_32f(data_sz));
- Ipp32f y = IPP_2PI * signal_frequency[fi];
- y /= sampling_frequency;
- // Generate sine wave with sampling_frequency size.
- for(Ipp32u i = 0; i < sampling_frequency; ++i) {
- data[i] = y * time_line[i];
- data[i] = std::sin(data[i]);
- data[i] *= signal_amplitude;
- }
- Ipp32s zero_begin = sampling_frequency;
- Ipp32s zero_end = data_sz - zero_begin;
- // Zero-pad the input signals (add zeros to the end so that at least half of the wave is "blank").
- IppStatus status = ippsZero_32f(data.get() + zero_begin, zero_end);
- if(status != ippStsNoErr) throw std::runtime_error(ippGetStatusString(status));
- std::cout << "The sine wave is generated. The length is equal to: " << sampling_frequency
- << "\nZeroed part of the signal is in the range: [ " << zero_begin << " ] [ " << zero_begin + zero_end << " ]\n";
- return data;
- }
- void do_processing()
- {
- while(true)
- for(Ipp32u i = 0; i < 5; i = (i+1 == 5)?(0):(i+1))
- {
- Ipp32s fftSz = 0; // Length of data with zeros.
- Ipp32f_ptr pSrc = signal_gen(i, fftSz);
- Ipp32f_ptr pDst(ippsMalloc_32f(fftSz));
- Ipp32s pSpecSize = 0;
- Ipp32s pSpecBuffSize = 0;
- Ipp32s pBuffSize = 0;
- Ipp32s order = std::log(fftSz)/log_2;
- IppStatus status = ippsFFTGetSize_R_32f(order, IPP_FFT_NODIV_BY_ANY, ippAlgHintFast, &pSpecSize, &pSpecBuffSize, &pBuffSize);
- if(status != ippStsNoErr) throw std::runtime_error(ippGetStatusString(status));
- Ipp8u_ptr pBuffer(ippsMalloc_8u(pBuffSize));
- Ipp8u_ptr pSpec(ippsMalloc_8u(pSpecSize));
- Ipp8u_ptr pSpecBuffer(ippsMalloc_8u(pSpecBuffSize));
- IppsFFTSpec_R_32f *pFFTSpec = nullptr;
- status = ippsFFTInit_R_32f(&pFFTSpec, order, IPP_FFT_NODIV_BY_ANY, ippAlgHintFast, pSpec.get(), pSpecBuffer.get());
- if(status != ippStsNoErr) throw std::runtime_error(ippGetStatusString(status));
- status = ippsFFTFwd_RToPack_32f(pSrc.get(), pDst.get(), pFFTSpec, pBuffer.get());
- if(status != ippStsNoErr) throw std::runtime_error(ippGetStatusString(status));
- Ipp32fc *pDstC = (Ipp32fc*)(pDst.get());
- Ipp32s realSz = fftSz/2; // Exclude zero part.
- Ipp32s magSz = realSz/2; // Convert length to complex length.
- // Extract magniutde from input signal.
- status = ippsMagnitude_32fc(pDstC, pDst.get(), realSz);
- if(status != ippStsNoErr) throw std::runtime_error(ippGetStatusString(status));
- Ipp32f lvl = 2.0/Ipp32f(realSz);
- Ipp32f B = 19.93156857;
- // Get amplitude in levels.
- status = ippsMulC_32f(pDst.get(), lvl, pDst.get(), magSz);
- if(status != ippStsNoErr) throw std::runtime_error(ippGetStatusString(status));
- // Convert level to dB.
- status = ippsLn_32f(pDst.get(), pDst.get(), magSz);
- if(status != ippStsNoErr) throw std::runtime_error(ippGetStatusString(status));
- status = ippsMulC_32f(pDst.get(), B, pDst.get(), magSz);
- if(status != ippStsNoErr) throw std::runtime_error(ippGetStatusString(status));
- }
- }
- int main()
- try{
- IppStatus status = ippInit();
- if(status != ippStsNoErr) throw std::runtime_error(ippGetStatusString(status));
- std::cout << "The IPP library was successfully initialized.\n";
- status = ippSetAffinity(ippAffinityCompactFineHT, 0);
- if(status != ippStsNoErr) throw std::runtime_error(ippGetStatusString(status));
- std::cout << "OpenMP succesfully bind all threads to OS processors. \n";
- init_time();
- std::cout << "Timeline was initialized.\n";
- do_processing();
- std::cout << "Signal processing has completed successfully.\n";
- return 0;
- }
- catch(std::runtime_error &e)
- {
- std::cerr << e.what() << '\n';
- return 1;
- }
- catch(...)
- {
- std::cerr << "Unhandled exception.\n";
- return 2;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement