SAF
Loading...
Searching...
No Matches
saf_utility_qmf.c
Go to the documentation of this file.
1/*
2 * Copyright 2020 Leo McCormack
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
15 */
16
32#include "saf_utilities.h"
33#include "saf_externals.h"
34
35#define QMF_MAX_HOP_SIZE ( 128 )
36#define QMF_HYBRID_FILTER_LENGTH ( 13 )
37#define QMF_NBANDS_2_SUBDIVIDE ( 3 )
40static const double __qmf_protofilter[1280] =
41{ 0.0000000000000, -0.0002762634720, -0.0005525342198, -0.0005571552713, -0.0005617683373, -0.0005282514607, -0.0004947593820, -0.0004911467040, -0.0004875236552, -0.0004884532092, -0.0004893838045, -0.0004967240815, -0.0005040750825, -0.0005133670560, -0.0005226597455, -0.0005346514478, -0.0005466472274, -0.0005572187697, -0.0005677828639, -0.0005774439998, -0.0005870916039, -0.0006001850920, -0.0006132728105, -0.0006222713668, -0.0006312541653, -0.0006426322143, -0.0006540371501, -0.0006658914180, -0.0006777676604, -0.0006859690454, -0.0006941641036, -0.0007049595278, -0.0007157690669, -0.0007206486380, -0.0007255024482, -0.0007348050240, -0.0007440890752, -0.0007465733138, -0.0007490661119, -0.0007586070399, -0.0007681336013, -0.0007703168846, -0.0007724918034, -0.0007779534357, -0.0007834287454, -0.0007807033412, -0.0007779944598, -0.0007791681113, -0.0007803615976, -0.0007802465749, -0.0007801371586, -0.0007779723824, -0.0007758066727, -0.0007694345970, -0.0007630873596, -0.0007580352349, -0.0007530028195, -0.0007424619382, -0.0007319442929, -0.0007267356718, -0.0007215430902, -0.0007066606628, -0.0006917932571, -0.0006784128723, -0.0006650339491, -0.0006495992993, -0.0006341674870, -0.0006143876230, -0.0005946202616, -0.0005755259068, -0.0005564609970, -0.0005355145456, -0.0005145569911, -0.0004875885201, -0.0004606378785, -0.0004350627059, -0.0004095097465, -0.0003798107209, -0.0003501149003, -0.0003199111004, -0.0002897008523, -0.0002497595743, -0.0002098366519, -0.0001772307680, -0.0001446327356, -0.0001031896779, -0.0000617345700, -0.0000241262916, 0.0000134965582, 0.0000614720333, 0.0001094394708, 0.0001568793435, 0.0002042941489, 0.0002496306494, 0.0002949442047, 0.0003487948377, 0.0004026588663, 0.0004567034861, 0.0005107402212, 0.0005673469176, 0.0006239305560, 0.0006848671621, 0.0007458077212, 0.0008033299866, 0.0008608421186, 0.0009247267892, 0.0009886054038, 0.0010567976484, 0.0011250228994, 0.0011914037242, 0.0012577875050, 0.0013240150513, 0.0013902546415, 0.0014672773757, 0.0015443257222, 0.0016155684463, 0.0016868125944, 0.0017608243873, 0.0018348194834, 0.0019094781805, 0.0019841117942, 0.0020651392863, 0.0021461575925, 0.0022239322768, 0.0023017300059, 0.0023821487099, 0.0024625676012, 0.0025413674009, 0.0026201724337, 0.0027036125466, 0.0027870398286, 0.0028669900755, 0.0029469530526, 0.0030297492329, 0.0031125415322, 0.0031932528503, 0.0032739529064, 0.0033579247943, 0.0034418941739, 0.0035213512278, 0.0036008198759, 0.0036806138717, 0.0037603943985, 0.0038405755459, 0.0039207434248, 0.0040013511319, 0.0040819786631, 0.0041542084654, 0.0042264200821, 0.0042997543412, 0.0043730783438, 0.0044470261882, 0.0045209852815, 0.0045908246900, 0.0046606421516, 0.0047269540845, 0.0047932482139, 0.0048535152844, 0.0049137657537, 0.0049765248518, 0.0050393080129, 0.0050900151409, 0.0051407363835, 0.0051934305868, 0.0052461239441, 0.0052966510528, 0.0053471668162, 0.0053834300667, 0.0054196692329, 0.0054536384534, 0.0054875987642, 0.0055175819312, 0.0055475647433, 0.0055706796759, 0.0055937957860, 0.0056079276013, 0.0056220645659, 0.0056337986965, 0.0056455222179, 0.0056422297604, 0.0056389176362, 0.0056327668217, 0.0056266091656, 0.0056091574042, 0.0055917226619, 0.0055660828884, 0.0055404363890, 0.0055079038122, 0.0054753740748, 0.0054296364962, 0.0053838906141, 0.0053277448432, 0.0052715748858, 0.0052048917290, 0.0051382369243, 0.0050611031180, 0.0049839753897, 0.0048974656698, 0.0048109527339, 0.0047074565514, 0.0046039611143, 0.0044920653988, 0.0043801801710, 0.0042526773209, 0.0041251565693, 0.0039854004245, 0.0038456425302, 0.0036928749747, 0.0035401280117, 0.0033746562534, 0.0032091902937, 0.0030269293555, 0.0028446739539, 0.0026477746403, 0.0024508568721, 0.0022391306831, 0.0020274204770, 0.0018029514204, 0.0015784683781, 0.0013343452136, 0.0010902376775, 0.0008367299190, 0.0005832296601, 0.0003054206134, 0.0000275949643, -0.0002594200645, -0.0005464255491, -0.0008516115925, -0.0011568197317, -0.0014803831871, -0.0018039541267, -0.0021433122423, -0.0024826685120, -0.0028380251464, -0.0031933817465, -0.0035667451218, -0.0039401076026, -0.0043311805485, -0.0047222586890, -0.0051279827987, -0.0055337255577, -0.0059564802822, -0.0063792311587, -0.0068204043175, -0.0072615851204, -0.0077207082313, -0.0081798213493, -0.0086561813865, -0.0091325370011, -0.0096237738418, -0.0101150314596, -0.0106232950447, -0.0111315462965, -0.0116582790656, -0.0121849952573, -0.0127284078410, 0.0132718219980, 0.0138311451561, 0.0143904592637, 0.0149655193874, 0.0155405563257, 0.0161365033964, 0.0167324755461, 0.0173379060568, 0.0179433390157, 0.0185652853849, 0.0191872443547, 0.0198202069558, 0.0204531843140, 0.0210999761274, 0.0217467552523, 0.0224073807150, 0.0230680077052, 0.0237420639970, 0.0244160996468, 0.0251018502840, 0.0257875813769, 0.0264867637542, 0.0271859403015, 0.0278965786129, 0.0286072223055, 0.0293287412129, 0.0300502657578, 0.0307760035778, 0.0315017677644, 0.0322385911186, 0.0329754179605, 0.0337187479017, 0.0344620871585, 0.0352159270599, 0.0359697555143, 0.0367255220455, 0.0374812763540, 0.0382433168854, 0.0390053697576, 0.0397701421370, 0.0405349210370, 0.0412999167409, 0.0420649194101, 0.0428373278803, 0.0436097603402, 0.0443793037143, 0.0451488448202, 0.0459165741975, 0.0466843062700, 0.0474504368762, 0.0482165646417, 0.0489775642920, 0.0497385823153, 0.0504970964492, 0.0512556073040, 0.0520093457341, 0.0527630662304, 0.0535041667383, 0.0542452690526, 0.0549813220428, 0.0557173653993, 0.0564395132831, 0.0571616382627, 0.0578766011820, 0.0585915643933, 0.0592876642498, 0.0599837452212, 0.0606646387769, 0.0613455131702, 0.0620156474286, 0.0626857856455, 0.0633286936041, 0.0639715979264, 0.0645981487145, 0.0652247009326, 0.0658307267839, 0.0664367611136, 0.0670221717462, 0.0676076079753, 0.0681559891452, 0.0687043838422, 0.0692337073129, 0.0697630166725, 0.0702629549865, 0.0707628759478, 0.0712315634186, 0.0717002581741, 0.0721342576042, 0.0725682604314, 0.0729651377816, 0.0733620227657, 0.0737312022298, 0.0741003643894, 0.0744228140298, 0.0747452534776, 0.0750294863750, 0.0753137309752, 0.0755572780429, 0.0758008300938, 0.0760000434804, 0.0761992513763, 0.0763492295011, 0.0764992119303, 0.0766042744439, 0.0767093398745, 0.0767633751145, 0.0768173954582, 0.0768201997673, 0.0768229914942, 0.0767717417580, 0.0767204942750, 0.0766127798195, 0.0765050741722, 0.0763399517187, 0.0761748271048, 0.0759527012645, 0.0757305674703, 0.0754440943880, 0.0751576275372, 0.0748120389752, 0.0744664374116, 0.0740535275534, 0.0736406055728, 0.0731590374596, 0.0726774627175, 0.0721300597492, 0.0715826345203, 0.0709679700483, 0.0703533154025, 0.0696598613057, 0.0689663921001, 0.0682094555550, 0.0674525095060, 0.0666107857601, 0.0657690713457, 0.0648567698624, 0.0639444739640, 0.0629523756575, 0.0619602868848, 0.0608884629011, 0.0598166659796, 0.0586659638617, 0.0575152710554, 0.0562806383895, 0.0550459966795, 0.0537276876358, 0.0524093819433, 0.0510036276363, 0.0495978728266, 0.0481141015474, 0.0466303207525, 0.0450536063583, 0.0434768684654, 0.0418113470397, 0.0401458200425, 0.0383938192996, 0.0366418135282, 0.0348001051306, 0.0329583954927, 0.0310203937989, 0.0290824047877, 0.0270565758359, 0.0250307595445, 0.0229152370232, 0.0207997071989, 0.0185849092217, 0.0163701328561, 0.0140662590890, 0.0117623737968, 0.0093630256607, 0.0069636910976, 0.0044701237103, 0.0019765626627, -0.0006160718469, -0.0032086847081, -0.0058899293948, -0.0085711743427, -0.0113500234728, -0.0141288758122, -0.0170061403777, -0.0198834128941, -0.0228530634389, -0.0258227375650, -0.0288879214102, -0.0319531234562, -0.0351153841344, -0.0382776482545, -0.0415291715265, -0.0447806909816, -0.0481305485026, -0.0514804188177, -0.0549254768665, -0.0583705333511, -0.0619057688888, -0.0654409770886, -0.0690676667901, -0.0726943349420, -0.0764158049026, -0.0801372926756, -0.0839460228550, -0.0877547532403, -0.0916540369715, -0.0955533319905, -0.0995431447659, -0.1035329487993, -0.1076078309406, -0.1116826856452, -0.1158452448469, -0.1200078053651, -0.1242540480203, -0.1285002933462, -0.1328277312573, -0.1371551768885, -0.1415659077401, -0.1459766566189, -0.1504686708336, -0.1549607093374, -0.1595283025664, -0.1640958787703, -0.1687383503701, -0.1733808142610, -0.1780990400378, -0.1828172523734, -0.1876069690506, -0.1923966770678, -0.1972608479266, -0.2021250183703, -0.2070492992006, -0.2119735831914, -0.2169694342266, -0.2219652633384, -0.2270171791500, -0.2320690812132, -0.2371853956606, -0.2423016905529, -0.2474748586816, -0.2526480256489, -0.2578766747326, -0.2631053356501, -0.2683843618811, -0.2736634049849, -0.2789924190238, -0.2843214254088, -0.2896965495685, -0.2950716774625, -0.3004907673195, -0.3059098614390, -0.3113688729716, -0.3168278894291, -0.3223196220800, -0.3278113723324, -0.3333418217172, -0.3388722635717, -0.3444318350435, -0.3499914122649, -0.3555752006991, 0.3611589994542, 0.3667692644921, 0.3723795603770, 0.3780072824452, 0.3836350041146, 0.3892780834412, 0.3949211684032, 0.4005764782039, 0.4062317776389, 0.4119007215285, 0.4175696873908, 0.4232408506554, 0.4289119900372, 0.4345836835439, 0.4402553743445, 0.4459275135166, 0.4515996558217, 0.4572652216857, 0.4629308042606, 0.4685880677215, 0.4742453243888, 0.4798853201396, 0.4855253145854, 0.4911480648994, 0.4967708227669, 0.5023762846177, 0.5079817400724, 0.5135526142353, 0.5191235000340, 0.5246737972393, 0.5302240884908, 0.5357397180600, 0.5412553475411, 0.5467302419087, 0.5522051263104, 0.5576420296770, 0.5630789053140, 0.5684656541449, 0.5738524091594, 0.5791963774384, 0.5845403276635, 0.5898263122286, 0.5951123147636, 0.6003453352359, 0.6055783444773, 0.6107446766601, 0.6159109984769, 0.6210176335538, 0.6261242644607, 0.6311611315428, 0.6361980097723, 0.6411624903953, 0.6461269646247, 0.6510142937142, 0.6559016399581, 0.6607078128371, 0.6655139870093, 0.6702401473311, 0.6749663289682, 0.6796008198535, 0.6842353261119, 0.6887817750021, 0.6933282316192, 0.6977835605066, 0.7022388743098, 0.7065899657830, 0.7109410429680, 0.7151936458078, 0.7194462550033, 0.7235955759236, 0.7277448954474, 0.7317830379552, 0.7358211812312, 0.7397519890246, 0.7436827956087, 0.7474982580821, 0.7513137453267, 0.7550109081443, 0.7587080846807, 0.7622877890950, 0.7658674845073, 0.7693227784089, 0.7727780946395, 0.7761034130896, 0.7794287461480, 0.7826320306499, 0.7858353214217, 0.7889044522646, 0.7919735858404, 0.7949101196306, 0.7978466399825, 0.8006476091170, 0.8034485723241, 0.8061090405782, 0.8087694965052, 0.8112943189503, 0.8138191301784, 0.8161983628005, 0.8185776070011, 0.8208098026271, 0.8230419833267, 0.8251347532814, 0.8272275373755, 0.8291656850689, 0.8311038496718, 0.8328987918843, 0.8346937360492, 0.8363327361895, 0.8379717266217, 0.8394629333539, 0.8409541296434, 0.8422889785528, 0.8436238352155, 0.8448028351663, 0.8459818486135, 0.8470067050139, 0.8480315835964, 0.8489060396447, 0.8497805277784, 0.8504888339266, 0.8511971453674, 0.8517509372895, 0.8523047120534, 0.8527033945043, 0.8531021044567, 0.8533370702489, 0.8535720597213, 0.8536553025990, 0.8537385506405, 0.8536553025990, 0.8535720597213, 0.8533370702489, 0.8531021044567, 0.8527033945043, 0.8523047120534, 0.8517509372895, 0.8511971453674, 0.8504888339266, 0.8497805277784, 0.8489060396447, 0.8480315835964, 0.8470067050139, 0.8459818486135, 0.8448028351663, 0.8436238352155, 0.8422889785528, 0.8409541296434, 0.8394629333539, 0.8379717266217, 0.8363327361895, 0.8346937360492, 0.8328987918843, 0.8311038496718, 0.8291656850689, 0.8272275373755, 0.8251347532814, 0.8230419833267, 0.8208098026271, 0.8185776070011, 0.8161983628005, 0.8138191301784, 0.8112943189503, 0.8087694965052, 0.8061090405782, 0.8034485723241, 0.8006476091170, 0.7978466399825, 0.7949101196306, 0.7919735858404, 0.7889044522646, 0.7858353214217, 0.7826320306499, 0.7794287461480, 0.7761034130896, 0.7727780946395, 0.7693227784089, 0.7658674845073, 0.7622877890950, 0.7587080846807, 0.7550109081443, 0.7513137453267, 0.7474982580821, 0.7436827956087, 0.7397519890246, 0.7358211812312, 0.7317830379552, 0.7277448954474, 0.7235955759236, 0.7194462550033, 0.7151936458078, 0.7109410429680, 0.7065899657830, 0.7022388743098, 0.6977835605066, 0.6933282316192, 0.6887817750021, 0.6842353261119, 0.6796008198535, 0.6749663289682, 0.6702401473311, 0.6655139870093, 0.6607078128371, 0.6559016399581, 0.6510142937142, 0.6461269646247, 0.6411624903953, 0.6361980097723, 0.6311611315428, 0.6261242644607, 0.6210176335538, 0.6159109984769, 0.6107446766601, 0.6055783444773, 0.6003453352359, 0.5951123147636, 0.5898263122286, 0.5845403276635, 0.5791963774384, 0.5738524091594, 0.5684656541449, 0.5630789053140, 0.5576420296770, 0.5522051263104, 0.5467302419087, 0.5412553475411, 0.5357397180600, 0.5302240884908, 0.5246737972393, 0.5191235000340, 0.5135526142353, 0.5079817400724, 0.5023762846177, 0.4967708227669, 0.4911480648994, 0.4855253145854, 0.4798853201396, 0.4742453243888, 0.4685880677215, 0.4629308042606, 0.4572652216857, 0.4515996558217, 0.4459275135166, 0.4402553743445, 0.4345836835439, 0.4289119900372, 0.4232408506554, 0.4175696873908, 0.4119007215285, 0.4062317776389, 0.4005764782039, 0.3949211684032, 0.3892780834412, 0.3836350041146, 0.3780072824452, 0.3723795603770, 0.3667692644921, -0.3611589811729, -0.3555752006991, -0.3499914122649, -0.3444318350435, -0.3388722635717, -0.3333418217172, -0.3278113723324, -0.3223196220800, -0.3168278894291, -0.3113688729716, -0.3059098614390, -0.3004907673195, -0.2950716774625, -0.2896965495685, -0.2843214254088, -0.2789924190238, -0.2736634049849, -0.2683843618811, -0.2631053356501, -0.2578766747326, -0.2526480256489, -0.2474748586816, -0.2423016905529, -0.2371853956606, -0.2320690812132, -0.2270171791500, -0.2219652633384, -0.2169694342266, -0.2119735831914, -0.2070492992006, -0.2021250183703, -0.1972608479266, -0.1923966770678, -0.1876069690506, -0.1828172523734, -0.1780990400378, -0.1733808142610, -0.1687383503701, -0.1640958787703, -0.1595283025664, -0.1549607093374, -0.1504686708336, -0.1459766566189, -0.1415659077401, -0.1371551768885, -0.1328277312573, -0.1285002933462, -0.1242540480203, -0.1200078053651, -0.1158452448469, -0.1116826856452, -0.1076078309406, -0.1035329487993, -0.0995431447659, -0.0955533319905, -0.0916540369715, -0.0877547532403, -0.0839460228550, -0.0801372926756, -0.0764158049026, -0.0726943349420, -0.0690676667901, -0.0654409770886, -0.0619057688888, -0.0583705333511, -0.0549254768665, -0.0514804188177, -0.0481305485026, -0.0447806909816, -0.0415291715265, -0.0382776482545, -0.0351153841344, -0.0319531234562, -0.0288879214102, -0.0258227375650, -0.0228530634389, -0.0198834128941, -0.0170061403777, -0.0141288758122, -0.0113500234728, -0.0085711743427, -0.0058899293948, -0.0032086847081, -0.0006160718469, 0.0019765626627, 0.0044701237103, 0.0069636910976, 0.0093630256607, 0.0117623737968, 0.0140662590890, 0.0163701328561, 0.0185849092217, 0.0207997071989, 0.0229152370232, 0.0250307595445, 0.0270565758359, 0.0290824047877, 0.0310203937989, 0.0329583954927, 0.0348001051306, 0.0366418135282, 0.0383938192996, 0.0401458200425, 0.0418113470397, 0.0434768684654, 0.0450536063583, 0.0466303207525, 0.0481141015474, 0.0495978728266, 0.0510036276363, 0.0524093819433, 0.0537276876358, 0.0550459966795, 0.0562806383895, 0.0575152710554, 0.0586659638617, 0.0598166659796, 0.0608884629011, 0.0619602868848, 0.0629523756575, 0.0639444739640, 0.0648567698624, 0.0657690713457, 0.0666107857601, 0.0674525095060, 0.0682094555550, 0.0689663921001, 0.0696598613057, 0.0703533154025, 0.0709679700483, 0.0715826345203, 0.0721300597492, 0.0726774627175, 0.0731590374596, 0.0736406055728, 0.0740535275534, 0.0744664374116, 0.0748120389752, 0.0751576275372, 0.0754440943880, 0.0757305674703, 0.0759527012645, 0.0761748271048, 0.0763399517187, 0.0765050741722, 0.0766127798195, 0.0767204942750, 0.0767717417580, 0.0768229914942, 0.0768201997673, 0.0768173954582, 0.0767633751145, 0.0767093398745, 0.0766042744439, 0.0764992119303, 0.0763492295011, 0.0761992513763, 0.0760000434804, 0.0758008300938, 0.0755572780429, 0.0753137309752, 0.0750294863750, 0.0747452534776, 0.0744228140298, 0.0741003643894, 0.0737312022298, 0.0733620227657, 0.0729651377816, 0.0725682604314, 0.0721342576042, 0.0717002581741, 0.0712315634186, 0.0707628759478, 0.0702629549865, 0.0697630166725, 0.0692337073129, 0.0687043838422, 0.0681559891452, 0.0676076079753, 0.0670221717462, 0.0664367611136, 0.0658307267839, 0.0652247009326, 0.0645981487145, 0.0639715979264, 0.0633286936041, 0.0626857856455, 0.0620156474286, 0.0613455131702, 0.0606646387769, 0.0599837452212, 0.0592876642498, 0.0585915643933, 0.0578766011820, 0.0571616382627, 0.0564395132831, 0.0557173653993, 0.0549813220428, 0.0542452690526, 0.0535041667383, 0.0527630662304, 0.0520093457341, 0.0512556073040, 0.0504970964492, 0.0497385823153, 0.0489775642920, 0.0482165646417, 0.0474504368762, 0.0466843062700, 0.0459165741975, 0.0451488448202, 0.0443793037143, 0.0436097603402, 0.0428373278803, 0.0420649194101, 0.0412999167409, 0.0405349210370, 0.0397701421370, 0.0390053697576, 0.0382433168854, 0.0374812763540, 0.0367255220455, 0.0359697555143, 0.0352159270599, 0.0344620871585, 0.0337187479017, 0.0329754179605, 0.0322385911186, 0.0315017677644, 0.0307760035778, 0.0300502657578, 0.0293287412129, 0.0286072223055, 0.0278965786129, 0.0271859403015, 0.0264867637542, 0.0257875813769, 0.0251018502840, 0.0244160996468, 0.0237420639970, 0.0230680077052, 0.0224073807150, 0.0217467552523, 0.0210999761274, 0.0204531843140, 0.0198202069558, 0.0191872443547, 0.0185652853849, 0.0179433390157, 0.0173379060568, 0.0167324755461, 0.0161365033964, 0.0155405563257, 0.0149655193874, 0.0143904592637, 0.0138311451561, -0.0132718220090, -0.0127284078410, -0.0121849952573, -0.0116582790656, -0.0111315462965, -0.0106232950447, -0.0101150314596, -0.0096237738418, -0.0091325370011, -0.0086561813865, -0.0081798213493, -0.0077207082313, -0.0072615851204, -0.0068204043175, -0.0063792311587, -0.0059564802822, -0.0055337255577, -0.0051279827987, -0.0047222586890, -0.0043311805485, -0.0039401076026, -0.0035667451218, -0.0031933817465, -0.0028380251464, -0.0024826685120, -0.0021433122423, -0.0018039541267, -0.0014803831871, -0.0011568197317, -0.0008516115925, -0.0005464255491, -0.0002594200645, 0.0000275949643, 0.0003054206134, 0.0005832296601, 0.0008367299190, 0.0010902376775, 0.0013343452136, 0.0015784683781, 0.0018029514204, 0.0020274204770, 0.0022391306831, 0.0024508568721, 0.0026477746403, 0.0028446739539, 0.0030269293555, 0.0032091902937, 0.0033746562534, 0.0035401280117, 0.0036928749747, 0.0038456425302, 0.0039854004245, 0.0041251565693, 0.0042526773209, 0.0043801801710, 0.0044920653988, 0.0046039611143, 0.0047074565514, 0.0048109527339, 0.0048974656698, 0.0049839753897, 0.0050611031180, 0.0051382369243, 0.0052048917290, 0.0052715748858, 0.0053277448432, 0.0053838906141, 0.0054296364962, 0.0054753740748, 0.0055079038122, 0.0055404363890, 0.0055660828884, 0.0055917226619, 0.0056091574042, 0.0056266091656, 0.0056327668217, 0.0056389176362, 0.0056422297604, 0.0056455222179, 0.0056337986965, 0.0056220645659, 0.0056079276013, 0.0055937957860, 0.0055706796759, 0.0055475647433, 0.0055175819312, 0.0054875987642, 0.0054536384534, 0.0054196692329, 0.0053834300667, 0.0053471668162, 0.0052966510528, 0.0052461239441, 0.0051934305868, 0.0051407363835, 0.0050900151409, 0.0050393080129, 0.0049765248518, 0.0049137657537, 0.0048535152844, 0.0047932482139, 0.0047269540845, 0.0046606421516, 0.0045908246900, 0.0045209852815, 0.0044470261882, 0.0043730783438, 0.0042997543412, 0.0042264200821, 0.0041542084654, 0.0040819786631, 0.0040013511319, 0.0039207434248, 0.0038405755459, 0.0037603943985, 0.0036806138717, 0.0036008198759, 0.0035213512278, 0.0034418941739, 0.0033579247943, 0.0032739529064, 0.0031932528503, 0.0031125415322, 0.0030297492329, 0.0029469530526, 0.0028669900755, 0.0027870398286, 0.0027036125466, 0.0026201724337, 0.0025413674009, 0.0024625676012, 0.0023821487099, 0.0023017300059, 0.0022239322768, 0.0021461575925, 0.0020651392863, 0.0019841117942, 0.0019094781805, 0.0018348194834, 0.0017608243873, 0.0016868125944, 0.0016155684463, 0.0015443257222, 0.0014672773757, 0.0013902546415, 0.0013240150513, 0.0012577875050, 0.0011914037242, 0.0011250228994, 0.0010567976484, 0.0009886054038, 0.0009247267892, 0.0008608421186, 0.0008033299866, 0.0007458077212, 0.0006848671621, 0.0006239305560, 0.0005673469176, 0.0005107402212, 0.0004567034861, 0.0004026588663, 0.0003487948377, 0.0002949442047, 0.0002496306494, 0.0002042941489, 0.0001568793435, 0.0001094394708, 0.0000614720333, 0.0000134965582, -0.0000241262916, -0.0000617345700, -0.0001031896779, -0.0001446327356, -0.0001772307680, -0.0002098366519, -0.0002497595743, -0.0002897008523, -0.0003199111004, -0.0003501149003, -0.0003798107209, -0.0004095097465, -0.0004350627059, -0.0004606378785, -0.0004875885201, -0.0005145569911, -0.0005355145456, -0.0005564609970, -0.0005755259068, -0.0005946202616, -0.0006143876230, -0.0006341674870, -0.0006495992993, -0.0006650339491, -0.0006784128723, -0.0006917932571, -0.0007066606628, -0.0007215430902, -0.0007267356718, -0.0007319442929, -0.0007424619382, -0.0007530028195, -0.0007580352349, -0.0007630873596, -0.0007694345970, -0.0007758066727, -0.0007779723824, -0.0007801371586, -0.0007802465749, -0.0007803615976, -0.0007791681113, -0.0007779944598, -0.0007807033412, -0.0007834287454, -0.0007779534357, -0.0007724918034, -0.0007703168846, -0.0007681336013, -0.0007586070399, -0.0007490661119, -0.0007465733138, -0.0007440890752, -0.0007348050240, -0.0007255024482, -0.0007206486380, -0.0007157690669, -0.0007049595278, -0.0006941641036, -0.0006859690454, -0.0006777676604, -0.0006658914180, -0.0006540371501, -0.0006426322143, -0.0006312541653, -0.0006222713668, -0.0006132728105, -0.0006001850920, -0.0005870916039, -0.0005774439998, -0.0005677828639, -0.0005572187697, -0.0005466472274, -0.0005346514478, -0.0005226597455, -0.0005133670560, -0.0005040750825, -0.0004967240815, -0.0004893838045, -0.0004884532092, -0.0004875236552, -0.0004911467040, -0.0004947593820, -0.0005282514607, -0.0005617683373, -0.0005571552713, -0.0005525342198, -0.0002762634720 };
42
45static const double __qmf_fb8bandCoeffs[13] =
46{ 0.0074608293425, 0.0227042095837, 0.0454686594059, 0.0726611394476, 0.0988510858112, 0.1179371056821, 0.1250000000000, 0.1179371056821, 0.0988510858112, 0.0726611394476, 0.0454686594059, 0.0227042095837, 0.0074608293425 };
47
49static const double __qmf_fb4bandCoeffs[13] =
50{ 0.0000000000000, 0.0189948752516, 0.0000000000000, -0.0729313916667, 0.0000000000000, 0.3059663054427, 0.5000000000000, 0.3059663054427, 0.0000000000000, -0.0729313916667, 0.0000000000000, 0.0189948752516, 0.0000000000000 };
51
56{ { 0.1013f, 0.0f, 0.0f},
57 { 0.2027f, 0.0f, 0.0f},
58 { 0.4054f, 0.0f, 0.0f},
59 { 0.8108f, 0.0f, 0.0f},
60 { 1.2533f, 0.0f, 0.0f},
61 { 1.7227f, 0.0f, 0.0f},
62 { 0.0f, 0.9039f, 0.0f},
63 { 0.0f, 1.1228f, 0.0f},
64 { 0.0f, 0.0f, 0.9424f},
65 { 0.0f, 0.0f, 1.0672f} };
66
68static void qmfAnalyse
69(
70 float* inTD/* nSamplesTD x nCH */,
71 int nSamplesTD,
72 int nCH,
73 int hopSize,
74 int hybridmode,
75 float_complex* outTF /* out_nBands x nTimeslots x nCH */
76)
77{
78 int t, ch, sample, band;
79 void* hQMF;
80 float_complex*** FrameTF;
81 float** tempFrameTD;
82 int nTimeSlots, nBands;
83
84 nBands = hopSize + (hybridmode ? 7 : 0);
85 nTimeSlots = (int)((float)nSamplesTD / (float)hopSize + 0.9999f); /*ceil*/
86
87 /* allocate memory */
88 qmf_create(&(hQMF), nCH, 1, hopSize, hybridmode, QMF_TIME_CH_BANDS);
89 FrameTF = (float_complex***)malloc3d(nTimeSlots, nCH, nBands, sizeof(float_complex));
90 tempFrameTD = (float**)calloc2d(nCH, nTimeSlots*hopSize, sizeof(float));
91
92 /* perform TF transform */
93 for(ch=0; ch<nCH; ch++)
94 for(sample=0; sample<nSamplesTD; sample++)
95 tempFrameTD[ch][sample] = inTD[sample* nCH + ch];
96 qmf_analysis(hQMF, tempFrameTD, nTimeSlots*hopSize, FrameTF);
97
98 /* save result to output */
99 for (band = 0; band < nBands; band++)
100 for (t = 0; t < nTimeSlots; t++)
101 for (ch = 0; ch < nCH; ch++)
102 outTF[band * nTimeSlots * nCH + t * nCH + ch] = FrameTF[t][ch][band];
103
104 /* clean-up */
105 qmf_destroy(&hQMF);
106 free(FrameTF);
107 free(tempFrameTD);
108}
109
111typedef struct _qmf_data {
114 int nCHin;
115 int nCHout;
116 int nBands;
120 /* QMF Analysis and Synthesis filters */
121 float_complex** h_a;
122 float** h_s_real;
123 float** h_s_imag;
124
125 /* Prototype window */
126 float* h_p;
127
128 /* For run-time */
129 float** buffer_ana;
130 float** buffer_syn;
131 float* buffer_win;
132 float* win_sum;
133 float* win_sum_cmplx_dummy; /* treated as complex data type (interleaved with zeros for imag parts) */
134 float_complex* qmfTF_frame;
135 float* qmfTF_frame_tmp; /* used when taking the real/imag parts */
136 float* tmp_real_frame;
137 float* tmp_imag_frame;
138
139 /* For hybrid filtering */
140 float_complex fb8bandCoeffs[8][QMF_HYBRID_FILTER_LENGTH];
141 float_complex fb4bandCoeffs[2][QMF_HYBRID_FILTER_LENGTH];
142 float_complex*** hybBuffer;
143 float_complex*** qmfDelayBuffer;
144 float_complex* hybQmfTF_frame;
145
146}qmf_data;
147
148
150(
151 void ** const phQMF,
152 int nCHin,
153 int nCHout,
154 int hopsize,
155 int hybridmode,
156 QMF_FDDATA_FORMAT format
157)
158{
159 *phQMF = malloc1d(sizeof(qmf_data));
160 qmf_data *h = (qmf_data*)(*phQMF);
161 int i,j,K,N,dsFactor;
162 float scale, eq;
163 float* k_tmp, *n_tmp;
164
165 saf_assert(hopsize==4 || hopsize==8 || hopsize==16 || hopsize==32 || hopsize==64 || hopsize==128, "Unsupported hopsize");
166
167 h->nCHin = nCHin;
168 h->nCHout = nCHout;
169 h->hopsize = hopsize;
170 h->hybridmode = hybridmode;
171 h->nBands = hybridmode ? hopsize+7 : hopsize; /* hybrid mode incurs an additional 7 bands */
172 h->format = format;
173
174 K = hopsize;
175 N = 2*hopsize;
176 k_tmp = malloc1d(K*sizeof(float));
177 n_tmp = malloc1d(N*sizeof(float));
178
179 /* QMF Analysis filters */
180 h->h_a = (float_complex**)malloc2d(K, N, sizeof(float_complex));
181 scale = (float)QMF_MAX_HOP_SIZE / (2.0f*(float)hopsize); /* (Used to balance the levels between different hopsizes) */
182 for(i=0; i<K; i++)
183 k_tmp[i] = SAF_PI/2.0f/(float)K * ((float)i+0.5f);
184 for(i=0; i<N; i++)
185 n_tmp[i] = 2.0f*(float)i - 2.0f*(float)K/(float)QMF_MAX_HOP_SIZE;
186 for(i=0; i<K; i++)
187 for(j=0; j<N; j++)
188 h->h_a[i][j] = crmulf(cexpf(cmplxf(0.0f, k_tmp[i]*n_tmp[j])), scale);
189
190 /* QMF Synthesis filters */
191 h->h_s_real = (float**)malloc2d(N, K, sizeof(float));
192 h->h_s_imag = (float**)malloc2d(N, K, sizeof(float));
193 scale = 2.0f / QMF_MAX_HOP_SIZE; /* (Used to balance the levels between different hopsizes) */
194 for(i=0; i<N; i++)
195 n_tmp[i] = 2.0f*(float)i - (2.0f*(float)QMF_MAX_HOP_SIZE-1.0f)*(float)K/((float)QMF_MAX_HOP_SIZE/2.0f);
196 for(i=0; i<N; i++){
197 for(j=0; j<K; j++){
198 h->h_s_real[i][j] = scale * cosf(k_tmp[j]*n_tmp[i]);
199 h->h_s_imag[i][j] = scale * sinf(k_tmp[j]*n_tmp[i]);
200 }
201 }
202
203 /* Prototype filter */
204 h->h_p = malloc1d(10*hopsize*sizeof(float));
205 if(hopsize<=QMF_MAX_HOP_SIZE)
206 for(i=0,j=0; i<10*QMF_MAX_HOP_SIZE; i+=QMF_MAX_HOP_SIZE/hopsize, j++)
207 h->h_p[j] = (float)__qmf_protofilter[i];
208 else{ /* Borrow the one from afSTFT: */
209 eq = 2.0f/sqrtf(5.487604141f);
210 dsFactor = 1024/hopsize;
211 for(i=0; i<10*hopsize; i++)
212 h->h_p[i] = __afSTFT_protoFilter1024[i*dsFactor]*eq;
213 }
214
215 /* Run-time buffers */
216 h->buffer_ana = (float**)malloc1d(nCHin*sizeof(float*)); /* actually faster to go with non-contiguous allocated memory here due to memmove... */
217 for(i=0; i<nCHin; i++)
218 h->buffer_ana[i] = calloc1d(hopsize * 10, sizeof(float));
219 h->buffer_syn = (float**)malloc1d(nCHout*sizeof(float*));
220 for(i=0; i<nCHout; i++)
221 h->buffer_syn[i] = calloc1d(hopsize * 20, sizeof(float));
222 h->buffer_win = malloc1d(hopsize * 10 * sizeof(float));
223 h->win_sum = malloc1d(hopsize * 2 * sizeof(float));
224 h->win_sum_cmplx_dummy = calloc1d(hopsize * 4, sizeof(float)); /* ca */
225 h->qmfTF_frame = malloc1d(hopsize * sizeof(float_complex));
226 h->qmfTF_frame_tmp = malloc1d(hopsize * sizeof(float));
227 h->tmp_real_frame = malloc1d(hopsize * 2 * sizeof(float));
228 h->tmp_imag_frame = malloc1d(hopsize * 2 * sizeof(float));
229
230 /* Init hybrid filtering coefficients: */
231 if(hybridmode){
232 /* Coefficients to subdivide the lowest QMF band into 8 subbands. The
233 * 1st, 2nd, 7th and 8th subbands then become the 1st, 2nd, 5th and 6th
234 * hybrid bands directly. Hybrid bands 3 and 4 are then obtained by
235 * summing subbands 3 and 6, and 4 and 5, respectively. Therefore, this
236 * raises the total number of bands by 5.
237 * (Note: __fb8bandCoeffs = 0.125*kaiser(13, 4.6) ) */
238 for(i=0; i<8; i++)
239 for(j=0; j<QMF_HYBRID_FILTER_LENGTH; j++)
240 h->fb8bandCoeffs[i][j] = crmulf(cexpf(cmplxf(0.0f, -1.0f*SAF_PI*((float)j-((float)QMF_HYBRID_FILTER_LENGTH-1.0f)/2.0f)/8.0f*(1.0f+2.0f*(float)i))),
241 (float)__qmf_fb8bandCoeffs[j]);
242
243 /* Coefficients to subdivide the 2nd and 3rd lowest QMF bands into 4
244 * subbands each. The 1st and 4th subdivided bands, and 2nd and 3rd
245 * subdivided bands are then summed to obtain the 2 hybrid bands for
246 * each QMF band . Therefore, this raises the total number of bands by
247 * 2 */
248 for(i=0; i<2; i++)
249 for(j=0; j<QMF_HYBRID_FILTER_LENGTH; j++)
250 h->fb4bandCoeffs[i][j] = cmplxf((float)__qmf_fb4bandCoeffs[j] *
251 cosf(2.0f*SAF_PI*(float)i*((float)j-(((float)QMF_HYBRID_FILTER_LENGTH-1.0f)/2.0f))/2.0f), 0.0f);
252
253 /* For run-time */
254 h->qmfDelayBuffer = (float_complex***)calloc3d(nCHin, hopsize-QMF_NBANDS_2_SUBDIVIDE, (QMF_HYBRID_FILTER_LENGTH-1)/2 + 1, sizeof(float_complex)); /* ca */
255 h->hybBuffer = (float_complex***)calloc3d(nCHin, QMF_NBANDS_2_SUBDIVIDE, QMF_HYBRID_FILTER_LENGTH, sizeof(float_complex));
256 h->hybQmfTF_frame = malloc1d(h->nBands * sizeof(float_complex));
257
258 /* Processing delay */
259 h->procDelay = hopsize*15+1;
260 }
261 else{
262 /* Processing delay */
263 h->procDelay = hopsize*9+1;
264 }
265
266 /* clean-up */
267 free(k_tmp);
268 free(n_tmp);
269}
270
272(
273 void ** const phQMF
274)
275{
276 qmf_data *h = (qmf_data*)(*phQMF);
277 int i;
278
279 if(h!=NULL){
280 /* QMF Analysis and Synthesis filters */
281 free(h->h_a);
282 free(h->h_s_real);
283 free(h->h_s_imag);
284
285 /* Prototype window */
286 free(h->h_p);
287
288 /* For run-time */
289 for(i=0; i<h->nCHin; i++)
290 free(h->buffer_ana[i]);
291 for(i=0; i<h->nCHout; i++)
292 free(h->buffer_syn[i]);
293 free(h->buffer_win);
294 free(h->win_sum);
295 free(h->win_sum_cmplx_dummy);
296 free(h->qmfTF_frame);
297 free(h->qmfTF_frame_tmp);
298 free(h->tmp_real_frame);
299 free(h->tmp_imag_frame);
300
301 /* For hybrid filtering */
302 if(h->hybridmode){
303 free(h->qmfDelayBuffer);
304 free(h->hybBuffer);
305 free(h->hybQmfTF_frame);
306 }
307
308 free(h);
309 h=NULL;
310 *phQMF = NULL;
311 }
312}
313
315(
316 void * const hQMF,
317 float** dataTD,
318 int framesize,
319 float_complex*** dataFD
320)
321{
322 qmf_data *h = (qmf_data*)(hQMF);
323 int i, ch, t, nHops, band;
324 float_complex subBands8[8], subBands2[2];
325 const float_complex calpha = cmplxf(1.0f, 0.0f), cbeta = cmplxf(0.0f, 0.0f);
326
327 saf_assert(framesize % h->hopsize == 0, "framesize must be multiple of hopsize");
328 nHops = framesize/h->hopsize;
329
330 for(ch=0; ch<h->nCHin; ch++){
331 for(t=0; t<nHops; t++){
332 /* Shift samples to the right by one hopsize, and copy the current frame
333 to the beginning */
334 memmove(&(h->buffer_ana[ch][h->hopsize]), h->buffer_ana[ch], h->hopsize * 9 * sizeof(float));
335 cblas_scopy(h->hopsize, &dataTD[ch][t*(h->hopsize)], -1, h->buffer_ana[ch], 1);
336
337 /* Apply prototype filter/window */
338 utility_svvmul(h->buffer_ana[ch], h->h_p, h->hopsize*10, h->buffer_win);
339
340 /* Sum all 5 consecutive 1:2*hopsize */
341 utility_svvadd(h->buffer_win, &(h->buffer_win[h->hopsize*2]), h->hopsize*2, h->win_sum);
342 cblas_saxpy(h->hopsize*2, 1.0f, h->buffer_win + h->hopsize*4, 1, h->win_sum, 1);
343 cblas_saxpy(h->hopsize*2, 1.0f, h->buffer_win + h->hopsize*6, 1, h->win_sum, 1);
344 cblas_saxpy(h->hopsize*2, 1.0f, h->buffer_win + h->hopsize*8, 1, h->win_sum, 1);
345 cblas_scopy(h->hopsize*2, h->win_sum, 1, h->win_sum_cmplx_dummy, 2);
346
347 /* Apply complex-QMF analysis modulators */
348 cblas_cgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, h->hopsize, 1, h->hopsize*2, &calpha,
349 FLATTEN2D(h->h_a), h->hopsize*2,
350 (float_complex*)h->win_sum_cmplx_dummy, 1, &cbeta,
351 h->qmfTF_frame, 1);
352
353 /* Subdivide the lowest 3 bands */
354 if(h->hybridmode){
355 /* Shift buffer down by 1 frame */
356 memmove(h->hybBuffer[ch][0], &(h->hybBuffer[ch][0][1]), (QMF_HYBRID_FILTER_LENGTH-1)*sizeof(float_complex));
357 memmove(h->hybBuffer[ch][1], &(h->hybBuffer[ch][1][1]), (QMF_HYBRID_FILTER_LENGTH-1)*sizeof(float_complex));
358 memmove(h->hybBuffer[ch][2], &(h->hybBuffer[ch][2][1]), (QMF_HYBRID_FILTER_LENGTH-1)*sizeof(float_complex));
359
360 /* Append new frame to hybrid filtering buffer */
361 h->hybBuffer[ch][0][QMF_HYBRID_FILTER_LENGTH-1] = h->qmfTF_frame[0];
362 h->hybBuffer[ch][1][QMF_HYBRID_FILTER_LENGTH-1] = h->qmfTF_frame[1];
363 h->hybBuffer[ch][2][QMF_HYBRID_FILTER_LENGTH-1] = h->qmfTF_frame[2];
364
365 /* Delay all the other QMF bands (i.e., the ones not being subdivided)
366 * so that they align with the hybrid bands in time: */
367 for(i=0; i<h->hopsize - QMF_NBANDS_2_SUBDIVIDE; i++){
368 memmove(h->qmfDelayBuffer[ch][i], &(h->qmfDelayBuffer[ch][i][1]), ((QMF_HYBRID_FILTER_LENGTH-1)/2)*sizeof(float_complex));
369 h->qmfDelayBuffer[ch][i][(QMF_HYBRID_FILTER_LENGTH-1)/2] = h->qmfTF_frame[i+QMF_NBANDS_2_SUBDIVIDE];
370 }
371
372 /* Subdivide first QMF band into 8 subbands, and form hybrid bands 1-6 */
373 cblas_cgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, 8, 1, QMF_HYBRID_FILTER_LENGTH, &calpha,
374 h->fb8bandCoeffs, QMF_HYBRID_FILTER_LENGTH,
375 h->hybBuffer[ch][0], 1, &cbeta,
376 subBands8, 1);
377 h->hybQmfTF_frame[0] = subBands8[6];
378 h->hybQmfTF_frame[1] = subBands8[7];
379 h->hybQmfTF_frame[2] = subBands8[0];
380 h->hybQmfTF_frame[3] = subBands8[1];
381#if _MSC_VER >= 1900
382 h->hybQmfTF_frame[4] = ccaddf(subBands8[2], subBands8[5]);
383 h->hybQmfTF_frame[5] = ccaddf(subBands8[3], subBands8[4]);
384#else
385 h->hybQmfTF_frame[4] = subBands8[2] + subBands8[5];
386 h->hybQmfTF_frame[5] = subBands8[3] + subBands8[4];
387#endif
388
389 /* Subdivide second QMF band to get hybrid bands 7 and 8 */
390 cblas_cgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, 2, 1, QMF_HYBRID_FILTER_LENGTH, &calpha,
391 h->fb4bandCoeffs, QMF_HYBRID_FILTER_LENGTH,
392 h->hybBuffer[ch][1], 1, &cbeta,
393 subBands2, 1);
394 h->hybQmfTF_frame[6] = subBands2[1]; /* Flipped! */
395 h->hybQmfTF_frame[7] = subBands2[0];
396
397 /* Subdivide third QMF band to get hybrid bands 9 and 10 */
398 cblas_cgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, 2, 1, QMF_HYBRID_FILTER_LENGTH, &calpha,
399 h->fb4bandCoeffs, QMF_HYBRID_FILTER_LENGTH,
400 h->hybBuffer[ch][2], 1, &cbeta,
401 subBands2, 1);
402 h->hybQmfTF_frame[8] = subBands2[0];
403 h->hybQmfTF_frame[9] = subBands2[1];
404
405 /* The remaining bands are then just the delayed qmf bands, 4:end */
406 cblas_ccopy(h->hopsize - QMF_NBANDS_2_SUBDIVIDE, FLATTEN2D(h->qmfDelayBuffer[ch]),
407 (QMF_HYBRID_FILTER_LENGTH-1)/2 + 1, &(h->hybQmfTF_frame[10]), 1);
408 }
409
410 /* copy to output */
411 if(h->hybridmode){
412 switch(h->format){
414 for(band=0; band<h->nBands; band++)
415 dataFD[band][ch][t] = h->hybQmfTF_frame[band];
416 break;
418 memcpy(dataFD[t][ch], h->hybQmfTF_frame, h->nBands*sizeof(float_complex));
419 break;
420 }
421 }
422 else{
423 switch(h->format){
425 for(band=0; band<h->nBands; band++)
426 dataFD[band][ch][t] = h->qmfTF_frame[band];
427 break;
429 memcpy(dataFD[t][ch], h->qmfTF_frame, h->nBands*sizeof(float_complex));
430 break;
431 }
432 }
433 }
434 }
435}
436
438(
439 void * const hQMF,
440 float_complex*** dataFD,
441 int framesize,
442 float** dataTD
443)
444{
445 qmf_data *h = (qmf_data*)(hQMF);
446 int ch, t, nHops, band;
447
448 saf_assert(framesize % h->hopsize == 0, "framesize must be multiple of hopsize");
449 nHops = framesize/h->hopsize;
450
451 for(ch=0; ch<h->nCHout; ch++){
452 for(t=0; t<nHops; t++){
453 /* Load frequency domain data */
454 if(h->hybridmode){
455 switch(h->format){
457 for(band=0; band<h->nBands; band++)
458 h->hybQmfTF_frame[band] = dataFD[band][ch][t];
459 break;
461 memcpy(h->hybQmfTF_frame, dataFD[t][ch], h->nBands*sizeof(float_complex));
462 break;
463 }
464
465 /* Recombine the hybrid bands: */
466#if _MSC_VER >= 1900
467 h->qmfTF_frame[0] = ccaddf( h->hybQmfTF_frame[0], h->hybQmfTF_frame[1]);
468 h->qmfTF_frame[0] = ccaddf( h->qmfTF_frame[0], h->hybQmfTF_frame[2]);
469 h->qmfTF_frame[0] = ccaddf( h->qmfTF_frame[0], h->hybQmfTF_frame[3]);
470 h->qmfTF_frame[0] = ccaddf( h->qmfTF_frame[0], h->hybQmfTF_frame[4]);
471 h->qmfTF_frame[0] = ccaddf( h->qmfTF_frame[0], h->hybQmfTF_frame[5]);
472 h->qmfTF_frame[1] = ccaddf( h->hybQmfTF_frame[6], h->hybQmfTF_frame[7]);
473 h->qmfTF_frame[2] = ccaddf( h->hybQmfTF_frame[8], h->hybQmfTF_frame[9]);
474#else
475 h->qmfTF_frame[0] = h->hybQmfTF_frame[0]+h->hybQmfTF_frame[1]+h->hybQmfTF_frame[2]+
476 h->hybQmfTF_frame[3]+h->hybQmfTF_frame[4]+h->hybQmfTF_frame[5];
477 h->qmfTF_frame[1] = h->hybQmfTF_frame[6]+h->hybQmfTF_frame[7];
478 h->qmfTF_frame[2] = h->hybQmfTF_frame[8]+h->hybQmfTF_frame[9];
479#endif
480 memmove(&(h->qmfTF_frame[3]), &(h->hybQmfTF_frame[10]), (h->hopsize - QMF_NBANDS_2_SUBDIVIDE)*sizeof(float_complex));
481 }
482 else{
483 switch(h->format){
485 for(band=0; band<h->nBands; band++)
486 h->qmfTF_frame[band] = dataFD[band][ch][t];
487 break;
489 memcpy(h->qmfTF_frame, dataFD[t][ch], h->nBands*sizeof(float_complex));
490 break;
491 }
492 }
493
494 /* Shift samples to the right by 2*hopsize */
495 memmove(h->buffer_syn[ch] + h->hopsize*2, h->buffer_syn[ch], h->hopsize * 18 * sizeof(float));
496
497 /* Apply complex-QMF synthesis modulators */
498 cblas_scopy(h->hopsize, (float*)h->qmfTF_frame, 2, h->qmfTF_frame_tmp, 1); /* creal(h->qmfTF_frame) */
499 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, h->hopsize*2, 1, h->hopsize, 1.0f,
500 FLATTEN2D(h->h_s_real), h->hopsize,
501 h->qmfTF_frame_tmp, 1, 0.0f,
502 h->tmp_real_frame, 1);
503 cblas_scopy(h->hopsize, &((float*)h->qmfTF_frame)[1], 2, h->qmfTF_frame_tmp, 1); /* cimag(h->qmfTF_frame) */
504 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, h->hopsize*2, 1, h->hopsize, 1.0f,
505 FLATTEN2D(h->h_s_imag), h->hopsize,
506 h->qmfTF_frame_tmp, 1, 0.0f,
507 h->tmp_imag_frame, 1);
508
509 /* Append new synthesis frame */
510 utility_svvsub(h->tmp_real_frame, h->tmp_imag_frame, h->hopsize*2, h->buffer_syn[ch]);
511
512 /* Apply prototype filter/window */
513 utility_svvmul(h->buffer_syn[ch], h->h_p, h->hopsize, h->buffer_win);
514 utility_svvmul(h->buffer_syn[ch] + h->hopsize*3, h->h_p + h->hopsize, h->hopsize, h->buffer_win + h->hopsize);
515 utility_svvmul(h->buffer_syn[ch] + h->hopsize*4, h->h_p + h->hopsize*2, h->hopsize, h->buffer_win + h->hopsize*2);
516 utility_svvmul(h->buffer_syn[ch] + h->hopsize*7, h->h_p + h->hopsize*3, h->hopsize, h->buffer_win + h->hopsize*3);
517 utility_svvmul(h->buffer_syn[ch] + h->hopsize*8, h->h_p + h->hopsize*4, h->hopsize, h->buffer_win + h->hopsize*4);
518 utility_svvmul(h->buffer_syn[ch] + h->hopsize*11, h->h_p + h->hopsize*5, h->hopsize, h->buffer_win + h->hopsize*5);
519 utility_svvmul(h->buffer_syn[ch] + h->hopsize*12, h->h_p + h->hopsize*6, h->hopsize, h->buffer_win + h->hopsize*6);
520 utility_svvmul(h->buffer_syn[ch] + h->hopsize*15, h->h_p + h->hopsize*7, h->hopsize, h->buffer_win + h->hopsize*7);
521 utility_svvmul(h->buffer_syn[ch] + h->hopsize*16, h->h_p + h->hopsize*8, h->hopsize, h->buffer_win + h->hopsize*8);
522 utility_svvmul(h->buffer_syn[ch] + h->hopsize*19, h->h_p + h->hopsize*9, h->hopsize, h->buffer_win + h->hopsize*9);
523
524 /* Sum all 1:hopsizes to get output frame */
525 utility_svvadd(h->buffer_win, h->buffer_win + h->hopsize, h->hopsize, dataTD[ch] + t*(h->hopsize));
526 cblas_saxpy(h->hopsize, 1.0f, h->buffer_win + h->hopsize*2, 1, dataTD[ch] + t*(h->hopsize), 1);
527 cblas_saxpy(h->hopsize, 1.0f, h->buffer_win + h->hopsize*3, 1, dataTD[ch] + t*(h->hopsize), 1);
528 cblas_saxpy(h->hopsize, 1.0f, h->buffer_win + h->hopsize*4, 1, dataTD[ch] + t*(h->hopsize), 1);
529 cblas_saxpy(h->hopsize, 1.0f, h->buffer_win + h->hopsize*5, 1, dataTD[ch] + t*(h->hopsize), 1);
530 cblas_saxpy(h->hopsize, 1.0f, h->buffer_win + h->hopsize*6, 1, dataTD[ch] + t*(h->hopsize), 1);
531 cblas_saxpy(h->hopsize, 1.0f, h->buffer_win + h->hopsize*7, 1, dataTD[ch] + t*(h->hopsize), 1);
532 cblas_saxpy(h->hopsize, 1.0f, h->buffer_win + h->hopsize*8, 1, dataTD[ch] + t*(h->hopsize), 1);
533 cblas_saxpy(h->hopsize, 1.0f, h->buffer_win + h->hopsize*9, 1, dataTD[ch] + t*(h->hopsize), 1);
534 }
535 }
536}
537
539(
540 void * const hQMF,
541 int new_nCHin,
542 int new_nCHout
543)
544{
545 qmf_data *h = (qmf_data*)(hQMF);
546 int i;
547
548 if(h->nCHin!=new_nCHin){
549 /* resize hybrid analysis buffers */
550 if(h->hybridmode){
551 h->qmfDelayBuffer = (float_complex***)realloc3d_r((void***)h->qmfDelayBuffer, new_nCHin, h->hopsize-QMF_NBANDS_2_SUBDIVIDE,
553 (QMF_HYBRID_FILTER_LENGTH-1)/2 + 1, sizeof(float_complex));
554 h->hybBuffer = (float_complex***)realloc3d_r((void***)h->hybBuffer, new_nCHin, QMF_NBANDS_2_SUBDIVIDE,
556 QMF_HYBRID_FILTER_LENGTH, sizeof(float_complex));
557
558 /* zero any new channels */
559 for(i=h->nCHin; i<new_nCHin; i++){
560 memset(FLATTEN2D(h->qmfDelayBuffer[i]), 0, (h->hopsize-QMF_NBANDS_2_SUBDIVIDE) * ((QMF_HYBRID_FILTER_LENGTH-1)/2 + 1) * sizeof(float_complex));
561 memset(FLATTEN2D(h->hybBuffer[i]), 0, QMF_NBANDS_2_SUBDIVIDE * QMF_HYBRID_FILTER_LENGTH * sizeof(float_complex));
562 }
563 }
564
565 /* resize analysis buffers */
566 for(i=new_nCHin; i<h->nCHin; i++)
567 free(h->buffer_ana[i]);
568 h->buffer_ana = (float**)realloc1d(h->buffer_ana, sizeof(float*)*new_nCHin);
569 for(i=h->nCHin; i<new_nCHin; i++)
570 h->buffer_ana[i] = (float*)calloc1d(h->hopsize * 10,sizeof(float));
571
572 h->nCHin = new_nCHin;
573 }
574
575 if(h->nCHout!=new_nCHout){
576 /* resize synthesis buffers */
577 for(i=new_nCHout; i<h->nCHout; i++)
578 free(h->buffer_syn[i]);
579 h->buffer_syn = (float**)realloc1d(h->buffer_syn, sizeof(float*)*new_nCHout);
580 for(i=h->nCHout; i<new_nCHout; i++)
581 h->buffer_syn[i] = (float*)calloc1d(h->hopsize * 20, sizeof(float));
582
583 h->nCHout = new_nCHout;
584 }
585}
586
588(
589 void * const hQMF
590)
591{
592 qmf_data *h = (qmf_data*)(hQMF);
593 int i;
594
595 /* flush analysis buffers */
596 for(i=0; i<h->nCHin; i++){
597 memset(h->buffer_ana[i], 0, h->hopsize * 10 * sizeof(float));
598 if(h->hybridmode){
599 memset(FLATTEN3D(h->qmfDelayBuffer), 0, h->nCHin*(h->hopsize-QMF_NBANDS_2_SUBDIVIDE)* ((QMF_HYBRID_FILTER_LENGTH-1)/2 + 1)*sizeof(float_complex));
600 memset(FLATTEN3D(h->hybBuffer), 0, h->nCHin*QMF_NBANDS_2_SUBDIVIDE*QMF_HYBRID_FILTER_LENGTH*sizeof(float_complex));
601 }
602 }
603
604 /* flush synthesis buffers */
605 for(i=0; i<h->nCHout; i++)
606 memset(h->buffer_syn[i], 0, h->hopsize * 20 * sizeof(float));
607}
608
610(
611 void * const hQMF
612)
613{
614 qmf_data *h = (qmf_data*)(hQMF);
615 return h->procDelay;
616}
617
619(
620 void * const hQMF
621)
622{
623 qmf_data *h = (qmf_data*)(hQMF);
624 return h->nBands;
625}
626
628(
629 void * const hQMF,
630 float fs,
631 int nBands,
632 float* centreFreq
633)
634{
635 qmf_data *h = (qmf_data*)(hQMF);
636 int i, j, hopsize;
637 float* cutoffs;
638 float centreFreqs_qmf[QMF_NBANDS_2_SUBDIVIDE];
639
640 saf_assert(nBands==h->nBands, "Just to check that \"centreFreq\" is of correct length");
641
642 /* QMF cutoff frequencies */
643 hopsize = h->hopsize;
644 cutoffs = malloc1d((hopsize+1)*sizeof(float));
645 for(i=0; i<hopsize+1; i++)
646 cutoffs[i] = i* fs/(2.0f*(float)hopsize);
647
648 if(h->hybridmode){
649 /* Convert the first 3 qmf centre frequencies to the 10 hybrid centre frequencies */
650 for(i=0; i<QMF_NBANDS_2_SUBDIVIDE; i++)
651 centreFreqs_qmf[i] = cutoffs[i+1] - (cutoffs[i+1]-cutoffs[i])/2.0f;
652 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, 10, 1, QMF_NBANDS_2_SUBDIVIDE, 1.0f,
654 centreFreqs_qmf, 1, 0.0f,
655 centreFreq, 1);
656
657 /* Remaining centre frequencies are then QMF centre frequencies 4:end */
658 for(i=10, j=QMF_NBANDS_2_SUBDIVIDE; i<nBands; i++, j++)
659 centreFreq[i] = cutoffs[j+1] - (cutoffs[j+1]-cutoffs[j])/2.0f;
660 }
661 else{
662 /* Centre frequencies are defined as directly inbetween the cutoff frequencies */
663 for(i=0; i<hopsize; i++)
664 centreFreq[i] = cutoffs[i+1] - (cutoffs[i+1]-cutoffs[i])/2.0f;
665 }
666
667 free(cutoffs);
668}
669
671(
672 float* hIR /*N_dirs x nCH x ir_len*/,
673 int N_dirs,
674 int nCH,
675 int ir_len,
676 int hopSize,
677 int hybridmode,
678 float_complex* hFB /* nBands x nCH x N_dirs */
679)
680{
681 int i, j, t, nd, nm, nTimeSlots, ir_pad, nBands;
682 int* maxIdx;
683 float maxVal, idxDel, irFB_energy, irFB_gain, phase;
684 float* centerImpulse, *centerImpulseFB_energy, *ir;
685 float_complex cross;
686 float_complex* centerImpulseFB, *irFB;
687
688 nBands = hopSize + (hybridmode ? 7 : 0);
689 ir_pad = 1024;//+512;
690 nTimeSlots = (int)((float)(SAF_MAX(ir_len, hopSize) + ir_pad) / (float)hopSize + 0.9999f); /*ceil*/
691 maxIdx = calloc1d(nCH,sizeof(int));
692 centerImpulse = calloc1d(SAF_MAX(ir_len,hopSize)+ir_pad, sizeof(float));
693
694 /* pick a direction to estimate the center of FIR delays */
695 for(j=0; j<nCH; j++){
696 maxVal = 2.23e-13f;
697 for(i=0; i<ir_len; i++){
698 if(hIR[j*ir_len + i] > maxVal){
699 maxVal = hIR[j*ir_len + i];
700 maxIdx[j] = i;
701 }
702 }
703 }
704 idxDel = 0.0f;
705 for(j=0; j<nCH; j++)
706 idxDel += (float)maxIdx[j];
707 idxDel /= (float)nCH;
708 idxDel = (idxDel + 1.5f);
709
710 /* ideal impulse at mean delay */
711 centerImpulse[(int)idxDel] = 1.0f;
712
713 /* analyse impulse with the filterbank */
714 centerImpulseFB = malloc1d(nBands*nTimeSlots*1*sizeof(float_complex));
715 qmfAnalyse(centerImpulse, SAF_MAX(ir_len,hopSize)+ir_pad, 1, hopSize, hybridmode, centerImpulseFB);
716 centerImpulseFB_energy = calloc1d(nBands, sizeof(float));
717 for(i=0; i<nBands; i++)
718 for(t=0; t<nTimeSlots; t++)
719 centerImpulseFB_energy[i] += powf(cabsf(centerImpulseFB[i*nTimeSlots + t]), 2.0f);
720
721 /* initialise FB coefficients */
722 ir = calloc1d( (SAF_MAX(ir_len,hopSize)+ir_pad) * nCH, sizeof(float));
723 irFB = calloc1d(nBands*nTimeSlots*nCH,sizeof(float_complex));
724 for(nd=0; nd<N_dirs; nd++){
725 for(j=0; j<ir_len; j++)
726 for(i=0; i<nCH; i++)
727 ir[j*nCH+i] = hIR[nd*nCH*ir_len + i*ir_len + j];
728 qmfAnalyse(ir, SAF_MAX(ir_len,hopSize)+ir_pad, nCH, hopSize, hybridmode, irFB);
729 for(nm=0; nm<nCH; nm++){
730 for(i=0; i<nBands; i++){
731 irFB_energy = 0;
732 for(t=0; t<nTimeSlots; t++)
733 irFB_energy += powf(cabsf(irFB[i*nTimeSlots*nCH + t*nCH + nm]), 2.0f); /* out_nBands x nTimeslots x nCH */
734 irFB_gain = sqrtf(irFB_energy/SAF_MAX(centerImpulseFB_energy[i], 2.23e-8f));
735 cross = cmplxf(0.0f,0.0f);
736 for(t=0; t<nTimeSlots; t++)
737 cross = ccaddf(cross, ccmulf(irFB[i*nTimeSlots*nCH + t*nCH + nm], conjf(centerImpulseFB[i*nTimeSlots + t])));
738 phase = atan2f(cimagf(cross), crealf(cross));
739 hFB[i*nCH*N_dirs + nm*N_dirs + nd] = crmulf( cexpf(cmplxf(0.0f, phase)), irFB_gain);
740 }
741 }
742 }
743
744 /* clean-up */
745 free(maxIdx);
746 free(centerImpulse);
747 free(centerImpulseFB_energy);
748 free(centerImpulseFB);
749 free(ir);
750 free(irFB);
751}
const float __afSTFT_protoFilter1024[10240]
Prototype filter used by afSTFTlib.
#define saf_assert(x, message)
Macro to make an assertion, along with a string explaining its purpose.
#define SAF_PI
pi constant (single precision)
void qmf_FIRtoFilterbankCoeffs(float *hIR, int N_dirs, int nCH, int ir_len, int hopSize, int hybridmode, float_complex *hFB)
Converts FIR filters into Filterbank Coefficients by passing them through the QMF filterbank.
void utility_svvmul(const float *a, const float *b, const int len, float *c)
Single-precision, element-wise vector-vector multiplication i.e.
#define SAF_MAX(a, b)
Returns the maximum of the two values.
void qmf_getCentreFreqs(void *const hQMF, float fs, int nBands, float *centreFreq)
Computes the QMF/hybrid-QMF centre frequencies.
QMF_FDDATA_FORMAT
Options for how the frequency domain data is permuted when using qmf.
void utility_svvsub(const float *a, const float *b, const int len, float *c)
Single-precision, vector-vector subtraction, i.e.
int qmf_getProcDelay(void *const hQMF)
Returns the processing delay in samples.
void qmf_synthesis(void *const hQMF, float_complex ***dataFD, int framesize, float **dataTD)
Performs QMF synthesis of the input frequency-domain signals.
void qmf_channelChange(void *const hQMF, int new_nCHin, int new_nCHout)
Changes the number input and/or output channels.
void qmf_analysis(void *const hQMF, float **dataTD, int framesize, float_complex ***dataFD)
Performs QMF analysis of the input time-domain signals.
void qmf_destroy(void **const phQMF)
Destroys an instance of the qmf filterbank.
int qmf_getNBands(void *const hQMF)
Returns the number of frequency bands.
void qmf_clearBuffers(void *const hQMF)
Flushes the analysis and synthesis buffers with zeros.
void utility_svvadd(const float *a, const float *b, const int len, float *c)
Single-precision, vector-vector addition, i.e.
void qmf_create(void **const phQMF, int nCHin, int nCHout, int hopsize, int hybridmode, QMF_FDDATA_FORMAT format)
Creates an instance of the qmf filterbank.
@ QMF_BANDS_CH_TIME
nBands x nChannels x nTimeHops
@ QMF_TIME_CH_BANDS
nTimeHops x nChannels x nBands
void ** malloc2d(size_t dim1, size_t dim2, size_t data_size)
2-D malloc (contiguously allocated, so use free() as usual to deallocate)
Definition md_malloc.c:89
void * malloc1d(size_t dim1_data_size)
1-D malloc (same as malloc, but with error checking)
Definition md_malloc.c:59
void * calloc1d(size_t dim1, size_t data_size)
1-D calloc (same as calloc, but with error checking)
Definition md_malloc.c:69
void * realloc1d(void *ptr, size_t dim1_data_size)
1-D realloc (same as realloc, but with error checking)
Definition md_malloc.c:79
void *** malloc3d(size_t dim1, size_t dim2, size_t dim3, size_t data_size)
3-D malloc (contiguously allocated, so use free() as usual to deallocate)
Definition md_malloc.c:151
void *** realloc3d_r(void ***ptr, size_t new_dim1, size_t new_dim2, size_t new_dim3, size_t prev_dim1, size_t prev_dim2, size_t prev_dim3, size_t data_size)
3-D realloc which does retain previous data order
Definition md_malloc.c:207
void ** calloc2d(size_t dim1, size_t dim2, size_t data_size)
2-D calloc (contiguously allocated, so use free() as usual to deallocate)
Definition md_malloc.c:102
void *** calloc3d(size_t dim1, size_t dim2, size_t dim3, size_t data_size)
3-D calloc (contiguously allocated, so use free() as usual to deallocate)
Definition md_malloc.c:170
#define FLATTEN2D(A)
Use this macro when passing a 2-D dynamic multi-dimensional array to memset, memcpy or any other func...
Definition md_malloc.h:65
#define FLATTEN3D(A)
Use this macro when passing a 3-D dynamic multi-dimensional array to memset, memcpy or any other func...
Definition md_malloc.h:72
Include header for SAF externals.
Main header for the utilities module (SAF_UTILITIES_MODULE)
static const double __qmf_protofilter[1280]
Prototype filter/window.
#define QMF_MAX_HOP_SIZE
Maximum hop size supported.
static void qmfAnalyse(float *inTD, int nSamplesTD, int nCH, int hopSize, int hybridmode, float_complex *outTF)
Passes input time-domain data through the QMF filterbank.
#define QMF_NBANDS_2_SUBDIVIDE
Number of QMF bands to subdivide.
static const double __qmf_fb4bandCoeffs[13]
Coefficients to subdivide the 2nd & 3rd lowest QMF bands into 4 subbands.
static const float __qmf2hybCentreFreq[10][QMF_NBANDS_2_SUBDIVIDE]
Matrix for converting the centre frequencies of the first 3 QMF bands into the centre frequencies for...
static const double __qmf_fb8bandCoeffs[13]
Coefficients to subdivide the lowest QMF band into 8 subbands: ~ 0.125*kaiser(13, 4....
#define QMF_HYBRID_FILTER_LENGTH
Hybrid-filter length.
Data structure for the complex-QMF filterbank.
int hybridmode
1: hybrid filtering enabled; 0: disabled
int nCHout
Number of output channels.
int procDelay
Processing delay in samples.
int nBands
Number of frequency bands.
int hopsize
Hop size in samples.
QMF_FDDATA_FORMAT format
see QMF_FDDATA_FORMAT
int nCHin
Number of input channels.