public void QueuePCM(byte[] buffer, int bufferSize) { AudioFlags flags = AudioFlags.None; if (_audioInfo.is16Bits) { flags |= AudioFlags.Is16Bits; } if (_audioInfo.isStereo) { flags |= AudioFlags.Stereo; } _audioStream.QueueBuffer(buffer, bufferSize, true, flags); }
public void QueueAudioFromSector(Stream sector) { sector.Seek(24, SeekOrigin.Begin); // This XA audio is different (yet similar) from normal XA audio! Watch out! // TODO: It's probably similar enough to normal XA that we can merge it somehow... // TODO: RTZ PSX needs the same audio code in a regular AudioStream class. Probably // will do something similar to QuickTime and creating a base class 'ISOMode2Parser' // or something similar. sector.Read(_buf, 0, AUDIO_DATA_CHUNK_SIZE); int channels = _audStream.IsStereo ? 2 : 1; var dst = _dst; var buf = _buf; Array.Clear(_dst, 0, _dst.Length); var leftChannel = 0; var rightChannel = 1; for (var src = 0; src < AUDIO_DATA_CHUNK_SIZE; src += 128) { for (int i = 0; i < 4; i++) { int shift = 12 - (buf[src + 4 + i * 2] & 0xf); int filter = buf[src + 4 + i * 2] >> 4; int f0 = _xaTable[filter, 0]; int f1 = _xaTable[filter, 1]; int s_1 = _adpcmStatus[0].sample[0]; int s_2 = _adpcmStatus[0].sample[1]; for (int j = 0; j < 28; j++) { byte d = buf[src + 16 + i + j * 4]; int t = (sbyte)(d << 4) >> 4; int s = (t << shift) + ((s_1 * f0 + s_2 * f1 + 32) >> 6); s_2 = s_1; s_1 = (short)ScummHelper.Clip(s, short.MinValue, short.MaxValue); dst.WriteInt16(leftChannel * 2, (short)s_1); leftChannel += channels; } if (channels == 2) { _adpcmStatus[0].sample[0] = (short)s_1; _adpcmStatus[0].sample[1] = (short)s_2; s_1 = _adpcmStatus[1].sample[0]; s_2 = _adpcmStatus[1].sample[1]; } shift = 12 - (buf[src + 5 + i * 2] & 0xf); filter = buf[src + 5 + i * 2] >> 4; f0 = _xaTable[filter, 0]; f1 = _xaTable[filter, 1]; for (int j = 0; j < 28; j++) { var d = buf[src + 16 + i + j * 4]; int t = (sbyte)d >> 4; int s = (t << shift) + ((s_1 * f0 + s_2 * f1 + 32) >> 6); s_2 = s_1; s_1 = (short)ScummHelper.Clip(s, short.MinValue, short.MaxValue); if (channels == 2) { dst.WriteInt16(rightChannel * 2, (short)s_1); rightChannel += 2; } else { dst.WriteInt16(leftChannel * 2, (short)s_1); leftChannel++; } } if (channels == 2) { _adpcmStatus[1].sample[0] = (short)s_1; _adpcmStatus[1].sample[1] = (short)s_2; } else { _adpcmStatus[0].sample[0] = (short)s_1; _adpcmStatus[0].sample[1] = (short)s_2; } } } var flags = AudioFlags.Is16Bits; if (_audStream.IsStereo) { flags |= AudioFlags.Stereo; } if (BitConverter.IsLittleEndian) { flags |= AudioFlags.LittleEndian; } _audStream.QueueBuffer(dst, AUDIO_DATA_SAMPLE_COUNT * 2, true, flags); }