2 * FryingPan - Amiga CD/DVD Recording Software (User Interface and supporting Libraries only)
3 * Copyright (C) 2001-2011 Tomasz Wiszkowski Tomasz.Wiszkowski at gmail.com
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public License
7 * as published by the Free Software Foundation; either version 2.1
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include <LibC/LibC.h>
22 #include <Generic/Debug.h>
24 CDText::CDText(const IOptItem
* i
) :
25 crc(SumCRC::CRC_16_CCITT
)
27 currentBlock
= Blk_Unknown
;
34 memset(&size
, 0, sizeof(size
));
36 if (i
->getItemType() != Item_Disc
)
39 if (i
->getChildCount() == 0)
42 cdText
|= i
->getChild(0)->hasCDText();
44 addBlockData(Blk_Title
, (uint8
*)i
->getChild(0)->getCDTTitle(), strlen(i
->getChild(0)->getCDTTitle())+1);
45 for (int tno
=0; tno
<i
->getChild(0)->getChildCount(); tno
++)
47 cdText
|= i
->getChild(0)->getChild(tno
)->hasCDText();
49 addBlockData(Blk_Title
,
50 (uint8
*)i
->getChild(0)->getChild(tno
)->getCDTTitle(),
51 strlen(i
->getChild(0)->getChild(tno
)->getCDTTitle())+1);
54 addBlockData(Blk_Performer
, (uint8
*)i
->getChild(0)->getCDTArtist(), strlen(i
->getChild(0)->getCDTArtist())+1);
55 for (int tno
=0; tno
<i
->getChild(0)->getChildCount(); tno
++)
57 addBlockData(Blk_Performer
,
58 (uint8
*)i
->getChild(0)->getChild(tno
)->getCDTArtist(),
59 strlen(i
->getChild(0)->getChild(tno
)->getCDTArtist())+1);
62 addBlockData(Blk_SongWriter
, (uint8
*)i
->getChild(0)->getCDTLyrics(), strlen(i
->getChild(0)->getCDTLyrics())+1);
63 for (int tno
=0; tno
<i
->getChild(0)->getChildCount(); tno
++)
65 addBlockData(Blk_SongWriter
,
66 (uint8
*)i
->getChild(0)->getChild(tno
)->getCDTLyrics(),
67 strlen(i
->getChild(0)->getChild(tno
)->getCDTLyrics())+1);
70 addBlockData(Blk_Composer
, (uint8
*)i
->getChild(0)->getCDTComposer(), strlen(i
->getChild(0)->getCDTComposer())+1);
71 for (int tno
=0; tno
<i
->getChild(0)->getChildCount(); tno
++)
73 addBlockData(Blk_Composer
,
74 (uint8
*)i
->getChild(0)->getChild(tno
)->getCDTComposer(),
75 strlen(i
->getChild(0)->getChild(tno
)->getCDTComposer())+1);
78 addBlockData(Blk_Arranger
, (uint8
*)i
->getChild(0)->getCDTDirector(), strlen(i
->getChild(0)->getCDTDirector())+1);
79 for (int tno
=0; tno
<i
->getChild(0)->getChildCount(); tno
++)
81 addBlockData(Blk_Arranger
,
82 (uint8
*)i
->getChild(0)->getChild(tno
)->getCDTDirector(),
83 strlen(i
->getChild(0)->getChild(tno
)->getCDTDirector())+1);
86 addBlockData(Blk_Message
, (uint8
*)i
->getChild(0)->getCDTMessage(), strlen(i
->getChild(0)->getCDTMessage())+1);
87 for (int tno
=0; tno
<i
->getChild(0)->getChildCount(); tno
++)
89 addBlockData(Blk_Message
,
90 (uint8
*)i
->getChild(0)->getChild(tno
)->getCDTMessage(),
91 strlen(i
->getChild(0)->getChild(tno
)->getCDTMessage())+1);
97 * we want to build size info here. now some rules:
98 * - the total size of cdtext block is what-we-got-so-far + 2 (= id of the last block).
99 * - size info always goes last because it's easier to compute :P
100 * - we fill in some table (initially filled with 0s) and push it to cdtext.
101 * the resulting array can be written almost directly to cd. we need to make
102 * the buffer n*96 bytes big and copy our data there (it's easy), then just tell drive
103 * to generate the pad data for us. that's it %]
106 size
.charCode
= Chr_ISO8859_1
;
107 size
.firstTrack
= i
->getChild(0)->getChild(0)->getItemNumber();
108 size
.lastTrack
= i
->getChild(0)->getChild(-1)->getItemNumber();
110 size
.lastSeqNum
[0] = currentPackNo
+2;
111 size
.languages
[0] = Lng_English
;
112 addBlockData(Blk_Size
, (uint8
*)&size
, sizeof(size
));
119 void CDText::addBlockData(Block b
, uint8
*data
, int16 size
)
121 if (b
!= currentBlock
)
130 ASSERT(currentOffset
<= 12);
132 if (currentOffset
== 12)
137 if (currentOffset
== 0)
139 currentPack
.block
= b
;
140 currentPack
.blockTrack
= currentTrack
;
141 currentPack
.totalPack
= currentPackNo
++;
142 currentPack
.charPos
= currentByte
;
145 while ((currentOffset
< 12) && (size
--))
147 currentPack
.data
[currentOffset
++] = *data
++;
148 if ((b
>= Blk_Title
) && (b
<= Blk_Message
))
152 if (currentOffset
== 12)
161 addBlockData(b
, data
, size
);
170 void CDText::closePack()
172 if (currentOffset
== 0)
175 while (currentOffset
< 12)
176 currentPack
.data
[currentOffset
++] = 0;
179 crc
.Update((uint8
*)¤tPack
, 16);
181 currentPack
.crc16
[0] = ~((crc
.GetSum() & 0xff00) >> 8);
182 currentPack
.crc16
[1] = ~(crc
.GetSum() & 0xff);
183 packs
<< currentPack
;
185 if (currentBlock
== Blk_Size
)
187 size
.packsCount
[Blk_Size
- 0x80] = 3;
191 size
.packsCount
[currentBlock
- 0x80]++;
197 void CDText::printReport(DbgHandler
* __dbg
)
199 for (int i
=0; i
<packs
.Count(); i
++)
201 _D(Lvl_Info
, "%08ld: %02lx %02lx %02lx %02lx: %02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx | %02lx %02lx",
207 packs
[i
].data
[0], packs
[i
].data
[1], packs
[i
].data
[2], packs
[i
].data
[3], packs
[i
].data
[4], packs
[i
].data
[5],
208 packs
[i
].data
[6], packs
[i
].data
[7], packs
[i
].data
[8], packs
[i
].data
[9], packs
[i
].data
[10], packs
[i
].data
[11],
209 packs
[i
].crc16
[0], packs
[i
].crc16
[1]);
213 bool CDText::hasCDText()
218 bool CDText::getDataBuffer(uint8
*& tgt
, int32
& size
)
223 if (hasCDText() == false)
226 size
= 24 * packs
.Count() + 95;
227 size
= (size
/ 96)*96;
229 tgt
= new uint8
[size
];
230 for (int i
=0; i
<packs
.Count(); i
++)
232 dat
= (uint8
*)&packs
[i
];
233 for (int j
=0; j
<6; j
++)
235 tgt
[off
++] = (dat
[3*j
] >> 2) & 0x3f;
236 tgt
[off
++] = ((dat
[3*j
]<< 4) | (dat
[3*j
+1] >> 4)) & 0x3f;
237 tgt
[off
++] = ((dat
[3*j
+1]<< 2) | (dat
[3*j
+2] >> 6)) & 0x3f;
238 tgt
[off
++] = (dat
[3*j
+2]) & 0x3f;