void BassCastPimpl::InitMachines() { machineStack = new_shared<MachineStack>(); noiseSource = new_shared<NoiseSource>(); bassSource = new_shared<BassSource>(); avSource = new_shared<AvSource>(); resample = new_shared<Resample>(); mixChannels = new_shared<MixChannels>(); mapChannels = new_shared<MapChannels>(); linearFade = new_shared<LinearFade>(); gain = new_shared<Gain>(); noiseSource->SetChannels(setting::encoder_channels); float ratio = setting::amiga_channel_ratio; mixChannels->Set(1 - ratio, ratio, 1 - ratio, ratio); mapChannels->SetOutChannels(setting::encoder_channels); machineStack->AddMachine(noiseSource); machineStack->AddMachine(resample); machineStack->AddMachine(mixChannels); machineStack->AddMachine(mapChannels); machineStack->AddMachine(linearFade); machineStack->AddMachine(gain); converter.SetSource(machineStack); }
// this is called whenever the song is changed void BassCastPimpl::ChangeSong() { // reset routing resample->SetEnabled(false); mixChannels->SetEnabled(false); linearFade->SetEnabled(false); SongInfo songInfo; uint32_t samplerate = setting::encoder_samplerate; double duration = 0; for (bool loadSuccess = false; !loadSuccess;) { bool bassLoaded = false; bool avLoaded = false; GetNextSong(songInfo); if (exists(songInfo.fileName)) { // try loading by extension if (BassSource::CheckExtension(songInfo.fileName)) bassLoaded = bassSource->Load(songInfo.fileName); else if (AvSource::CheckExtension(songInfo.fileName)) avLoaded = avSource->Load(songInfo.fileName); // if above failed if (!bassLoaded && !avLoaded) bassLoaded = bassSource->Load(songInfo.fileName); if (!bassLoaded && !avLoaded) avLoaded = avSource->Load(songInfo.fileName); } else Error("file doesn't exist: %1%"), songInfo.fileName; if (bassLoaded) { machineStack->AddMachine(bassSource, 0); samplerate = bassSource->Samplerate(); duration = bassSource->Duration(); if (bassSource->IsAmigaModule() && setting::encoder_channels == 2) mixChannels->SetEnabled(true); if (songInfo.loopDuration > 0) { bassSource->SetLoopDuration(songInfo.loopDuration); uint64_t const start = (songInfo.loopDuration - 5) * setting::encoder_samplerate; uint64_t const end = songInfo.loopDuration * setting::encoder_samplerate; linearFade->Set(start, end, 1, 0); linearFade->SetEnabled(true); } loadSuccess = true; } if (avLoaded) { machineStack->AddMachine(avSource, 0); samplerate = avSource->Samplerate(); loadSuccess = true; } if (!loadSuccess && songInfo.fileName == setting::error_tune) { Log(warning, "no error tune, playing some glorious noise"), songInfo.fileName; noiseSource->SetDuration(120 * setting::encoder_samplerate); machineStack->AddMachine(noiseSource, 0); gain->SetAmp(DbToAmp(-24)); loadSuccess = true; } } Log(info, "duration %1% seconds"), duration; if (samplerate != setting::encoder_samplerate) { resample->Set(samplerate, setting::encoder_samplerate); resample->SetEnabled(true); } // once clipping is working also apply positive gain gain->SetAmp(DbToAmp(songInfo.gain)); machineStack->UpdateRouting(); string title = create_cast_title(songInfo.artist, songInfo.title); BASS_Encode_CastSetTitle(encoder, title.c_str(), NULL); }