/// <summary> /// Returns the fully mixed audio of the Flipnote, Including its Sound Effects. /// Returns Null if no audio exists. /// </summary> /// <param name="flip"></param> /// <param name="sampleRate"></param> /// <returns>Signed 16-bit PCM audio</returns> public byte[] GetWavBGM(PPMFile flip, int sampleRate = 32768) { // start decoding AdpcmDecoder encoder = new AdpcmDecoder(flip); var decoded = encoder.getAudioMasterPcm(sampleRate); if (decoded.Length > 0) { byte[] output = new byte[decoded.Length]; // thank you https://github.com/meemo for (int i = 0; i < decoded.Length; i += 2) { try { output[i] = (byte)(decoded[i + 1] & 0xff); output[i + 1] = (byte)(decoded[i] >> 8); } catch (Exception) { } } var a = new WavePcmFormat(output, 1, (uint)(sampleRate / 2), 16); return(a.ToBytesArray()); } return(null); }
private void UpdateBuffer(AMemory Memory) { //TODO: Implement conversion for formats other //than interleaved stereo (2 channels). //As of now, it assumes that HostChannelsCount == 2. WaveBuffer Wb = WaveBuffers[BufferIndex]; if (SampleFormat == SampleFormat.PcmInt16) { int SamplesCount = (int)(Wb.Size / (sizeof(short) * ChannelsCount)); Samples = new int[SamplesCount * AudioConsts.HostChannelsCount]; if (ChannelsCount == 1) { for (int Index = 0; Index < SamplesCount; Index++) { short Sample = Memory.ReadInt16(Wb.Position + Index * 2); Samples[Index * 2 + 0] = Sample; Samples[Index * 2 + 1] = Sample; } } else { for (int Index = 0; Index < SamplesCount * 2; Index++) { Samples[Index] = Memory.ReadInt16(Wb.Position + Index * 2); } } } else if (SampleFormat == SampleFormat.Adpcm) { byte[] Buffer = Memory.ReadBytes(Wb.Position, Wb.Size); Samples = AdpcmDecoder.Decode(Buffer, AdpcmCtx); } else { throw new InvalidOperationException(); } if (SampleRate != AudioConsts.HostSampleRate) { //TODO: We should keep the frames being discarded (see the 4 below) //on a buffer and include it on the next samples buffer, to allow //the resampler to do seamless interpolation between wave buffers. int SamplesCount = Samples.Length / AudioConsts.HostChannelsCount; SamplesCount = Math.Max(SamplesCount - 4, 0); Samples = Resampler.Resample2Ch( Samples, SampleRate, AudioConsts.HostSampleRate, SamplesCount, ref ResamplerFracPart); } }
private void UpdateBuffer(MemoryManager memory) { // TODO: Implement conversion for formats other // than interleaved stereo (2 channels). // As of now, it assumes that HostChannelsCount == 2. WaveBuffer wb = WaveBuffers[_bufferIndex]; if (wb.Position == 0) { _samples = new int[0]; return; } if (SampleFormat == SampleFormat.PcmInt16) { int samplesCount = (int)(wb.Size / (sizeof(short) * ChannelsCount)); _samples = new int[samplesCount * AudioConsts.HostChannelsCount]; if (ChannelsCount == 1) { for (int index = 0; index < samplesCount; index++) { short sample = memory.ReadInt16(wb.Position + index * 2); _samples[index * 2 + 0] = sample; _samples[index * 2 + 1] = sample; } } else { for (int index = 0; index < samplesCount * 2; index++) { _samples[index] = memory.ReadInt16(wb.Position + index * 2); } } } else if (SampleFormat == SampleFormat.Adpcm) { byte[] buffer = memory.ReadBytes(wb.Position, wb.Size); _samples = AdpcmDecoder.Decode(buffer, AdpcmCtx); } else { throw new InvalidOperationException(); } if (SampleRate != AudioConsts.HostSampleRate) { // TODO: We should keep the frames being discarded (see the 4 below) // on a buffer and include it on the next samples buffer, to allow // the resampler to do seamless interpolation between wave buffers. int samplesCount = _samples.Length / AudioConsts.HostChannelsCount; samplesCount = Math.Max(samplesCount - 4, 0); _samples = Resampler.Resample2Ch( _samples, SampleRate, AudioConsts.HostSampleRate, samplesCount, ref _resamplerFracPart); } }