GenericNodes.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /* ----------------------------------------------------------------------
  2. * Project: CMSIS DSP Library
  3. * Title: Sched.h
  4. * Description: C++ support templates for the SDF scheduler
  5. *
  6. * $Date: 29 July 2021
  7. * $Revision: V1.10.0
  8. *
  9. * Target Processor: Cortex-M and Cortex-A cores
  10. * -------------------------------------------------------------------- */
  11. /*
  12. * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
  13. *
  14. * SPDX-License-Identifier: Apache-2.0
  15. *
  16. * Licensed under the Apache License, Version 2.0 (the License); you may
  17. * not use this file except in compliance with the License.
  18. * You may obtain a copy of the License at
  19. *
  20. * www.apache.org/licenses/LICENSE-2.0
  21. *
  22. * Unless required by applicable law or agreed to in writing, software
  23. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  24. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  25. * See the License for the specific language governing permissions and
  26. * limitations under the License.
  27. */
  28. #ifndef _SCHEDGEN_H_
  29. #define _SCHEDGEN_H_
  30. #include <vector>
  31. // FIFOS
  32. #ifdef DEBUGSCHED
  33. template<typename T>
  34. struct debugtype{
  35. typedef T type;
  36. };
  37. template<>
  38. struct debugtype<char>{
  39. typedef int type;
  40. };
  41. template<typename T>
  42. using Debug = struct debugtype<T>;
  43. #endif
  44. template<typename T>
  45. class FIFOBase{
  46. public:
  47. virtual T* getWriteBuffer(int nb)=0;
  48. virtual T* getReadBuffer(int nb)=0;
  49. };
  50. template<typename T, int length, int isArray=0>
  51. class FIFO: public FIFOBase<T>
  52. {
  53. public:
  54. FIFO(T *buffer,int delay=0):mBuffer(buffer),readPos(0),writePos(delay) {};
  55. FIFO(uint8_t *buffer,int delay=0):mBuffer((T*)buffer),readPos(0),writePos(delay) {};
  56. T * getWriteBuffer(int nb) override
  57. {
  58. if (isArray==1)
  59. {
  60. return(mBuffer);
  61. }
  62. T *ret;
  63. if (readPos > 0)
  64. {
  65. memcpy((void*)mBuffer,(void*)(mBuffer+readPos),(writePos-readPos)*sizeof(T));
  66. writePos -= readPos;
  67. readPos = 0;
  68. }
  69. ret = mBuffer + writePos;
  70. writePos += nb;
  71. return(ret);
  72. };
  73. T* getReadBuffer(int nb) override
  74. {
  75. if (isArray==1)
  76. {
  77. return(mBuffer);
  78. }
  79. T *ret = mBuffer + readPos;
  80. readPos += nb;
  81. return(ret);
  82. }
  83. #ifdef DEBUGSCHED
  84. void dump()
  85. {
  86. int nb=0;
  87. std::cout << std::endl;
  88. for(int i=0; i < length ; i++)
  89. {
  90. std::cout << (Debug<T>::type)mBuffer[i] << " ";
  91. nb++;
  92. if (nb == 10)
  93. {
  94. nb=0;
  95. std::cout << std::endl;
  96. }
  97. }
  98. std::cout << std::endl;
  99. std::cout << std::endl;
  100. }
  101. #endif
  102. protected:
  103. T *mBuffer;
  104. int readPos,writePos;
  105. };
  106. // GENERIC NODES
  107. class NodeBase
  108. {
  109. public:
  110. virtual int run()=0;
  111. };
  112. template<typename IN, int inputSize,typename OUT, int outputSize>
  113. class GenericNode:public NodeBase
  114. {
  115. public:
  116. GenericNode(FIFOBase<IN> &src,FIFOBase<OUT> &dst):mSrc(src),mDst(dst){};
  117. protected:
  118. OUT * getWriteBuffer(){return mDst.getWriteBuffer(outputSize);};
  119. IN * getReadBuffer(){return mSrc.getReadBuffer(inputSize);};
  120. private:
  121. FIFOBase<IN> &mSrc;
  122. FIFOBase<OUT> &mDst;
  123. };
  124. template<typename IN, int inputSize,typename OUT1, int output1Size,typename OUT2, int output2Size>
  125. class GenericNode12:public NodeBase
  126. {
  127. public:
  128. GenericNode12(FIFOBase<IN> &src,FIFOBase<OUT1> &dst1,FIFOBase<OUT2> &dst2):mSrc(src),
  129. mDst1(dst1),mDst2(dst2){};
  130. protected:
  131. OUT1 * getWriteBuffer1(){return mDst1.getWriteBuffer(output1Size);};
  132. OUT2 * getWriteBuffer2(){return mDst2.getWriteBuffer(output2Size);};
  133. IN * getReadBuffer(){return mSrc.getReadBuffer(inputSize);};
  134. private:
  135. FIFOBase<IN> &mSrc;
  136. FIFOBase<OUT1> &mDst1;
  137. FIFOBase<OUT2> &mDst2;
  138. };
  139. template<typename IN1, int input1Size,typename IN2, int input2Size,typename OUT, int outputSize>
  140. class GenericNode21:public NodeBase
  141. {
  142. public:
  143. GenericNode21(FIFOBase<IN1> &src1,FIFOBase<IN2> &src2,FIFOBase<OUT> &dst):mSrc1(src1),
  144. mSrc2(src2),
  145. mDst(dst){};
  146. protected:
  147. OUT * getWriteBuffer(){return mDst.getWriteBuffer(outputSize);};
  148. IN1 * getReadBuffer1(){return mSrc1.getReadBuffer(input1Size);};
  149. IN2 * getReadBuffer2(){return mSrc2.getReadBuffer(input2Size);};
  150. private:
  151. FIFOBase<IN1> &mSrc1;
  152. FIFOBase<IN2> &mSrc2;
  153. FIFOBase<OUT> &mDst;
  154. };
  155. template<typename OUT, int outputSize>
  156. class GenericSource:public NodeBase
  157. {
  158. public:
  159. GenericSource(FIFOBase<OUT> &dst):mDst(dst){};
  160. protected:
  161. OUT * getWriteBuffer(){return mDst.getWriteBuffer(outputSize);};
  162. private:
  163. FIFOBase<OUT> &mDst;
  164. };
  165. template<typename IN,int inputSize>
  166. class GenericSink:public NodeBase
  167. {
  168. public:
  169. GenericSink(FIFOBase<IN> &src):mSrc(src){};
  170. protected:
  171. IN * getReadBuffer(){return mSrc.getReadBuffer(inputSize);};
  172. private:
  173. FIFOBase<IN> &mSrc;
  174. };
  175. #define REPEAT(N) for(int i=0;i<N;i++)
  176. // GENERIC APPLICATION NODES
  177. template<typename IN,int windowSize, int overlap>
  178. class SlidingBuffer: public GenericNode<IN,windowSize-overlap,IN,windowSize>
  179. {
  180. public:
  181. SlidingBuffer(FIFOBase<IN> &src,FIFOBase<IN> &dst):GenericNode<IN,windowSize-overlap,IN,windowSize>(src,dst)
  182. {
  183. static_assert((windowSize-overlap)>0, "Overlap is too big");
  184. memory.resize(overlap);
  185. };
  186. int run(){
  187. IN *a=this->getReadBuffer();
  188. IN *b=this->getWriteBuffer();
  189. memcpy((void*)b,(void*)memory.data(),overlap*sizeof(IN));
  190. memcpy((void*)(b+overlap),(void*)a,(windowSize-overlap)*sizeof(IN));
  191. memcpy((void*)memory.data(),(void*)(b+windowSize-overlap),overlap*sizeof(IN)) ;
  192. return(0);
  193. };
  194. protected:
  195. std::vector<IN> memory;
  196. };
  197. template<typename IN,int windowSize, int overlap>
  198. class OverlapAdd: public GenericNode<IN,windowSize,IN,windowSize-overlap>
  199. {
  200. public:
  201. OverlapAdd(FIFOBase<IN> &src,FIFOBase<IN> &dst):GenericNode<IN,windowSize,IN,overlap>(src,dst)
  202. {
  203. static_assert((windowSize-overlap)>0, "Overlap is too big");
  204. memory.resize(overlap);
  205. };
  206. int run(){
  207. int i;
  208. IN *a=this->getReadBuffer();
  209. IN *b=this->getWriteBuffer();
  210. for(i=0;i<overlap;i++)
  211. {
  212. memory[i] = a[i] + memory[i];
  213. }
  214. if (2*overlap - windowSize > 0)
  215. {
  216. memcpy((void*)b,(void*)memory.data(),(windowSize-overlap)*sizeof(IN));
  217. memmove(memory.data(),memory.data()+windowSize-overlap,(2*overlap - windowSize)*sizeof(IN));
  218. memcpy(memory.data()+2*overlap - windowSize,a+overlap,(windowSize-overlap)*sizeof(IN));
  219. }
  220. else if (2*overlap - windowSize < 0)
  221. {
  222. memcpy((void*)b,(void*)memory.data(),overlap*sizeof(IN));
  223. memcpy((void*)(b+overlap),(void*)(a+overlap),(windowSize - 2*overlap)*sizeof(IN));
  224. memcpy((void*)memory.data(),(void*)(a+windowSize-overlap),overlap*sizeof(IN));
  225. }
  226. else
  227. {
  228. memcpy((void*)b,(void*)memory.data(),overlap*sizeof(IN));
  229. memcpy((void*)memory.data(),(void*)(a+overlap),overlap*sizeof(IN));
  230. }
  231. return(0);
  232. };
  233. protected:
  234. std::vector<IN> memory;
  235. };
  236. #if !defined(CHECKERROR)
  237. #define CHECKERROR if (sdfError < 0) \
  238. {\
  239. break;\
  240. }
  241. #endif
  242. #endif