1 #include "audiobuffercontainer.h"
5 void ChannelPinMapper::Reset()
7 for (int i
=0; i
< CHANNELPINMAPPER_MAXPINS
; ++i
)
8 m_mapping
[i
].set_excl(i
);
11 void ChannelPinMapper::SetNPins(int nPins
)
14 else if (nPins
>CHANNELPINMAPPER_MAXPINS
) nPins
=CHANNELPINMAPPER_MAXPINS
;
16 for (i
= m_nPins
; i
< nPins
; ++i
)
27 void ChannelPinMapper::SetNChannels(int nCh
, bool auto_passthru
)
29 if (auto_passthru
) for (int i
= m_nCh
; i
< nCh
&& i
< m_nPins
; ++i
) {
35 void ChannelPinMapper::Init(const PinMapPin
* pMapping
, int nPins
)
38 else if (nPins
>CHANNELPINMAPPER_MAXPINS
) nPins
=CHANNELPINMAPPER_MAXPINS
;
39 memcpy(m_mapping
, pMapping
, nPins
*sizeof(PinMapPin
));
40 memset(m_mapping
+nPins
, 0, (CHANNELPINMAPPER_MAXPINS
-nPins
)*sizeof(PinMapPin
));
41 m_nPins
= m_nCh
= nPins
;
44 #define BITMASK64(bitIdx) (((WDL_UINT64)1)<<(bitIdx))
46 void ChannelPinMapper::ClearPin(int pinIdx
)
48 if (pinIdx
>=0 && pinIdx
< CHANNELPINMAPPER_MAXPINS
) m_mapping
[pinIdx
].clear();
51 void ChannelPinMapper::SetPin(int pinIdx
, int chIdx
, bool on
)
53 if (pinIdx
>=0 && pinIdx
< CHANNELPINMAPPER_MAXPINS
)
57 m_mapping
[pinIdx
].set_chan(chIdx
);
61 m_mapping
[pinIdx
].clear_chan(chIdx
);
66 bool ChannelPinMapper::TogglePin(int pinIdx
, int chIdx
)
68 bool on
= GetPin(pinIdx
, chIdx
);
70 SetPin(pinIdx
, chIdx
, on
);
74 bool ChannelPinMapper::GetPin(int pinIdx
, int chIdx
) const
76 if (pinIdx
>= 0 && pinIdx
< CHANNELPINMAPPER_MAXPINS
)
78 return m_mapping
[pinIdx
].has_chan(chIdx
);
83 bool ChannelPinMapper::IsStraightPassthrough() const
85 if (m_nCh
!= m_nPins
) return false;
88 for (int i
= 0; i
< m_nPins
; ++i
)
91 if (!tmp
.equal_to(m_mapping
[i
])) return false;
97 #define PINMAPPER_MAGIC 1000
99 const char *ChannelPinMapper::SaveStateNew(int* pLen
)
102 int magic
= PINMAPPER_MAGIC
;
103 WDL_Queue__AddToLE(&m_cfgret
, &magic
);
104 WDL_Queue__AddToLE(&m_cfgret
, &m_nCh
);
105 WDL_Queue__AddToLE(&m_cfgret
, &m_nPins
);
106 const int num64
= wdl_max(1,(wdl_min(m_nCh
,CHANNELPINMAPPER_MAXPINS
) + 63)/64);
107 for (int y
= 0; y
< num64
; y
++)
109 for (int x
= 0; x
< m_nPins
; x
++)
111 const WDL_UINT64 v
= m_mapping
[x
].get_64(y
);
112 WDL_Queue__AddToLE(&m_cfgret
, &v
);
115 *pLen
= m_cfgret
.GetSize();
116 return (const char*)m_cfgret
.Get();
119 bool ChannelPinMapper::LoadState(const char* buf
, int len
)
123 int* pMagic
= WDL_Queue__GetTFromLE(&chunk
, (int*)0);
124 if (!pMagic
|| *pMagic
!= PINMAPPER_MAGIC
) return false;
125 int* pNCh
= WDL_Queue__GetTFromLE(&chunk
, (int*) 0);
126 int* pNPins
= WDL_Queue__GetTFromLE(&chunk
, (int*) 0);
127 if (!pNCh
|| !pNPins
) return false;
128 const int src_pins
= *pNPins
;
131 const int num64
= wdl_max(1,(wdl_min(m_nCh
,CHANNELPINMAPPER_MAXPINS
)+63)/64);
132 const int maplen
= src_pins
* sizeof(WDL_UINT64
);
133 for (int y
= 0; y
< num64
; y
++)
135 if (chunk
.Available() < maplen
) return y
>0;
136 const WDL_UINT64
*pMap
= (const WDL_UINT64
*)WDL_Queue__GetDataFromLE(&chunk
, maplen
, sizeof(WDL_UINT64
));
137 const int sz
= wdl_min(m_nPins
,src_pins
);
138 for (int x
= 0; x
< sz
; x
++)
140 m_mapping
[x
].set_64(pMap
[x
], y
);
148 AudioBufferContainer::AudioBufferContainer()
153 m_interleaved
= true;
157 // converts interleaved buffer to interleaved buffer, using min(len_in,len_out) and zeroing any extra samples
158 // isInput means it reads from track channels and writes to plugin pins
159 // wantZeroExcessOutput=false means that untouched channels will be preserved in buf_out
160 void PinMapperConvertBuffers(const double *buf
, int len_in
, int nch_in
,
161 double *buf_out
, int len_out
, int nch_out
,
162 const ChannelPinMapper
*pinmap
, bool isInput
, bool wantZeroExcessOutput
)
165 if (pinmap
->IsStraightPassthrough() || !pinmap
->GetNPins())
168 char *op
= (char *)buf_out
;
169 const char *ip
= (const char *)buf
;
171 const int ip_adv
= nch_in
* sizeof(double);
173 const int clen
= wdl_min(nch_in
, nch_out
) * sizeof(double);
174 const int zlen
= nch_out
> nch_in
? (nch_out
- nch_in
) * sizeof(double) : 0;
176 const int cplen
= wdl_min(len_in
,len_out
);
178 for (x
=0;x
<cplen
;x
++)
184 if (wantZeroExcessOutput
) memset(op
,0,zlen
);
189 if (x
< len_out
&& wantZeroExcessOutput
) memset(op
, 0, (len_out
-x
)*sizeof(double)*nch_out
);
193 if (wantZeroExcessOutput
) memset(buf_out
,0,len_out
*nch_out
*sizeof(double));
195 const int npins
= wdl_min(pinmap
->GetNPins(),isInput
? nch_out
: nch_in
);
196 const int nchan
= isInput
? nch_in
: nch_out
;
201 for (p
= 0; p
< npins
; p
++)
203 const PinMapPin
&map
= pinmap
->m_mapping
[p
];
204 for (unsigned int x
= 0; map
.enum_chans(&x
,nchan
); x
++)
207 const double *ip
= buf
+ (isInput
? x
: p
);
208 const int out_idx
= (isInput
? p
: x
);
210 bool want_zero
=false;
211 if (!wantZeroExcessOutput
)
213 if (!clearmask
.has_chan(out_idx
))
215 clearmask
.set_chan(out_idx
);
220 double *op
= buf_out
+ out_idx
;