From 3f5067c8c2a6716c317bbbdf61fc07e2ecf04496 Mon Sep 17 00:00:00 2001 From: Jeremy Bullock Date: Sep 08 2016 06:19:01 +0000 Subject: Mp3 Import (#749) MP3 import ( ffmpeg required ) --- diff --git a/toonz/sources/sound/CMakeLists.txt b/toonz/sources/sound/CMakeLists.txt index 668fa13..bb66ec3 100644 --- a/toonz/sources/sound/CMakeLists.txt +++ b/toonz/sources/sound/CMakeLists.txt @@ -2,6 +2,7 @@ set(HEADERS wav/tsio_wav.h aiff/tsio_aiff.h raw/tsio_raw.h + mp3/tsio_mp3.h ../include/tnzsound.h tsio.h ) @@ -12,6 +13,7 @@ set(SOURCES wav/tsio_wav.cpp aiff/tsio_aiff.cpp raw/tsio_raw.cpp + mp3/tsio_mp3.cpp ) add_library(sound SHARED ${HEADERS} ${SOURCES}) @@ -27,7 +29,7 @@ message("subdir: sound") message("type:" ${CMAKE_SHARED_LIBRARY_SUFFIX}) message("Bin: " ${CMAKE_CURRENT_BINARY_DIR}) -_find_toonz_library(EXTRA_LIBS tnzcore) +_find_toonz_library(EXTRA_LIBS "tnzcore;tnzbase;toonzlib") message("ToonzCore: " ${EXTRA_LIBS}) target_link_libraries(sound Qt5::Core ${EXTRA_LIBS}) diff --git a/toonz/sources/sound/mp3/tsio_mp3.cpp b/toonz/sources/sound/mp3/tsio_mp3.cpp new file mode 100644 index 0000000..e53d337 --- /dev/null +++ b/toonz/sources/sound/mp3/tsio_mp3.cpp @@ -0,0 +1,103 @@ +#include + +#include "tmachine.h" +#include "tsio_mp3.h" +#include "tsystem.h" +#include "tfilepath_io.h" +#include "tsound_t.h" +#include "toonz/preferences.h" +#include "toonz/toonzfolders.h" +#include +#include + +//============================================================================== + +TSoundTrackReaderMp3::TSoundTrackReaderMp3(const TFilePath &fp) + : TSoundTrackReader(fp) {} + +//------------------------------------------------------------------------------ + +TSoundTrackP TSoundTrackReaderMp3::load() { + FfmpegAudio *ffmepegAudio = new FfmpegAudio(); + TFilePath tempFile = ffmepegAudio->getRawAudio(m_path); + + Tifstream is(tempFile); + + if (!is) + throw TException(L"Unable to load the RAW file " + m_path.getWideString() + + L" : doesn't exist"); + + is.seekg(0, std::ios_base::end); + long sampleCount = is.tellg() / 4; + is.seekg(0, std::ios_base::beg); + + TSoundTrack *track = new TSoundTrackStereo16(44100, 2, sampleCount); + is.read((char *)track->getRawData(), sampleCount * 4); + return track; +} + +bool FfmpegAudio::checkFfmpeg() { + // check the user defined path in preferences first + QString path = Preferences::instance()->getFfmpegPath() + "/ffmpeg"; +#if defined(_WIN32) + path = path + ".exe"; +#endif + if (TSystem::doesExistFileOrLevel(TFilePath(path))) return true; + + // check the OpenToonz root directory next + path = QDir::currentPath() + "/ffmpeg"; +#if defined(_WIN32) + path = path + ".exe"; +#endif + if (TSystem::doesExistFileOrLevel(TFilePath(path))) { + Preferences::instance()->setFfmpegPath(QDir::currentPath().toStdString()); + return true; + } + + // give up + return false; +} + +TFilePath FfmpegAudio::getFfmpegCache() { + QString cacheRoot = ToonzFolder::getCacheRootFolder().getQString(); + if (!TSystem::doesExistFileOrLevel(TFilePath(cacheRoot + "/ffmpeg"))) { + TSystem::mkDir(TFilePath(cacheRoot + "/ffmpeg")); + } + std::string ffmpegPath = + TFilePath(cacheRoot + "/ffmpeg").getQString().toStdString(); + return TFilePath(cacheRoot + "/ffmpeg"); +} + +void FfmpegAudio::runFfmpeg(QStringList args) { + // write the file + QString m_ffmpegPath = Preferences::instance()->getFfmpegPath(); + std::string strFfmpegPath = m_ffmpegPath.toStdString(); + QProcess ffmpeg; + ffmpeg.start(m_ffmpegPath + "/ffmpeg", args); + ffmpeg.waitForFinished(30000); + QString results = ffmpeg.readAllStandardError(); + results += ffmpeg.readAllStandardOutput(); + int exitCode = ffmpeg.exitCode(); + ffmpeg.close(); + std::string strResults = results.toStdString(); +} + +TFilePath FfmpegAudio::getRawAudio(TFilePath path) { + std::string name = path.getName(); + TFilePath outPath = getFfmpegCache() + TFilePath(name + ".raw"); + std::string strPath = path.getQString().toStdString(); + std::string strOutPath = outPath.getQString().toStdString(); + QStringList args; + args << "-i"; + args << path.getQString(); + args << "-f"; + args << "s16le"; + args << "-ac"; + args << "2"; + args << "-ar"; + args << "44100"; + args << "-y"; + args << outPath.getQString(); + runFfmpeg(args); + return outPath; +} \ No newline at end of file diff --git a/toonz/sources/sound/mp3/tsio_mp3.h b/toonz/sources/sound/mp3/tsio_mp3.h new file mode 100644 index 0000000..60797c6 --- /dev/null +++ b/toonz/sources/sound/mp3/tsio_mp3.h @@ -0,0 +1,42 @@ +#pragma once + +#ifndef TSIO_MP3_INCLUDED +#define TSIO_MP3_INCLUDED + +#include "tsound_io.h" + +//========================================================== +/*! +The class TSoundTrackReaderMp3 reads audio files having +.mp3 extension +*/ +class TSoundTrackReaderMp3 final : public TSoundTrackReader { +public: + TSoundTrackReaderMp3(const TFilePath &fp); + ~TSoundTrackReaderMp3() {} + + /*! +Loads the .mp3 audio file whose path has been specified in the constructor. +It returns a TSoundTrackP created from the audio file +*/ + TSoundTrackP load() override; + + /*! +Returns a soundtrack reader able to read .mp3 audio files +*/ + static TSoundTrackReader *create(const TFilePath &fp) { + return new TSoundTrackReaderMp3(fp); + } +}; + +class FfmpegAudio { +public: + TFilePath getRawAudio(TFilePath path); + static bool checkFfmpeg(); + +private: + TFilePath getFfmpegCache(); + void runFfmpeg(QStringList args); +}; + +#endif diff --git a/toonz/sources/sound/tsio.cpp b/toonz/sources/sound/tsio.cpp index 5bc932f..bff4eb0 100644 --- a/toonz/sources/sound/tsio.cpp +++ b/toonz/sources/sound/tsio.cpp @@ -25,5 +25,10 @@ void initSoundIo() { TSoundTrackWriter::define("raw", TSoundTrackWriterRaw::create); TFileType::declare("raw", TFileType::AUDIO_LEVEL); + if (FfmpegAudio::checkFfmpeg()) { + TSoundTrackReader::define("mp3", TSoundTrackReaderMp3::create); + // TSoundTrackWriter::define("mp3", TSoundTrackWriterMp3::create); + TFileType::declare("mp3", TFileType::AUDIO_LEVEL); + } // return &info; } diff --git a/toonz/sources/sound/tsio.h b/toonz/sources/sound/tsio.h index 3070f36..4c35aa4 100644 --- a/toonz/sources/sound/tsio.h +++ b/toonz/sources/sound/tsio.h @@ -6,5 +6,6 @@ #include "wav/tsio_wav.h" #include "aiff/tsio_aiff.h" #include "raw/tsio_raw.h" +#include "mp3/tsio_mp3.h" #endif