langpackedit: sorting fixes, 0.015 -- from 8f06f769
[wdl.git] / WDL / audiobuffercontainer.cpp
blobd68d83721c3647a94578281fa04b09a165256db5
1 #include "audiobuffercontainer.h"
2 #include "queue.h"
3 #include <assert.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)
13 if (nPins<0) nPins=0;
14 else if (nPins>CHANNELPINMAPPER_MAXPINS) nPins=CHANNELPINMAPPER_MAXPINS;
15 int i;
16 for (i = m_nPins; i < nPins; ++i)
18 ClearPin(i);
19 if (i < m_nCh)
21 SetPin(i, i, true);
24 m_nPins = nPins;
27 void ChannelPinMapper::SetNChannels(int nCh, bool auto_passthru)
29 if (auto_passthru) for (int i = m_nCh; i < nCh && i < m_nPins; ++i) {
30 SetPin(i, i, true);
32 m_nCh = nCh;
35 void ChannelPinMapper::Init(const PinMapPin * pMapping, int nPins)
37 if (nPins<0) nPins=0;
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)
55 if (on)
57 m_mapping[pinIdx].set_chan(chIdx);
59 else
61 m_mapping[pinIdx].clear_chan(chIdx);
66 bool ChannelPinMapper::TogglePin(int pinIdx, int chIdx)
68 bool on = GetPin(pinIdx, chIdx);
69 on = !on;
70 SetPin(pinIdx, chIdx, on);
71 return 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);
80 return false;
83 bool ChannelPinMapper::IsStraightPassthrough() const
85 if (m_nCh != m_nPins) return false;
86 PinMapPin tmp;
87 tmp.clear();
88 for (int i = 0; i < m_nPins; ++i)
90 tmp.set_chan(i);
91 if (!tmp.equal_to(m_mapping[i])) return false;
92 tmp.clear_chan(i);
94 return true;
97 #define PINMAPPER_MAGIC 1000
99 const char *ChannelPinMapper::SaveStateNew(int* pLen)
101 m_cfgret.Clear();
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)
121 WDL_Queue chunk;
122 chunk.Add(buf, 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;
129 SetNPins(src_pins);
130 SetNChannels(*pNCh);
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);
144 return true;
148 AudioBufferContainer::AudioBufferContainer()
150 m_nCh = 0;
151 m_nFrames = 0;
152 m_fmt = FMT_32FP;
153 m_interleaved = true;
154 m_hasData = false;
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())
167 int x;
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++)
180 memcpy(op,ip,clen);
181 op += clen;
182 if (zlen)
184 if (wantZeroExcessOutput) memset(op,0,zlen);
185 op += zlen;
187 ip += ip_adv;
189 if (x < len_out && wantZeroExcessOutput) memset(op, 0, (len_out-x)*sizeof(double)*nch_out);
191 else
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;
198 int p;
199 PinMapPin clearmask;
200 clearmask.clear();
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 ++)
206 int i=len_in;
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);
216 want_zero=true;
220 double *op = buf_out + out_idx;
222 if (want_zero)
224 while (i-- > 0)
226 *op = *ip;
227 op += nch_out;
228 ip += nch_in;
231 else
233 while (i-- > 0)
235 *op += *ip;
236 op += nch_out;
237 ip += nch_in;