uint32_t AudioSourceOJM::Read(short* buffer, size_t count) { std::vector<short> temp_buf(count); size_t read = 0; if (TemporaryState.Enabled == 0) return 0; if (TemporaryState.Enabled == OJM_WAV) { read = sf_read_short(static_cast<SNDFILE*>(TemporaryState.File), temp_buf.data(), count); CheckInterruption(); } else if (TemporaryState.Enabled == OJM_OGG) { auto size = count * sizeof(short); while (read < size) { int sect; int res = ov_read(static_cast<OggVorbis_File*>(TemporaryState.File), reinterpret_cast<char*>(temp_buf.data()) + read, size - read, 0, 2, 1, §); if (res > 0) read += res; if (res <= 0) { if (res < 0) Log::Printf("Error loading ogg (%d)\n", res); break; } CheckInterruption(); } if (read < size) Log::Printf("AudioSourceOJM: PCM count differs from what's reported! (%d out of %d)\n", read, size); } std::copy(temp_buf.begin(), temp_buf.end(), buffer); return read; // We /KNOW/ we won't be overreading. }
bool ImageList::LoadAll() { bool WereErrors = false; for (auto i = Images.begin(); i != Images.end(); ++i) { i->second = ImageLoader::Load(i->first); if (i->second == nullptr) WereErrors = true; CheckInterruption(); } for (auto i = ImagesIndexPending.begin(); i != ImagesIndexPending.end();) { ImagesIndex[i->first] = ImageLoader::Load(i->second); if (ImagesIndex[i->first] == nullptr) WereErrors = true; i = ImagesIndexPending.erase(i); CheckInterruption(); } return WereErrors; }
void AudioSourceOJM::parseOMC() { OMC_header Head; int acc_keybyte = 0xFF; int acc_counter = 0; int Offset = 20; int SampleID = 0; ifile->read(reinterpret_cast<char*>(&Head), sizeof(OMC_header)); // Parse WAV data first while (Offset < Head.ogg_start) { CheckInterruption(); OMC_WAV_header WavHead; ifile->read(reinterpret_cast<char*>(&WavHead), sizeof(OMC_WAV_header)); Offset += sizeof(OMC_WAV_header) + WavHead.chunk_size; if (WavHead.chunk_size == 0) { SampleID++; continue; } std::vector<char> Buffer(WavHead.chunk_size); ifile->read(&Buffer[0], WavHead.chunk_size); omc_rearrange(&Buffer[0], WavHead.chunk_size); omc_xor(&Buffer[0], WavHead.chunk_size, acc_keybyte, acc_counter); int ifmt; switch (WavHead.bits_per_sample) { case 8: ifmt = SF_FORMAT_PCM_U8; break; case 16: ifmt = SF_FORMAT_PCM_16; break; case 24: ifmt = SF_FORMAT_PCM_24; break; case 32: ifmt = SF_FORMAT_PCM_32; break; default: ifmt = 0; } SF_INFO Info; Info.format = ifmt | SF_FORMAT_RAW; Info.samplerate = WavHead.sample_rate; Info.channels = WavHead.num_channels; SFM30 ToLoad; ToLoad.Buffer = std::move(Buffer); ToLoad.DataLength = WavHead.chunk_size; auto NewSample = std::make_shared<SoundSample>(); TemporaryState.File = sf_open_virtual(&M30Interface, SFM_READ, &Info, &ToLoad); TemporaryState.Info = &Info; TemporaryState.Enabled = OJM_WAV; NewSample->SetPitch(Speed); NewSample->Open(this); TemporaryState.Enabled = false; Arr[SampleID] = NewSample; SampleID++; } SampleID = 1000; // We start from the first OGG file.. while (Offset < Head.fsize) { CheckInterruption(); OMC_OGG_header OggHead; ifile->read(reinterpret_cast<char*>(&OggHead), sizeof(OMC_OGG_header)); Offset += sizeof(OMC_OGG_header) + OggHead.sample_size; if (OggHead.sample_size == 0) { SampleID++; continue; } std::vector<char> Buffer(OggHead.sample_size); ifile->read(&Buffer[0], OggHead.sample_size); auto NewSample = std::make_shared<SoundSample>(); SFM30 ToLoad; ToLoad.Buffer = Buffer; ToLoad.DataLength = OggHead.sample_size; OggVorbis_File vf; ov_open_callbacks(&ToLoad, &vf, nullptr, 0, M30InterfaceOgg); TemporaryState.File = &vf; TemporaryState.Info = vf.vi; TemporaryState.Enabled = OJM_OGG; NewSample->SetPitch(Speed); NewSample->Open(this); TemporaryState.Enabled = false; ov_clear(&vf); Arr[SampleID] = NewSample; SampleID++; } }
bool ScreenGameplay7K::LoadSongAudio() { if (!Music) { Music = std::make_shared<AudioStream>(); Music->SetPitch(Speed); if (MySong->SongFilename.length() && Music->Open((MySong->SongDirectory / MySong->SongFilename).c_path())) { Log::Printf("Stream for %s succesfully opened.\n", MySong->SongFilename.c_str()); } else { if (!CurrentDiff->IsVirtual) { // Caveat: Try to autodetect an mp3/ogg file. std::vector<std::string> DirCnt; auto SngDir = MySong->SongDirectory; SngDir.ListDirectory(DirCnt, Directory::FS_REG); for (auto i = DirCnt.begin(); i != DirCnt.end(); ++i) { if (Directory(*i).GetExtension() == "mp3" || Directory(*i).GetExtension() == "ogg") if (Music->Open((SngDir / *i).c_path())) return true; } Music = nullptr; Log::Printf("Unable to load song (Path: %s)\n", MySong->SongFilename.c_str()); return false; // Quit; couldn't find audio for a chart that requires it. } } } // Load samples. if (strstr(MySong->SongFilename.c_str(), ".ojm")) { Log::Printf("Loading OJM.\n"); OJMAudio = std::make_shared<AudioSourceOJM>(this); OJMAudio->SetPitch(Speed); OJMAudio->Open((MySong->SongDirectory / MySong->SongFilename).c_path()); for (int i = 1; i <= 2000; i++) { std::shared_ptr<SoundSample> Snd = OJMAudio->GetFromIndex(i); if (Snd != nullptr) Keysounds[i].push_back(Snd); } } else if (CurrentDiff->SoundList.size() || CurrentDiff->Data->TimingInfo->GetType() == VSRG::TI_BMS) { Log::Printf("Loading samples... "); if (CurrentDiff->Data->TimingInfo->GetType() == VSRG::TI_BMS) { Directory dir = MySong->SongDirectory; bool isBMSON = ((VSRG::BMSTimingInfo*)CurrentDiff->Data->TimingInfo.get())->IsBMSON; if (isBMSON) { int wavs = 0; std::map<int, SoundSample> audio; auto &slicedata = CurrentDiff->Data->SliceData; // do bmson loading for (auto wav : slicedata.Slices) { for (auto sounds : wav.second) { CheckInterruption(); // load basic sound if (!audio[sounds.first].IsValid()) { Directory path = (dir / slicedata.AudioFiles[sounds.first]); audio[sounds.first].SetPitch(Speed); if (!audio[sounds.first].Open(path.c_path())) throw std::exception(Utility::Format("Unable to load %s.", slicedata.AudioFiles[sounds.first]).c_str()); Log::Printf("BMSON: Load sound %s\n", path.c_path()); } audio[sounds.first].Slice(sounds.second.Start, sounds.second.End); Keysounds[wav.first].push_back(audio[sounds.first].CopySlice()); wavs++; } Keysounds[wav.first].shrink_to_fit(); } Log::Printf("BMSON: Generated %d sound objects.\n", wavs); } } for (auto i = CurrentDiff->SoundList.begin(); i != CurrentDiff->SoundList.end(); ++i) { auto ks = std::make_shared<SoundSample>(); ks->SetPitch(Speed); #ifdef WIN32 std::wstring sd = Utility::Widen(MySong->SongDirectory) + L"/" + Utility::Widen(i->second); ks->Open(Utility::Narrow(sd).c_str()); #else ks->Open((MySong->SongDirectory + "/" + i->second).c_str()); #endif Keysounds[i->first].push_back(ks); CheckInterruption(); } } return true; }