24 #include "sound/MASoundData.hpp" 27 #include <MCThreadLocalData.hpp> 29 #if defined(LIBARCHIVE_USE_INTERNAL) 31 #include <archive_entry.h> 33 #define __LIBARCHIVE_BUILD 34 #include <archive_private.h> 37 #include <archive_entry.h> 40 #include <boost/algorithm/string/predicate.hpp> 41 #include <boost/scoped_ptr.hpp> 48 void CheckStaticVariables()
50 if (unlikely(!WriteBuffer.get()))
55 MASkit::MASkit() : AudioStart(0)
60 MASkit::MASkit(
const std::string& name, MA::MotionSkitSPtr motion, MA::LedSkitSPtr led,
61 MC::BinaryDataSPtr sound) :
Name(name), MotionSkit(motion), LedSkit(led),
62 SoundData(sound), AudioStart(0)
101 MC_LOG(
"++ %s skit content ++",
Name.c_str());
151 MC_WARNING(
"This skit (%s) has no motions inside to be mirrored",
Name.c_str());
152 return MA::SkitSPtr();
154 if (mirrored_name.empty())
156 MC_WARNING(
"Cannot create a noname mirrored skit from %s",
Name.c_str());
157 return MA::SkitSPtr();
159 MA::MotionSkitSPtr NewMotion(
MotionSkit->CloneMirrored());
169 if (!MotionSkit.get())
171 MC_WARNING(
"Invalid motion data cannot be converted to aib format");
174 archive* Archive(archive_write_new());
175 archive_entry* ArchiveEntry =
nullptr;
176 size_t FinalSize = 0;
178 archive_write_set_format_zip(Archive);
179 archive_write_add_filter_none(Archive);
180 CheckStaticVariables();
181 archive_write_open_memory(Archive, WriteBuffer->GetData(), WriteBuffer->GetSize(),
184 ArchiveEntry = archive_entry_new();
185 archive_entry_copy_pathname(ArchiveEntry,
186 std::string(
"Motion/"+MotionSkit->GetSkitName()+
".mtn").c_str());
187 archive_entry_set_mode(ArchiveEntry, AE_IFREG | 0755);
188 archive_entry_set_size(ArchiveEntry, motion_data.
GetSize());
189 archive_write_header(Archive, ArchiveEntry);
190 archive_entry_free(ArchiveEntry);
191 archive_write_data(Archive, motion_data.
GetData(), motion_data.
GetSize());
193 archive_write_close(Archive);
194 archive_write_free(Archive);
198 memcpy(FinalData->
GetData(), WriteBuffer->GetData(), FinalData->
GetSize());
206 archive* Archive(archive_read_new());
207 archive_entry* ArchiveEntry =
nullptr;
209 #if __cplusplus >= 201103L 210 #pragma GCC diagnostic push 211 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 213 archive_read_support_format_zip(Archive);
214 archive_read_support_compression_gzip(Archive);
215 archive_read_support_compression_none(Archive);
216 #if __cplusplus >= 201103L 217 #pragma GCC diagnostic pop 219 int result = archive_read_open_memory(Archive, BinaryData.
GetData(), BinaryData.
GetSize());
224 MC_WARNING(
"Binary data can not be read as aib (zip) format (error: %d)", result);
225 archive_read_free(Archive);
231 while (archive_read_next_header(Archive, &ArchiveEntry) == 0)
233 std::string FileName(archive_entry_pathname(ArchiveEntry));
236 if (Skit->
Name.empty() &&
237 (boost::algorithm::iends_with(FileName,
".mtn") ||
238 boost::algorithm::iends_with(FileName,
".wav") ||
239 boost::algorithm::iends_with(FileName,
".mid") ||
240 boost::algorithm::iends_with(FileName,
".info") ||
241 boost::algorithm::iends_with(FileName,
".led")))
245 Skit->
Name = FileName;
246 boost::split(Strs, Skit->
Name, boost::is_any_of(
"/"));
247 if (Strs.size() == 2)
249 Skit->
Name = Strs[1];
250 Skit->
Name.erase(Skit->
Name.size()-4, 4);
253 boost::scoped_ptr<MCBinaryData> FileData(
new MCBinaryData((
int)archive_entry_size(ArchiveEntry)));
255 result = archive_read_data(Archive, FileData->GetData(), FileData->GetSize());
256 if (result != FileData->GetSize())
260 if (boost::algorithm::iends_with(FileName,
".mtn"))
264 if (boost::algorithm::iends_with(FileName,
".info"))
268 if (boost::algorithm::iends_with(FileName,
".wav"))
271 MC::BinaryDataSPtr TempData(
new MCBinaryData((FileData->GetSize()-44)*2, 0));
272 MC::DoubleList ResampleData, RightChannel;
274 for (
int i = 0; i < TempData->GetSize() / 2; ++i)
275 ((int16_t*)(
void*)TempData->GetData())[i] = ((int16_t)FileData->GetData()[44+i]-128)*253;
281 if (boost::algorithm::iends_with(FileName,
".led"))
285 boost::split(Strs, FileName, boost::is_any_of(
"/"));
286 boost::split(Strs, Strs.back(), boost::is_any_of(
"."));
290 archive_read_close(Archive);
291 archive_read_free(Archive);
294 MC_WARNING(
"No motion/LED/sound skit found in aib decoding");
298 MC_LOG(
"Decoded skit: %s", Skit->
Name.c_str());
305 std::istringstream Stream;
307 Stream.rdbuf()->pubsetbuf((
char*)binary_data.
GetData(), binary_data.
GetSize());
308 while (Stream.good())
312 std::getline(Stream, Line);
313 if (boost::algorithm::istarts_with(Line,
"SOUNDSTART"))
317 boost::split(Strs, Line, boost::is_any_of(
" "));
318 if (Strs.size() >= 2)
320 return MCStrConvert<int>(Strs[1])*16;
static MCBinaryData * ConvertDoubleToRaw(MC::DoubleList &left_channel, MC::DoubleList &right_channel)
Convert double lists back to raw audio data.
static const int SampleRateOnAIBO
Sample rate for audio processing on AIBO.
MA::LedSkitSPtr LedSkit
Led skit.
void Dump() const
Print the skit content.
std::string Name
Skit name.
static MALedSkit * DecodeLedData(const MCBinaryData &binary_data, const std::string &name)
Load LED sequence from binary data.
MA::MotionSkitSPtr MotionSkit
Motion skit.
std::string Name
Motion name.
MA::LedSkitSPtr GetLedSkit()
Get the LED skit.
#define MC_WARNING(...)
Warning macro.
std::string GetName() const
Get the skit name.
static MAMotionSkit * DecodeMtnData(const MCBinaryData &binary_data)
Load motion sequence from binary data.
MA::SkitSPtr CloneMirrored(const std::string &mirrored_name)
Creates a new skit with mirrored leg joint trajectories between left and right sides.
static MCBinaryData * EncodeMtnToAibFormat(const MCBinaryData &motion_data)
Encode motion data (mtn) to aib format.
int GetAudioStart() const
Get the audio effect start time.
static MC::DoubleList ConvertToDouble(const MCBinaryData &raw_data)
Convert audio data to a double list.
int AudioStart
Audio start time in msec.
static MC::DoubleList Resample(const MC::DoubleList &audio_data, int original_frequency, int new_frequency)
Resample audio data.
Skit class to decode aib format.
MA::MotionSkitSPtr GetMotionSkit()
Get the motion skit.
MC::BinaryDataSPtr SoundData
Sound skit binary data.
static int GetAudioStartFromSkitterInfo(const MCBinaryData &binary_data)
Get the audio effect start from Skitter info format.
int GetAudioDuration() const
Get the audio duration.
int GetDuration() const
Get the skit duration.
MC::BinaryDataSPtr GetSoundData()
Get the sound data.
static MASkit * DecodeAibData(const MCBinaryData &binary_data)
Load a skit from binary data.
unsigned char * GetData() const
Get direct access to the binary data.
A wrapper class to cover boost::thread_specific_ptr/folly::ThreadLocal API on certain targets...
const T MCMax(const U &container)
Get the maximal value of a container.
#define MC_LOG(...)
Debug macro.
int GetSize() const
Get binary data size.