[2e5c52e] | 1 | /* |
---|
| 2 | Copyright (C) 2017 Paul Brossier <piem@aubio.org> |
---|
| 3 | |
---|
| 4 | This file is part of aubio. |
---|
| 5 | |
---|
| 6 | aubio is free software: you can redistribute it and/or modify |
---|
| 7 | it under the terms of the GNU General Public License as published by |
---|
| 8 | the Free Software Foundation, either version 3 of the License, or |
---|
| 9 | (at your option) any later version. |
---|
| 10 | |
---|
| 11 | aubio is distributed in the hope that it will be useful, |
---|
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
| 14 | GNU General Public License for more details. |
---|
| 15 | |
---|
| 16 | You should have received a copy of the GNU General Public License |
---|
| 17 | along with aubio. If not, see <http://www.gnu.org/licenses/>. |
---|
| 18 | |
---|
| 19 | */ |
---|
| 20 | |
---|
| 21 | #include "aubio_priv.h" |
---|
| 22 | #include "fvec.h" |
---|
| 23 | #include "spectral/dct.h" |
---|
| 24 | |
---|
| 25 | #if defined(HAVE_INTEL_IPP) |
---|
| 26 | |
---|
| 27 | #if !HAVE_AUBIO_DOUBLE |
---|
| 28 | #define aubio_IppFloat Ipp32f |
---|
| 29 | #define aubio_ippsDCTFwdSpec IppsDCTFwdSpec_32f |
---|
| 30 | #define aubio_ippsDCTInvSpec IppsDCTInvSpec_32f |
---|
| 31 | #define aubio_ippsDCTFwdGetSize ippsDCTFwdGetSize_32f |
---|
| 32 | #define aubio_ippsDCTInvGetSize ippsDCTInvGetSize_32f |
---|
| 33 | #define aubio_ippsDCTFwdInit ippsDCTFwdInit_32f |
---|
| 34 | #define aubio_ippsDCTInvInit ippsDCTInvInit_32f |
---|
| 35 | #define aubio_ippsDCTFwd ippsDCTFwd_32f |
---|
| 36 | #define aubio_ippsDCTInv ippsDCTInv_32f |
---|
| 37 | #else /* HAVE_AUBIO_DOUBLE */ |
---|
| 38 | #define aubio_IppFloat Ipp64f |
---|
| 39 | #define aubio_ippsDCTFwdSpec IppsDCTFwdSpec_64f |
---|
| 40 | #define aubio_ippsDCTInvSpec IppsDCTInvSpec_64f |
---|
| 41 | #define aubio_ippsDCTFwdGetSize ippsDCTFwdGetSize_64f |
---|
| 42 | #define aubio_ippsDCTInvGetSize ippsDCTInvGetSize_64f |
---|
| 43 | #define aubio_ippsDCTFwdInit ippsDCTFwdInit_64f |
---|
| 44 | #define aubio_ippsDCTInvInit ippsDCTInvInit_64f |
---|
| 45 | #define aubio_ippsDCTFwd ippsDCTFwd_64f |
---|
| 46 | #define aubio_ippsDCTInv ippsDCTInv_64f |
---|
| 47 | #endif |
---|
| 48 | |
---|
[8c50194] | 49 | typedef struct _aubio_dct_ipp_t aubio_dct_ipp_t; |
---|
| 50 | |
---|
| 51 | struct _aubio_dct_ipp_t { |
---|
[2e5c52e] | 52 | uint_t size; |
---|
[6812354] | 53 | Ipp8u* pSpecFwd; |
---|
| 54 | Ipp8u* pSpecInv; |
---|
[2e5c52e] | 55 | Ipp8u* pSpecBuffer; |
---|
| 56 | Ipp8u* pBuffer; |
---|
| 57 | aubio_ippsDCTFwdSpec* pFwdDCTSpec; |
---|
| 58 | aubio_ippsDCTInvSpec* pInvDCTSpec; |
---|
| 59 | }; |
---|
| 60 | |
---|
[8c50194] | 61 | void del_aubio_dct_ipp (aubio_dct_ipp_t *s); |
---|
| 62 | |
---|
| 63 | aubio_dct_ipp_t * new_aubio_dct_ipp (uint_t size) { |
---|
| 64 | aubio_dct_ipp_t * s = AUBIO_NEW(aubio_dct_ipp_t); |
---|
[2e5c52e] | 65 | |
---|
| 66 | const IppHintAlgorithm qualityHint = ippAlgHintAccurate; // ippAlgHintFast; |
---|
| 67 | int pSpecSize, pSpecBufferSize, pBufferSize; |
---|
| 68 | IppStatus status; |
---|
| 69 | |
---|
[eed4133] | 70 | if ((sint_t)size <= 0) { |
---|
| 71 | AUBIO_ERR("dct: can only create with sizes greater than 0, requested %d\n", |
---|
[2e5c52e] | 72 | size); |
---|
| 73 | goto beach; |
---|
| 74 | } |
---|
| 75 | |
---|
| 76 | status = aubio_ippsDCTFwdGetSize(size, qualityHint, &pSpecSize, |
---|
| 77 | &pSpecBufferSize, &pBufferSize); |
---|
| 78 | if (status != ippStsNoErr) { |
---|
| 79 | AUBIO_ERR("dct: failed to initialize dct. IPP error: %d\n", status); |
---|
| 80 | goto beach; |
---|
| 81 | } |
---|
| 82 | |
---|
| 83 | //AUBIO_INF("dct: fwd initialized with %d %d %d\n", pSpecSize, pSpecBufferSize, |
---|
| 84 | // pBufferSize); |
---|
| 85 | |
---|
[6812354] | 86 | s->pSpecFwd = ippsMalloc_8u(pSpecSize); |
---|
| 87 | s->pSpecInv = ippsMalloc_8u(pSpecSize); |
---|
[2e5c52e] | 88 | if (pSpecSize > 0) { |
---|
| 89 | s->pSpecBuffer = ippsMalloc_8u(pSpecBufferSize); |
---|
| 90 | } else { |
---|
| 91 | s->pSpecBuffer = NULL; |
---|
| 92 | } |
---|
| 93 | s->pBuffer = ippsMalloc_8u(pBufferSize); |
---|
| 94 | |
---|
| 95 | status = aubio_ippsDCTInvGetSize(size, qualityHint, &pSpecSize, |
---|
| 96 | &pSpecBufferSize, &pBufferSize); |
---|
| 97 | if (status != ippStsNoErr) { |
---|
| 98 | AUBIO_ERR("dct: failed to initialize dct. IPP error: %d\n", status); |
---|
| 99 | goto beach; |
---|
| 100 | } |
---|
| 101 | |
---|
| 102 | //AUBIO_INF("dct: inv initialized with %d %d %d\n", pSpecSize, pSpecBufferSize, |
---|
| 103 | // pBufferSize); |
---|
| 104 | |
---|
[6812354] | 105 | status = aubio_ippsDCTFwdInit(&(s->pFwdDCTSpec), size, qualityHint, s->pSpecFwd, |
---|
[2e5c52e] | 106 | s->pSpecBuffer); |
---|
| 107 | if (status != ippStsNoErr) { |
---|
| 108 | AUBIO_ERR("dct: failed to initialize fwd dct. IPP error: %d\n", status); |
---|
| 109 | goto beach; |
---|
| 110 | } |
---|
| 111 | |
---|
[6812354] | 112 | status = aubio_ippsDCTInvInit(&(s->pInvDCTSpec), size, qualityHint, s->pSpecInv, |
---|
[03df4dc] | 113 | s->pSpecBuffer); |
---|
[2e5c52e] | 114 | if (status != ippStsNoErr) { |
---|
| 115 | AUBIO_ERR("dct: failed to initialize inv dct. IPP error: %d\n", status); |
---|
| 116 | goto beach; |
---|
| 117 | } |
---|
| 118 | |
---|
| 119 | s->size = size; |
---|
| 120 | |
---|
| 121 | return s; |
---|
| 122 | |
---|
| 123 | beach: |
---|
[8c50194] | 124 | del_aubio_dct_ipp(s); |
---|
[2e5c52e] | 125 | return NULL; |
---|
| 126 | } |
---|
| 127 | |
---|
[8c50194] | 128 | void del_aubio_dct_ipp(aubio_dct_ipp_t *s) { |
---|
[6812354] | 129 | ippFree(s->pSpecFwd); |
---|
| 130 | ippFree(s->pSpecInv); |
---|
[2e5c52e] | 131 | ippFree(s->pSpecBuffer); |
---|
| 132 | ippFree(s->pBuffer); |
---|
| 133 | AUBIO_FREE(s); |
---|
| 134 | } |
---|
| 135 | |
---|
[8c50194] | 136 | void aubio_dct_ipp_do(aubio_dct_ipp_t *s, const fvec_t *input, fvec_t *output) { |
---|
[2e5c52e] | 137 | |
---|
| 138 | aubio_ippsDCTFwd((const aubio_IppFloat*)input->data, |
---|
| 139 | (aubio_IppFloat*)output->data, s->pFwdDCTSpec, s->pBuffer); |
---|
| 140 | |
---|
| 141 | } |
---|
| 142 | |
---|
[8c50194] | 143 | void aubio_dct_ipp_rdo(aubio_dct_ipp_t *s, const fvec_t *input, fvec_t *output) { |
---|
[2e5c52e] | 144 | |
---|
| 145 | aubio_ippsDCTInv((const aubio_IppFloat*)input->data, |
---|
| 146 | (aubio_IppFloat*)output->data, s->pInvDCTSpec, s->pBuffer); |
---|
| 147 | |
---|
| 148 | } |
---|
| 149 | |
---|
| 150 | #endif //defined(HAVE_INTEL_IPP) |
---|