+ *PCMdata++ = state0->samp2;
+ *PCMdata++ = state1->samp2;
+ *PCMdata++ = state0->samp1;
+ *PCMdata++ = state1->samp1;
+
+ in_len -= 14;
+ out_len += 8;
+ m_next_block = m_block_size;
+ continue;
+ }
+
+ while (in_len != 0 && m_next_block > 0) {
+ wxUint8 nib[2];
+
+ GET_DATA_8(nib[0]);
+ nib[1] = (nib[0] >> 4) & 0x0f;
+ nib[0] &= 0x0f;
+
+ Nibble(nib[0], state0, &PCMdata);
+ Nibble(nib[1], state1, &PCMdata);
+
+ in_len -= 4;
+ out_len += 4;
+ m_next_block -= 4;
+ }
+ }
+
+ return out_len;
+
+#undef GET_DATA_16
+#undef GET_DATA_8
+}
+
+void wxSoundStreamMSAdpcm::Nibble(wxInt8 nyb,
+ AdpcmState *state,
+ wxInt16 **out_buffer)
+{
+ wxUint32 new_delta;
+ wxInt32 new_sample;
+
+ // First: compute the next delta value
+ new_delta = (state->iDelta * gl_ADPCMcoeff_delta[nyb]) >> 8;
+ // If null, minor it by 16
+ if (!new_delta)
+ new_delta = 16;
+
+ // Barycentre
+ new_sample = (state->samp1 * state->coeff[0] +
+ state->samp2 * state->coeff[1]) / 256;
+
+ // Regenerate the sign
+ if (nyb & 0x08)
+ nyb -= 0x10;
+
+ new_sample += state->iDelta * nyb;
+
+ // Samples must be in [-32767, 32768]
+ if (new_sample < -32768)
+ new_sample = -32768;
+ else if (new_sample > 32767)
+ new_sample = 32767;
+
+ state->iDelta = new_delta;
+ state->samp2 = state->samp1;
+ state->samp1 = new_sample;
+
+ *(*out_buffer)++ = new_sample;
+}
+
+wxSoundStream& wxSoundStreamMSAdpcm::Write(const void *buffer, wxUint32 len)
+{
+ wxUint8 *out_buf;
+ wxUint32 new_len;
+
+ // TODO: prealloc the output buffer
+ out_buf = new wxUint8[len*2];
+
+ if (!m_stereo)
+ new_len = DecodeMonoADPCM(buffer, out_buf, len);
+ else
+ new_len = DecodeStereoADPCM(buffer, out_buf, len);
+
+ m_router->Write(out_buf, new_len);
+
+ m_lastcount = len;
+ m_snderror = wxSOUND_NOERROR;
+
+ delete[] out_buf;
+