public Task <PCM16Audio> ReadFileAsync(string filename) { byte[] data = File.ReadAllBytes(filename); try { IPcmAudioSource <short> msf = MSF.Parse(data); var lwav = new PCM16Audio( msf.Channels, msf.SampleRate, msf.SampleData.ToArray(), msf.LoopStartSample, msf.LoopStartSample + msf.LoopSampleCount, !msf.IsLooping); if (msf is MSF_MP3 mp3) { lwav.OriginalMP3 = mp3.Body; } return(Task.FromResult(lwav)); } catch (NotSupportedException) { throw new AudioImporterException("Cannot read MSF file (unsupported codec?)"); } }
/// <summary> /// Creates a new MSF (with a 16-bit PCM codec) using an IPCM16AudioSource object as the source. /// </summary> /// <param name="source">The IPCM16AudioSource object</param> /// <param name="big_endian">Whether to use big-endian (default is true)</param> /// <returns></returns> public unsafe static MSF FromAudioSource(IPcmAudioSource <short> source, bool big_endian = true) { short[] samples = source.SampleData.ToArray(); MSFHeader header = MSFHeader.Create(); header.codec = big_endian ? 0 : 1; header.channel_count = source.Channels; header.data_size = samples.Length * sizeof(short); header.sample_rate = source.SampleRate; if (source.IsLooping) { header.flags.Flags |= MSFFlag.LoopMarker0; } MSF_PCM16 msf; if (big_endian) { BigEndianInt16[] samples_be = new BigEndianInt16[samples.Length]; for (int i = 0; i < samples.Length; i++) { samples_be[i] = samples[i]; } byte[] data = new byte[samples.Length * sizeof(short)]; fixed(BigEndianInt16 *ptr = samples_be) { Marshal.Copy((IntPtr)ptr, data, 0, data.Length); } msf = new MSF_PCM16BE(header, data); } else { LittleEndianInt16[] samples_le = new LittleEndianInt16[samples.Length]; for (int i = 0; i < samples.Length; i++) { samples_le[i] = samples[i]; } byte[] data = new byte[samples.Length * sizeof(short)]; fixed(LittleEndianInt16 *ptr = samples_le) { Marshal.Copy((IntPtr)ptr, data, 0, data.Length); } msf = new MSF_PCM16LE(header, data); } if (source.IsLooping) { msf.LoopStartSample = source.LoopStartSample; if (msf.LoopStartSample != source.LoopStartSample) { throw new Exception(); } msf.LoopSampleCount = source.LoopSampleCount; if (msf.LoopSampleCount != source.LoopSampleCount) { throw new Exception(); } } return(msf); }