From c943e47b05bc4a8168fa15c4ed5c00514aea3150 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Fri, 2 Oct 2015 02:44:22 +0100 Subject: [PATCH] Correct CD+G packetization. --- CD+G.cs | 76 +++++++++++++++++++------------- ChangeLog | 6 +++ Program.cs | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 175 insertions(+), 32 deletions(-) diff --git a/CD+G.cs b/CD+G.cs index 9f7a27d..874619f 100644 --- a/CD+G.cs +++ b/CD+G.cs @@ -26,7 +26,7 @@ namespace SubChannelDecoder { public static class CD_G { - public struct CD_G_Packet + public struct CD_RW_Packet { public byte command; public byte instruction; @@ -50,9 +50,25 @@ namespace SubChannelDecoder public const byte CD_G_Command = 0x09; - public static CD_G_Packet[] Packetize_CDG(byte[] subchannel) + static readonly int[] offsets = new [] + { 0, 66, 125, 191, 100, 50, 150, 175, + 8, 33, 58, 83, 108, 133, 158, 183, + 16, 41, 25, 91, 116, 141, 166, 75 + }; + + public static CD_RW_Packet[] Packetize_CD_RW(byte[] subchannels) { - CD_G_Packet[] packets = new CD_G_Packet[4]; + Console.WriteLine("{0}", subchannels.Length); + CD_RW_Packet[] packets = new CD_RW_Packet[4]; + + System.IO.MemoryStream ms = new System.IO.MemoryStream(); + + for (int pack = 0; pack < 4; pack++) + for (int column = 0; column < 24; column++) + ms.WriteByte(subchannels[(pack*24)+offsets[column]]); + + ms.Seek(0, System.IO.SeekOrigin.Begin); + byte[] packetized = ms.ToArray(); for (int i = 0; i < 4; i++) { @@ -60,31 +76,31 @@ namespace SubChannelDecoder packets[i].data = new byte[16]; packets[i].parityP = new byte[4]; - packets[i].command = (byte)(subchannel[0 + i * 24] & 0x3F); - packets[i].instruction = (byte)(subchannel[1 + i * 24] & 0x3F); + packets[i].command = (byte)(packetized[0 + i * 24] & 0x3F); + packets[i].instruction = (byte)(packetized[1 + i * 24] & 0x3F); - packets[i].parityQ[0] = (byte)(subchannel[2 + i * 24] & 0x3F); - packets[i].parityQ[1] = (byte)(subchannel[3 + i * 24] & 0x3F); - packets[i].data[0] = (byte)(subchannel[4 + i * 24] & 0x3F); - packets[i].data[1] = (byte)(subchannel[5 + i * 24] & 0x3F); - packets[i].data[2] = (byte)(subchannel[6 + i * 24] & 0x3F); - packets[i].data[3] = (byte)(subchannel[7 + i * 24] & 0x3F); - packets[i].data[4] = (byte)(subchannel[8 + i * 24] & 0x3F); - packets[i].data[5] = (byte)(subchannel[9 + i * 24] & 0x3F); - packets[i].data[6] = (byte)(subchannel[10 + i * 24] & 0x3F); - packets[i].data[7] = (byte)(subchannel[11 + i * 24] & 0x3F); - packets[i].data[8] = (byte)(subchannel[12 + i * 24] & 0x3F); - packets[i].data[9] = (byte)(subchannel[13 + i * 24] & 0x3F); - packets[i].data[10] = (byte)(subchannel[14 + i * 24] & 0x3F); - packets[i].data[11] = (byte)(subchannel[15 + i * 24] & 0x3F); - packets[i].data[12] = (byte)(subchannel[16 + i * 24] & 0x3F); - packets[i].data[13] = (byte)(subchannel[17 + i * 24] & 0x3F); - packets[i].data[14] = (byte)(subchannel[18 + i * 24] & 0x3F); - packets[i].data[15] = (byte)(subchannel[19 + i * 24] & 0x3F); - packets[i].parityP[0] = (byte)(subchannel[20 + i * 24] & 0x3F); - packets[i].parityP[1] = (byte)(subchannel[21 + i * 24] & 0x3F); - packets[i].parityP[2] = (byte)(subchannel[22 + i * 24] & 0x3F); - packets[i].parityP[3] = (byte)(subchannel[23 + i * 24] & 0x3F); + packets[i].parityQ[0] = (byte)(packetized[2 + i * 24] & 0x3F); + packets[i].parityQ[1] = (byte)(packetized[3 + i * 24] & 0x3F); + packets[i].data[0] = (byte)(packetized[4 + i * 24] & 0x3F); + packets[i].data[1] = (byte)(packetized[5 + i * 24] & 0x3F); + packets[i].data[2] = (byte)(packetized[6 + i * 24] & 0x3F); + packets[i].data[3] = (byte)(packetized[7 + i * 24] & 0x3F); + packets[i].data[4] = (byte)(packetized[8 + i * 24] & 0x3F); + packets[i].data[5] = (byte)(packetized[9 + i * 24] & 0x3F); + packets[i].data[6] = (byte)(packetized[10 + i * 24] & 0x3F); + packets[i].data[7] = (byte)(packetized[11 + i * 24] & 0x3F); + packets[i].data[8] = (byte)(packetized[12 + i * 24] & 0x3F); + packets[i].data[9] = (byte)(packetized[13 + i * 24] & 0x3F); + packets[i].data[10] = (byte)(packetized[14 + i * 24] & 0x3F); + packets[i].data[11] = (byte)(packetized[15 + i * 24] & 0x3F); + packets[i].data[12] = (byte)(packetized[16 + i * 24] & 0x3F); + packets[i].data[13] = (byte)(packetized[17 + i * 24] & 0x3F); + packets[i].data[14] = (byte)(packetized[18 + i * 24] & 0x3F); + packets[i].data[15] = (byte)(packetized[19 + i * 24] & 0x3F); + packets[i].parityP[0] = (byte)(packetized[20 + i * 24] & 0x3F); + packets[i].parityP[1] = (byte)(packetized[21 + i * 24] & 0x3F); + packets[i].parityP[2] = (byte)(packetized[22 + i * 24] & 0x3F); + packets[i].parityP[3] = (byte)(packetized[23 + i * 24] & 0x3F); } return packets; @@ -92,10 +108,10 @@ namespace SubChannelDecoder public static void PrintCDGPackets(byte[] subchannel) { - PrintCDGPackets(Packetize_CDG(subchannel)); + PrintCDGPackets(Packetize_CD_RW(subchannel)); } - public static void PrintCDGPackets(CD_G_Packet[] packets) + public static void PrintCDGPackets(CD_RW_Packet[] packets) { for (int i = 0; i < packets.Length; i++) { @@ -104,7 +120,7 @@ namespace SubChannelDecoder } } - public static void PrintCDGPacket(CD_G_Packet packet) + public static void PrintCDGPacket(CD_RW_Packet packet) { if (packet.command != CD_G_Command) return; diff --git a/ChangeLog b/ChangeLog index a747379..da12342 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2015-10-02 Natalia Portillo + + * CD+G.cs: + * Program.cs: + Correct CD+G packetization. + 2015-10-02 Natalia Portillo * Program.cs: diff --git a/Program.cs b/Program.cs index c14bad9..f376558 100644 --- a/Program.cs +++ b/Program.cs @@ -32,6 +32,7 @@ namespace SubChannelDecoder const int QData = 0x40; const int QCopyPermitted = 0x20; const int QPreEmphasis = 0x10; + const int QMode0 = 0x00; const int QMode1 = 0x01; const int QMode2 = 0x02; const int QMode3 = 0x03; @@ -145,6 +146,10 @@ namespace SubChannelDecoder PrintQSubchannel(sub.q); + bool StandardRW = false; + bool correctlyPacketized = false; + MemoryStream ms = new MemoryStream(); + if(interleaved == true || interleaved == null) { if((sectorBytes[0] & 0x3F) == 0x09 || @@ -153,7 +158,32 @@ namespace SubChannelDecoder (sectorBytes[72] & 0x3F) == 0x09) { Console.WriteLine("CD+G detected."); - CD_G.PrintCDGPackets(sectorBytes); + StandardRW = true; + } + + if(StandardRW) + { + if((fs.Length / 96) >= (sector+2)) + { + try + { + ms.Write(sectorBytes, 0, 96); + + fs.Seek((sector+1)*96, SeekOrigin.Begin); + fs.Read(sectorBytes, 0, 96); + ms.Write(sectorBytes, 0, 96); + + fs.Seek((sector+2)*96, SeekOrigin.Begin); + fs.Read(sectorBytes, 0, 96); + ms.Write(sectorBytes, 0, 96); + + correctlyPacketized = true; + } + catch + { + correctlyPacketized = false; + } + } } } else @@ -166,9 +196,37 @@ namespace SubChannelDecoder (interBytes[72] & 0x3F) == 0x09) { Console.WriteLine("CD+G detected."); - CD_G.PrintCDGPackets(interBytes); + StandardRW = true; + } + + if(StandardRW) + { + if((fs.Length / 96) >= (sector+2)) + { + try + { + ms.Write(interBytes, 0, 96); + + fs.Seek((sector+1)*96, SeekOrigin.Begin); + fs.Read(sectorBytes, 0, 96); + ms.Write(InterleaveSubchannel(UnpackSubchannel(sectorBytes)), 0, 96); + + fs.Seek((sector+2)*96, SeekOrigin.Begin); + fs.Read(sectorBytes, 0, 96); + ms.Write(InterleaveSubchannel(UnpackSubchannel(sectorBytes)), 0, 96); + + correctlyPacketized = true; + } + catch + { + correctlyPacketized = false; + } + } } } + + if(correctlyPacketized) + CD_G.PrintCDGPackets(ms.ToArray()); } } else @@ -246,6 +304,10 @@ namespace SubChannelDecoder PrintQSubchannel(sub.q); + bool StandardRW = false; + bool correctlyPacketized = false; + MemoryStream ms = new MemoryStream(); + if(interleaved == true || interleaved == null) { if((sectorBytes[0] & 0x3F) == 0x09 || @@ -254,6 +316,32 @@ namespace SubChannelDecoder (sectorBytes[72] & 0x3F) == 0x09) { Console.WriteLine("CD+G detected."); + StandardRW = true; + } + + if(StandardRW) + { + if((fs.Length / 96) >= (sector+2)) + { + try + { + ms.Write(sectorBytes, 0, 96); + + fs.Seek((sector+1)*96, SeekOrigin.Begin); + fs.Read(sectorBytes, 0, 96); + ms.Write(sectorBytes, 0, 96); + + fs.Seek((sector+2)*96, SeekOrigin.Begin); + fs.Read(sectorBytes, 0, 96); + ms.Write(sectorBytes, 0, 96); + + correctlyPacketized = true; + } + catch + { + correctlyPacketized = false; + } + } } } else @@ -266,8 +354,37 @@ namespace SubChannelDecoder (interBytes[72] & 0x3F) == 0x09) { Console.WriteLine("CD+G detected."); + StandardRW = true; + } + + if(StandardRW) + { + if((fs.Length / 96) >= (sector+2)) + { + try + { + ms.Write(interBytes, 0, 96); + + fs.Seek((sector+1)*96, SeekOrigin.Begin); + fs.Read(sectorBytes, 0, 96); + ms.Write(InterleaveSubchannel(UnpackSubchannel(sectorBytes)), 0, 96); + + fs.Seek((sector+2)*96, SeekOrigin.Begin); + fs.Read(sectorBytes, 0, 96); + ms.Write(InterleaveSubchannel(UnpackSubchannel(sectorBytes)), 0, 96); + + correctlyPacketized = true; + } + catch + { + correctlyPacketized = false; + } + } } } + + if(correctlyPacketized) + CD_G.PrintCDGPackets(ms.ToArray()); } } catch @@ -299,6 +416,10 @@ namespace SubChannelDecoder if ((q[0] & QCopyPermitted) == QCopyPermitted) Console.WriteLine("Track may be copied"); + else if ((q[0] & 0x0F) == QMode0) + { + Console.WriteLine("Q Mode 0: Empty"); + } if ((q[0] & 0x0F) == QMode1) { int hour = 0;