How to create a hidden track at the beginning of a CD – Part 2
PrimoBurnerSDK 3.5.6 introduced a new way for writing hidden tracks to audio CDs.
Before 3.5.6 there would always be a digital silence of 2 seconds at the start of the pre-gap on the first track.
Now PrimoBurner allows the first two seconds to be filled with audio too. All that needs to be done is to set the pre-gap start of the first track to -150. The following code shows how you can use the new feature:
void WriteToCD_HiddenTrack_With_User_Data_In_First_2seconds(char driveLetter)
{
IEngine * engine = Library::CreateEngine();
engine->Initialize();
int deviceIndex = Library::GetCDROMIndexFromLetter(driveLetter);
IDeviceEnum * devices = engine->GetDevices();
IDevice* dev = devices->GetItem(deviceIndex, 1);
IAudioCD* audio = Library::CreateAudioCD();
audio->SetDevice(dev);
audio->SetAudioDecodingMethod(ADM_MEMORY);
char_t* inputPath = _T("C:sample.wav");
IAudioInput* ain = Library::CreateAudioInput();
ain->SetFilePath(inputPath);
bool_t res = audio->GetAudioInputsRef()->Add(ain);
if (!res)
{
// failed to add audio input
return;
}
// Leave AudioCD to be the single owner the IAudioInput instance
ain->Release();
ain = NULL;
int32_t len1 = audio->GetInputLength(audio->GetAudioInputsRef()->GetItemRef(0));
// It is essential that the audio input should be 2 seconds longer than usual,
// since the first 150 frames(blocks) of the input will be written in the 2s pregap
// that is usually filled with digital silence
printf("audio frames: %d", len1);
ICDSession* pSession = Library::CreateCDSession();
pSession->SetType(ST_CDDA);
ICDTrack* pTrack = Library::CreateCDTrack();
pTrack->SetType(TT_AUDIO);
// CD_PREGAP_START equals -150 - this will allow you to write user data in
// the first 2 seconds of the pregap as well
pTrack->SetPregapStart(CD_PREGAP_START);
// Just leave the first 2 seconds as the intended pregap (hidden track) and continue
// from address 0 with the rest of the audio input data
pTrack->SetStart(0);
int32_t pos = len1 - 1;
// Since the first two seconds of the audio input will be in the pregap,
// then the actual end is CD_PREGAP_LENGTH blocks earlier as well.
pTrack->SetEnd(pos - CD_PREGAP_LENGTH);
// The same goes for the postgap
pTrack->SetPostgapEnd(pos - CD_PREGAP_LENGTH);
pSession->GetTracksRef()->Add(pTrack);
pTrack->Release();
audio->SetCDSession(pSession);
pSession->Release();
res = audio->WriteToCD();
if (!res)
{
printf("n last error: 0x%x n ", audio->GetLastError());
}
audio->Release();
dev->Release();
devices->Release();
engine->Shutdown();
engine->Release();
}
Note the CD_PREGAP_START
constant – it is a negative value and equals -150. Using a pre-gap start value other than -150 and less then 0 will result in AUDIOCD_INVALID_CD_SESSION
error.
By default PrimoBurner SDK ensures that the audio inputs could provide at least 4 seconds of data. Any inputs that are shorter will have trailing silence added when burned to the disc.
There is a new IAudioInput::SetForceMinTrackLength
method that controls that behavior. If you have to create a track from small audio segments call SetForceMinTrackLength(FALSE)
to disable the track length validation.