ALACSink::ALACSink(const std::wstring &path, EncoderBase &encoder) : m_mp4file(0), m_filename(path), m_closed(false) { static const char * const compatibleBrands[] = { "M4A ", "mp42" }; const AudioStreamBasicDescription &format = encoder.getOutputBasicDescription(); uint32_t sample_rate = static_cast<uint32_t>(format.mSampleRate); try { m_mp4file.Create( w2m(path, utf8_codecvt_facet()).c_str(), 0, // flags 1, // add_ftypes 0, // add_iods "M4A ", // majorBrand 0, // minorVersion const_cast<char**>(compatibleBrands), array_size(compatibleBrands)); m_mp4file.SetTimeScale(sample_rate); std::vector<char> cookie; encoder.getMagicCookie(&cookie); m_track_id = m_mp4file.AddAlacAudioTrack(sample_rate, reinterpret_cast<uint8_t*>(&cookie[20]), cookie.size() - 28); } catch (mp4v2::impl::MP4Error *e) { handle_mp4error(e); } }
int wmain1(int argc, wchar_t **argv) { utf8_codecvt_facet codec; std::vector<std::string> args; std::vector<char*> cargs; for (int i = 0; i < argc; ++i) args.push_back(w2m(argv[i], codec)); for (std::vector<std::string>::const_iterator ii = args.begin(); ii != args.end(); ++ii) cargs.push_back(const_cast<char*>(ii->c_str())); cargs.push_back(0); return main1(argc, &cargs[0]); }
FLACSink::FLACSink(FILE *fp, uint64_t duration, const SampleFormat &fmt, const FLACModule &module, const std::map<uint32_t, std::wstring> &tags) :m_fp(fp), m_module(module), m_format(fmt) { if (fmt.m_type == SampleFormat::kIsFloat) throw std::runtime_error("Can't handle float source"); if (fmt.m_endian == SampleFormat::kIsBigEndian) throw std::runtime_error("Can't handle big endian source"); m_encoder.swap(encoder_t(m_module.stream_encoder_new(), std::bind1st(std::mem_fun(&FLACSink::closeEncoder), this))); TRYFL(m_module.stream_encoder_set_channels( m_encoder.get(), fmt.m_nchannels)); TRYFL(m_module.stream_encoder_set_bits_per_sample( m_encoder.get(), fmt.m_bitsPerSample)); TRYFL(m_module.stream_encoder_set_sample_rate( m_encoder.get(), fmt.m_rate)); TRYFL(m_module.stream_encoder_set_total_samples_estimate( m_encoder.get(), duration)); TRYFL(m_module.stream_encoder_set_compression_level( m_encoder.get(), 5)); FLAC__StreamMetadata *meta[2]; meta[0] = m_module.metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT); meta[1] = m_module.metadata_object_new(FLAC__METADATA_TYPE_PADDING); meta[1]->length = 0x1000; m_metadata_holder[0].swap( metadata_t(meta[0], m_module.metadata_object_delete)); m_metadata_holder[1].swap( metadata_t(meta[1], m_module.metadata_object_delete)); { FLAC__StreamMetadata_VorbisComment_Entry entry; std::map<uint32_t, std::wstring>::const_iterator ii; utf8_codecvt_facet u8codec; for (ii = tags.begin(); ii != tags.end(); ++ii) { const char *key = GetNameFromTagID(ii->first); if (!key) continue; std::string value = w2m(ii->second, u8codec); m_module.metadata_object_vorbiscomment_entry_from_name_value_pair( &entry, key, value.c_str()); m_module.metadata_object_vorbiscomment_append_comment( meta[0], entry, false); } } m_module.stream_encoder_set_metadata(m_encoder.get(), meta, 2); TRYFL(m_module.stream_encoder_init_stream(m_encoder.get(), staticWriteCallback, 0, 0, 0, this) == FLAC__STREAM_ENCODER_INIT_STATUS_OK); }
int main() { /*使用wcstombs和mbstowcs之前必须调用setlocale,以便决定内码*/ setlocale(LC_ALL,"zh_CN.utf8"); //默认设置为utf8,即转换为utf8的多字节 /*假定有一个Unicode(UTF-16LE)编码的文件,将其打开,重新编码为ANSI ,写入aa.txt中,再继续编码回Unicode,写入aw.txt中*/ /*如果不存在a.txt文件,则程序出错,没有做错误处理*/ char* filename = "text.file.uni"; char* filenamea = "aa.txt"; char* filenamew = "aw.txt"; FILE* input=fopen( filename, "rb"); FILE* inputa=fopen( filenamea, "wb"); FILE* inputw=fopen( filenamew, "wb"); /*BOE设置,UTF-16LE的BOE为FEFF,如果不先将其读取出来,wcstombs会调用失败*/ unsigned short BOM ; fread(&BOM,sizeof(unsigned short),1,input); fwrite(&BOM,sizeof(unsigned short),1,inputw); unsigned short word = 0; unsigned short *buffer = (unsigned short *)malloc(sizeof(unsigned short)*BUFF_SIZE); unsigned short *pBuffer = buffer; printf("%d\n",sizeof(wchar_t)); int count = 0; /*开始读取文件*/ while((count=readUnicodeLine(buffer,BUFF_SIZE,input))!=-1) { if(count>0){ //当前行有数据 char *buf = w2m(buffer); printf("%s\n",buf); fprintf(inputa,"%s\n",buf); int len; wchar_t * bufWideChar = m2w(buf,&len); fwrite(buffer,sizeof(wchar_t),count,inputw); free(bufWideChar); free(buf); } } /*后续处理*/ free(buffer); fclose(input); fclose(inputa); fclose(inputw); return 0; }
ALACSource::ALACSource(const std::wstring &path) : m_position(0) { try { m_file.Read(w2m(path, utf8_codecvt_facet()).c_str(), 0); m_track_id = m_file.FindTrackId(0, MP4_AUDIO_TRACK_TYPE); const char *type = m_file.GetTrackMediaDataName(m_track_id); if (std::strcmp(type, "alac")) throw std::runtime_error("Not an ALAC file"); const char *alacprop, *chanprop; const char *brand = m_file.GetStringProperty("ftyp.majorBrand"); if (!std::strcmp(brand, "qt ")) { // throw std::runtime_error("Not supported format"); alacprop = "mdia.minf.stbl.stsd.alac.wave.alac.decoderConfig"; chanprop = "mdia.minf.stbl.stsd.alac.wave.chan.data"; } else { alacprop = "mdia.minf.stbl.stsd.alac.alac.decoderConfig"; chanprop = "mdia.minf.stbl.stsd.alac.chan.data"; } std::vector<uint8_t> alac, chan; uint8_t *value; uint32_t size; m_file.GetTrackBytesProperty(m_track_id, alacprop, &value, &size); std::copy(value + 4, value + size, std::back_inserter(alac)); MP4Free(value); value = 0; try { m_file.GetTrackBytesProperty(m_track_id, chanprop, &value, &size); std::copy(value + 4, value + size, std::back_inserter(chan)); MP4Free(value); } catch (...) {} if (alac.size() != 24 || (chan.size() && chan.size() < 12)) throw std::runtime_error("ALACSource: invalid magic cookie"); std::memset(&m_format, 0, sizeof m_format); m_format.m_type = SampleFormat::kIsSignedInteger; m_format.m_endian = SampleFormat::kIsLittleEndian; m_format.m_nchannels = alac[9]; m_format.m_bitsPerSample = alac[5]; if (m_format.m_bitsPerSample == 20) m_format.m_bitsPerSample = 24; uint32_t timeScale; std::memcpy(&timeScale, &alac[20], 4); timeScale = b2host32(timeScale); m_format.m_rate = timeScale; AudioChannelLayout acl = { 0 }; if (chan.size()) { fourcc tag(reinterpret_cast<const char*>(&chan[0])); fourcc bitmap(reinterpret_cast<const char*>(&chan[4])); acl.mChannelLayoutTag = tag; acl.mChannelBitmap = bitmap; chanmap::GetChannels(&acl, &m_chanmap); } m_decoder = x::shared_ptr<ALACDecoder>(new ALACDecoder()); CHECKCA(m_decoder->Init(&alac[0], alac.size())); setRange(0, m_file.GetTrackDuration(m_track_id)); mp4a::fetchTags(m_file, &m_tags); } catch (mp4v2::impl::Exception *e) { handle_mp4error(e); } }