result Wav::loadflac(MemoryFile *aReader) { drflac *decoder = drflac_open_memory(aReader->mDataPtr, aReader->mDataLength); if (!decoder) { return FILE_LOAD_FAILED; } drflac_uint64 samples = decoder->totalSampleCount; if (!samples) { drflac_close(decoder); return FILE_LOAD_FAILED; } mData = new float[(unsigned int)(samples * decoder->channels)]; mBaseSamplerate = (float)decoder->sampleRate; mSampleCount = (unsigned int)samples; mChannels = decoder->channels; drflac_seek_to_pcm_frame(decoder, 0); unsigned int i, j, k; for (i = 0; i < mSampleCount; i += 512) { float tmp[512 * MAX_CHANNELS]; unsigned int blockSize = (mSampleCount - i) > 512 ? 512 : mSampleCount - i; drflac_read_pcm_frames_f32(decoder, blockSize, tmp); for (j = 0; j < blockSize; j++) { for (k = 0; k < decoder->channels; k++) { mData[k * mSampleCount + i + j] = tmp[j * decoder->channels + k]; } } } drflac_close(decoder); return SO_NO_ERROR; }
int main(int argc, char** argv) { (void)argc; (void)argv; #if 1 const char* testFiles[] = { "ocremix_tests/7th Saga - Seven Songs for Seventh Saga/FLAC/01 Seven Songs for Seventh Saga - I. Wind.flac", "ocremix_tests/7th Saga - Seven Songs for Seventh Saga/FLAC/02 Seven Songs for Seventh Saga - II. Water.flac", "ocremix_tests/7th Saga - Seven Songs for Seventh Saga/FLAC/03 Seven Songs for Seventh Saga - III. Star.flac", "ocremix_tests/7th Saga - Seven Songs for Seventh Saga/FLAC/04 Seven Songs for Seventh Saga - IV. Sky.flac", "ocremix_tests/7th Saga - Seven Songs for Seventh Saga/FLAC/05 Seven Songs for Seventh Saga - V. Moon.flac", "ocremix_tests/7th Saga - Seven Songs for Seventh Saga/FLAC/06 Seven Songs for Seventh Saga - VI. Light.flac", "ocremix_tests/7th Saga - Seven Songs for Seventh Saga/FLAC/07 Seven Songs for Seventh Saga - VII. Wizard.flac", "ocremix_tests/Apex 2015 - This Is the Moment/FLAC/01 John Ryan - This Is the Moment [Main Theme of Apex 2015].flac", "ocremix_tests/Apex 2015 - This Is the Moment/FLAC/02 DusK - A Day Like No Other [Ultimate Marvel vs. Capcom 3].flac", "ocremix_tests/Apex 2015 - This Is the Moment/FLAC/03 DarkeSword - Got My Mind on My Money Match [Super Smash Bros. for Wii U].flac", "ocremix_tests/Apex 2015 - This Is the Moment/FLAC/04 CJthemusicdude - Smashed Fridge Bits [Super Smash Bros. Melee].flac", "ocremix_tests/Apex 2015 - This Is the Moment/FLAC/05 Amphibious - Forest Fire [Pokemon X and Y].flac", "ocremix_tests/Apex 2015 - This Is the Moment/FLAC/06 DjjD - Bull in a China Shop [Super Smash Bros. Melee].flac", "ocremix_tests/Apex 2015 - This Is the Moment/FLAC/07 Sixto Sounds - Falcon DREAM!! [Super Smash Bros. Brawl].flac", "ocremix_tests/Apex 2015 - This Is the Moment/FLAC/08 WillRock - Filler Instinct [Killer Instinct].flac", "ocremix_tests/Apex 2015 - This Is the Moment/FLAC/09 Neblix - Girl from Another World [Ultra Street Fighter IV].flac", "ocremix_tests/Apex 2015 - This Is the Moment/FLAC/10 Ivan Hakstok - May the Stars Light Your Way [Guilty Gear Xrd].flac", "ocremix_tests/CEO 2015 - Champion/FLAC/01 O_Super x Mag.Lo - CEO Champion [Main Theme of CEO 2015].flac", "ocremix_tests/CEO 2015 - Champion/FLAC/02 Jeff Matthews - The Last Kill [Killer Instinct].flac", "ocremix_tests/CEO 2015 - Champion/FLAC/03 DarkeSword - Kuro Yuki [Persona 4 Arena].flac", "ocremix_tests/CEO 2015 - Champion/FLAC/04 DjjD - Prodigious Blitz [Tekken Tag Tournament 2].flac", "ocremix_tests/CEO 2015 - Champion/FLAC/05 Richie Branson - Iron Fist [Tekken Theme of CEO 2015].flac", "ocremix_tests/CEO 2015 - Champion/FLAC/06 Flexstyle - It's Okay, I Still Made Money [Divekick].flac", "ocremix_tests/CEO 2015 - Champion/FLAC/07 zykO - #unanimous #undisputed [Super Smash Bros. for Wii U].flac", "ocremix_tests/CEO 2015 - Champion/FLAC/08 Benjamin Briggs - FALCON PUNCH [Super Smash Bros. Theme of CEO 2015].flac", "ocremix_tests/CEO 2015 - Champion/FLAC/09 Neblix - Together, We Fly [Super Smash Bros. Melee].flac", "ocremix_tests/CEO 2015 - Champion/FLAC/10 DarkeSword - Fatalistic [Mortal Kombat].flac", "ocremix_tests/CEO 2015 - Champion/FLAC/11 Richie Branson - Finish Him [Mortal Kombat Theme of CEO 2015].flac", "ocremix_tests/CEO 2015 - Champion/FLAC/12 DarkeSword - U JELLY! [Guilty Gear X].flac", "ocremix_tests/CEO 2015 - Champion/FLAC/13 Nutritious - Dash Cancel [Ultra Street Fighter IV].flac", "ocremix_tests/CEO 2015 - Champion/FLAC/14 Ivan Hakstok, Sixto Sounds - What's Your Poison [Ultimate Marvel vs. Capcom 3].flac", "ocremix_tests/Final Fantasy II - Rebellion/FLAC/1-01 Preluematsude (Prelude) [Jeff Ball].flac", "ocremix_tests/Final Fantasy II - Rebellion/FLAC/1-02 The Last March (The Imperial Army) [Dr. Manhattan].flac", "ocremix_tests/Final Fantasy II - Rebellion/FLAC/1-03 Rebirth (Revival) [Brandon Strader].flac", "ocremix_tests/Final Fantasy II - Rebellion/FLAC/1-04 Rebel Dream [Main Theme (FF1), The Rebel Army, Find Your Way (FF8), Main Theme] (BONKERS).flac", "ocremix_tests/Final Fantasy II - Rebellion/FLAC/1-05 Leon Is a F*****g Dick (Battle Theme 1) [Kidd Cabbage].flac", "ocremix_tests/Final Fantasy II - Rebellion/FLAC/1-06 garLACTUS Win [Victory, Fanfare (FF7)] (Darkmoocher).flac", "ocremix_tests/Final Fantasy II - Rebellion/FLAC/1-07 Deuces (Ancient Castle) [mellogear].flac", "ocremix_tests/Final Fantasy II - Rebellion/FLAC/1-08 Firion N Maria (Will Take You to the Rebels) [The Rebel Army] (PrototypeRaptor).flac", "ocremix_tests/Final Fantasy II - Rebellion/FLAC/1-09 Analog Freedom (Town, The Rebel Army) [BONKERS].flac", "ocremix_tests/Final Fantasy II - Rebellion/FLAC/1-10 the final WON (Battle Theme A, Victory) [W!SE the all.E].flac", "ocremix_tests/Final Fantasy II - Rebellion/FLAC/1-11 Rebellion (Dead Music, The Rebel Army) [Brandon Strader, Chernabogue, Detective Tuesday].flac", "ocremix_tests/Final Fantasy II - Rebellion/FLAC/2-01 Heroes of Dawn [Chaos Temple (FF1), Reunion, The Rebel Army, Deep Under the Water (FF3), Dead Music (FF1)] (PacificPoem).flac", "ocremix_tests/Final Fantasy II - Rebellion/FLAC/2-02 Snakeyes (Battle Theme B) [zykO].flac", "ocremix_tests/Final Fantasy II - Rebellion/FLAC/2-03 Grind My Crank (Tower of the Magi) [XPRTNovice].flac", "ocremix_tests/Final Fantasy II - Rebellion/FLAC/2-04 Personification of Evil (The Emperor's Rebirth, Escape!) [Tuberz McGee].flac", "ocremix_tests/Final Fantasy II - Rebellion/FLAC/2-05 A Kingdom Fallen (Main Theme) [Sixto Sounds].flac", "ocremix_tests/Final Fantasy II - Rebellion/FLAC/2-06 Torchlit (Dungeon) [Viking Guitar].flac", "ocremix_tests/Final Fantasy II - Rebellion/FLAC/2-07 GG but ___ Solos Win [Victory, The Winner (FF8)] (Sir Jordanius feat. Brandon Strader).flac", "ocremix_tests/Final Fantasy II - Rebellion/FLAC/2-08 Castellum Infernum (Castle Pandemonium) [Brandon Strader].flac", "ocremix_tests/Final Fantasy II - Rebellion/FLAC/2-09 Imperial Rapture (Battle Theme 2) [IanFitC].flac", "ocremix_tests/Final Fantasy II - Rebellion/FLAC/2-10 Finally (Finale) [Hat].flac", "ocremix_tests/01 The Orichalcon - megAsfear (Title).flac", "ocremix_tests/02 Evil Horde - Running from Evil Horde (MAP01 - Running from Evil).flac", "ocremix_tests/03 analoq - Adrian's Sleep (MAP25 - Adrian's Asleep).flac", "ocremix_tests/04 Mazedude - Westside Archvile (MAP20 - Message for the Archvile).flac", "ocremix_tests/05 Jovette Rivera - The Countdown (MAP03 - Countdown to Death).flac", "ocremix_tests/06 The Orichalcon - Crushing Headache (MAP06 - In the Dark).flac", "ocremix_tests/07 Mazedude - Silent Healer (MAP02 - The Healer Stalks).flac", "ocremix_tests/08 Big Giant Circles, Flik - Icon of Sinwave (MAP30 - Opening to Hell).flac", "ocremix_tests/09 John Revoredo - 31 Seconds (MAP09 - Into Sandy's City).flac", "ocremix_tests/10 Mazedude, Ailsean - The End of Hell (Endgame).flac", "ocremix_tests/11 phoenixdk - No Smoking Area (MAP23 - Bye Bye American Pie).flac", "ocremix_tests/12 Evil Horde - The Duel (MAP08 - The Dave D. Taylor Blues).flac", "ocremix_tests/13 djpretzel - Red Waltz (Intermission).flac", "ocremix_tests/Bonus phoenixdk - Ablaze (MAP10 - The Demon's Dead).flac", "Hallelujah.flac", "1 Sullivan The Lost Chord, Seated one day at the organ.FLAC", "1 Vaet Videns Dominus.FLAC", "3 Schubert String Quartet No 14 in D minor Death and the Maiden, D810 - Movement 3 Scherzo Allegro molto.FLAC", "14 Clementi Piano Sonata in D major, Op 25 No 6 - Movement 2 Un poco andante.FLAC", "E+questa+vita+un+lampo+Studio+Master.flac", "recit24bit.flac", "recit16bit.flac", "recit8bit.flac", "song1.flac", "BIS1536-001-flac_24.flac", "BIS1447-002-flac_24.flac", }; unsigned int testCount = sizeof(testFiles) / sizeof(testFiles[0]); for (unsigned int i = 0; i < testCount; ++i) { const char* filename = testFiles[i]; if (do_test(filename)) { printf("TEST PASSED: %s\n", filename); } } #endif #if 0 FILE* pFile; //if (fopen_s(&pFile, "BIS1536-001-flac_24.flac", "rb") != 0) { //if (fopen_s(&pFile, "BIS1447-002-flac_24.flac", "rb") != 0) { //if (fopen_s(&pFile, "song1.flac", "rb") != 0) { //if (fopen_s(&pFile, "recit24bit.flac", "rb") != 0) { if (fopen_s(&pFile, "recit8bit.flac", "rb") != 0) { return -1; } fseek(pFile, 0, SEEK_END); size_t fileDataSize = (size_t)ftell(pFile); fseek(pFile, 0, SEEK_SET); void* pFileData = malloc(fileDataSize); fread(pFileData, 1, fileDataSize, pFile); fclose(pFile); drflac* pFlac = drflac_open_memory(pFileData, fileDataSize); if (pFlac == NULL) { return -1; } uint64_t firstSample = pFlac->totalSampleCount / 2; drflac_seek_to_sample(pFlac, firstSample); int* pSampleData = malloc((size_t)pFlac->totalSampleCount * sizeof(int)); drflac_read_s32(pFlac, (size_t)(pFlac->totalSampleCount - firstSample), pSampleData); //drflac_seek_to_sample(&flac, 0); //drflac_read_s32(&flac, (size_t)(flac.totalSampleCount - firstSample), pSampleData); draudio_context* pContext = draudio_create_context(); if (pContext == NULL) { return -2; } draudio_device* pDevice = draudio_create_output_device(pContext, 0); if (pDevice == NULL) { return -3; } draudio_buffer_desc bufferDesc; memset(&bufferDesc, 0, sizeof(&bufferDesc)); bufferDesc.format = draudio_format_pcm; bufferDesc.channels = pFlac->channels; bufferDesc.sampleRate = pFlac->sampleRate; bufferDesc.bitsPerSample = sizeof(int)*8; bufferDesc.sizeInBytes = (size_t)pFlac->totalSampleCount * sizeof(int); bufferDesc.pData = pSampleData; draudio_buffer* pBuffer = draudio_create_buffer(pDevice, &bufferDesc, 0); if (pBuffer == NULL) { return -4; } draudio_play(pBuffer, false); #endif #if 0 drflac flac; drflac_open_file(&flac, "MyFile.flac"); int* pSampleData = malloc((size_t)flac.totalSampleCount * sizeof(int)); drflac_read_s32(&flac, flac.totalSampleCount, pSampleData); #endif //_getch(); return 0; }
void DrFlacImporter::doOpenData(Containers::ArrayView<const char> data) { drflac* const handle = drflac_open_memory(data.data(), data.size()); if(!handle) { Error() << "Audio::DrFlacImporter::openData(): failed to open and decode FLAC data"; return; } Containers::ScopeGuard drflacClose{handle, drflac_close}; const std::uint64_t samples = handle->totalSampleCount; const std::uint8_t numChannels = handle->channels; const std::uint8_t bitsPerSample = handle->bitsPerSample; /* FLAC supports any bitspersample from 4 to 64, but DrFlac always gives us 32-bit samples. So we normalize bit amounts to multiples of 8, rounding up. */ const UnsignedInt normalizedBytesPerSample = (bitsPerSample + 7)/8; if(numChannels == 0 || numChannels == 3 || numChannels == 5 || numChannels > 8 || normalizedBytesPerSample == 0 || normalizedBytesPerSample > 8) { Error() << "Audio::DrFlacImporter::openData(): unsupported channel count" << numChannels << "with" << bitsPerSample << "bits per sample"; return; } /* Can't load something with no samples */ if(samples == 0) { Error() << "Audio::DrFlacImporter::openData(): no samples"; return; } _frequency = handle->sampleRate; _format = flacFormatTable[numChannels-1][normalizedBytesPerSample-1]; CORRADE_INTERNAL_ASSERT(_format != BufferFormat{}); /* 32-bit integers need to be normalized to Double (with a 32 bit mantissa) */ if(normalizedBytesPerSample == 4) { Containers::Array<Int> tempData(samples); drflac_read_s32(handle, samples, reinterpret_cast<Int*>(tempData.begin())); /* If the channel is mono/stereo, we can use double samples */ if(numChannels < 3) { Containers::Array<Double> doubleData(samples); for(std::size_t i = 0; i < samples; ++i) { doubleData[i] = Math::unpack<Double>(tempData[i]); } const char* doubleBegin = reinterpret_cast<const char*>(doubleData.begin()); const char* doubleEnd = reinterpret_cast<const char*>(doubleData.end()); _data = Containers::Array<char>(samples*sizeof(Double)); std::copy(doubleBegin, doubleEnd, _data.begin()); /* Otherwise, convert to float */ } else { Containers::Array<Float> floatData(samples); for(std::size_t i = 0; i < samples; ++i) { floatData[i] = Math::unpack<Float>(tempData[i]); } const char* floatBegin = reinterpret_cast<const char*>(floatData.begin()); const char* floatEnd = reinterpret_cast<const char*>(floatData.end()); _data = Containers::Array<char>(samples*sizeof(Float)); std::copy(floatBegin, floatEnd, _data.begin()); } return; } Containers::Array<char> tempData(samples*sizeof(Int)); drflac_read_s32(handle, samples, reinterpret_cast<Int*>(tempData.begin())); _data = convert32PCM(tempData, samples, normalizedBytesPerSample); /* 8-bit needs to become unsigned */ if(normalizedBytesPerSample == 1) { for(char& item: _data) item = item - 128; /* 24-bit needs to become float */ } else if(normalizedBytesPerSample == 3) { Containers::Array<Float> floatData(samples); for(std::size_t i = 0; i != samples; ++i) { const UnsignedInt s0 = _data[i*3 + 0]; const UnsignedInt s1 = _data[i*3 + 1]; const UnsignedInt s2 = _data[i*3 + 2]; const Int intData = Int((s0 << 8) | (s1 << 16) | (s2 << 24)); floatData[i] = Math::unpack<Float>(intData); } const char* const floatBegin = reinterpret_cast<const char*>(floatData.begin()); const char* const floatEnd = reinterpret_cast<const char*>(floatData.end()); _data = Containers::Array<char>(samples*sizeof(Float)); std::copy(floatBegin, floatEnd, _data.begin()); } return; }