public CDRom() { m_BRAM = new SaveMemoryBank(); m_Ram = new RamBank[32]; m_CDInserted = false; m_ADPCM = new ADPCM(); for (int i = 0; i < 32; i++) { m_Ram[i] = new RamBank(); } m_Playing = null; m_AudioPaused = false; m_PlayChunk = new byte[0x20000]; m_FadeCurrent = 1.0f; m_FadeDown = false; m_FadeUp = false; m_FadeStep = 0.0f; m_DataReady = false; m_DataTransferDone = false; m_CDRomState = CDState.RESET; }
private void PlayAudioTrack(int msfStart, int msfEnd) { if (!m_CDInserted) { return; } for (int i = 0; i < m_CDTracks.Length; i++) { if (m_CDTracks[i].m_Frame < msfStart) { continue; } msfStart -= m_CDTracks[i].m_Frame; msfEnd -= m_CDTracks[i].m_Frame; m_Playing = m_CDTracks[i]; m_Playing.m_WaveOffset = m_Playing.m_WaveStart + msfStart * 2352; m_Playing.m_WaveEnd = m_Playing.m_WaveStart + msfEnd * 2352; return; } m_Playing = null; }
public void LoadCue(string file) { StreamReader text = new StreamReader(file); Queue q = new Queue(); CDTrack track = null; Console.WriteLine("Opening CD: {0}", file); int frame = 0; int i; while (!text.EndOfStream) { string[] line = text.ReadLine().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); switch (line[0]) { case "FILE": if (track != null) { q.Enqueue(track); } track = new CDTrack(); file = ""; for (i = 1; i < line.Length; i++) { file += line[i]; if (file[0] != '"') { i++; break; } if (file[file.Length - 1] == '"') { file = file.Substring(1, file.Length - 2); i++; break; } } track.m_DataSource = new FileStream(file, FileMode.Open, FileAccess.Read); switch (line[i]) { case "WAVE": track.m_TrackType = TrackType.WAVE; break; case "BINARY": track.m_TrackType = TrackType.BINARY; break; default: Console.WriteLine("Unknown track type {0}", line[i]); track.m_TrackType = TrackType.UNKNOWN; return; } track.m_Frame = frame; break; case "TRACK": i = Convert.ToInt32(line[1]); if (i - 1 == q.Count) { switch (line[2]) { case "AUDIO": if (track.m_TrackType != TrackType.WAVE) { Console.WriteLine("AUDIO line with an unknown track data source"); return; } i = WaveSize(track.m_DataSource); track.m_WaveStart = (int)track.m_DataSource.Length - i; frame += i / 2352; if (i < 0) { Console.WriteLine("Audio track was not in the proper format (16b PCM Stereo)"); return; } break; case "MODE1/2048": if (track.m_TrackType != TrackType.BINARY) { Console.WriteLine("MODE1/2048 line with an unknown track data source"); return; } // This is a mode1 / 2048 line (no subq channel info) frame += (int)track.m_DataSource.Length / 2048; break; default: Console.WriteLine("Unknown Data Source {0}", line[2]); break; } } else { Console.WriteLine("Cue file TRACK number is out of order"); return; } break; case "PREGAP": { string[] msf_s = line[1].Split(new char[] { ':' }); int msf = (Convert.ToInt32(msf_s[0]) * 60 + Convert.ToInt32(msf_s[1])) * 75 + Convert.ToInt32(msf_s[2]); frame += msf; track.m_Frame += msf; } break; case "POSTGAP": { string[] msf_s = line[1].Split(new char[] { ':' }); int msf = (Convert.ToInt32(msf_s[0]) * 60 + Convert.ToInt32(msf_s[1])) * 75 + Convert.ToInt32(msf_s[2]); frame += msf; } break; case "INDEX": // THIS IS IGNORED (I don't think the system actually uses it) break; } } // Shove the last track to the TOC m_CDTracks = new CDTrack[q.Count + 2]; m_CDTracks[q.Count] = track; // Append leadout track track = new CDTrack(); m_CDTracks[m_CDTracks.Length - 1] = track; track.m_Frame = frame; track.m_Track = 0; track.m_TrackType = TrackType.LEADOUT; for (i = 0; q.Count > 0; i++) { m_CDTracks[i] = (CDTrack)q.Dequeue(); } for (i = 0; i < m_CDTracks.Length; i++) { track = m_CDTracks[i]; int f = track.m_Frame + 150; track.m_MSF_M = f / 75 / 60; track.m_MSF_S = f / 75 % 60; track.m_MSF_F = f % 75; track.m_Track = i + 1; } m_CDInserted = true; }
public unsafe void MixCD(short *buffer, int length) { if (m_AudioPaused || m_Playing == null) { return; } int count = (int)m_Playing.m_DataSource.Length - m_Playing.m_WaveOffset; if (length < count) { count = length; } m_Playing.m_DataSource.Position = m_Playing.m_WaveOffset; m_Playing.m_DataSource.Read(m_PlayChunk, 0, count); int i = 0; length /= 2; while (length > 0) { // Mix the channels if (m_FadeUp || m_FadeDown) { *(buffer++) += m_OutLeft = (short)((m_PlayChunk[i + 1] << 8 | m_PlayChunk[i]) * m_FadeCurrent); i += 2; *(buffer++) += m_OutRight = (short)((m_PlayChunk[i + 1] << 8 | m_PlayChunk[i]) * m_FadeCurrent); i += 2; if (m_FadeDown) { if (m_FadeCurrent > 0.0f) { m_FadeCurrent -= m_FadeStep; } else { m_FadeDown = false; } } else { if (m_FadeCurrent < 1.0f) { m_FadeCurrent += m_FadeStep; } else { m_FadeUp = false; } } } else if (m_FadeCurrent > 0.0f) { *(buffer++) += m_OutLeft = (short)(m_PlayChunk[i + 1] << 8 | m_PlayChunk[i]); i += 2; *(buffer++) += m_OutRight = (short)(m_PlayChunk[i + 1] << 8 | m_PlayChunk[i]); i += 2; } length -= 4; } m_Playing.m_WaveOffset += count; if (m_Playing.m_WaveOffset > m_Playing.m_WaveEnd) { m_Playing = null; } }