1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
/*
Audio.Codec object
creator: Honza Petrous, hop@unibase.cz
*/
#pike __REAL_VERSION__
mapping codec_map = ([
#if constant(_Ffmpeg.ffmpeg1)
"MP3": ([ "encoder": 0,
"decoder": ({ "_Ffmpeg.ffmpeg", _Ffmpeg.CODEC_ID_MP3LAME })
]),
"WAV": ([ "encoder": ({ "_Ffmpeg.ffmpeg", _Ffmpeg.CODEC_ID_PCM_S16LE }),
"decoder": ({ "_Ffmpeg.ffmpeg", _Ffmpeg.CODEC_ID_PCM_S16LE })
])
#endif
]);
#if constant(_Ffmpeg.ffmpeg)
//! Decoder object.
//!
//! @note
//! It needs @[_Ffmpeg.ffmpeg] module for real work.
class decoder {
/*private*/ object codec;
/*private*/ Audio.Format.ANY infile;
//! Creates decoder object
//!
//! @param codecnum
//! Some of supported codec, like _Ffmpeg.CODEC_ID_*
//!
//! @param _codec
//! The low level object will be used for decoder.
//! By default @[_Ffmpeg.ffmpeg] object will be used.
//!
//! @note
//! Until additional library is implemented the second
//! parameter @[_codec] hasn't effect.
//!
//! @seealso
//! @[_Ffmpeg.ffmpeg], @[_Ffmpeg.CODEC_ID_MP2]
protected void create(string|void codecname, object|void _codec) {
if(stringp(codecname))
init(codecname);
}
private this_program init(string codecname) {
mixed err;
string cn = upper_case(codecname);
#if 0
if(!has_index(codec_map, cn) || !codec_map[cn]->decoder)
error("Decoder codec '"+codecname+"' isn't supported.\n");
err = catch(codec = _Ffmpeg.ffmpeg(codec_map[cn]->decoder[1], 0));
#else
foreach(Array.filter(_Ffmpeg.list_codecs(), lambda(mapping m, string n) { return m->name == n; }, codecname), mapping fc)
if(!fc->encoder_flg &&
#if constant(_Ffmpeg.AVMEDIA_TYPE_AUDIO)
fc->type == _Ffmpeg.AVMEDIA_TYPE_AUDIO
#else
fc->type == _Ffmpeg.CODEC_TYPE_AUDIO
#endif
) {
err = catch(codec = _Ffmpeg.ffmpeg(fc->id, 0));
break;
}
#endif
if(err)
error(err[0]);
return this;
}
//! Set codec type from file
//!
//! It uses @[Audio.Format.ANY]'s method get_map()
//! to determine which codec should be used.
//!
//! @param file
//! The object @[Audio.Format.ANY].
this_program from_file(Audio.Format.ANY file) {
string ctype;
if(objectp(file) && file->get_map)
ctype = file->get_map()->codec_type;
if(stringp(ctype)) {
infile = file;
return init(ctype);
}
return 0;
}
//! Decodes audio data
//!
//! @param partial
//! Only one frame will be decoded per call.
//!
//! @returns
//! If successfull a mapping with decoded data and byte number
//! of used input data is returned, @tt{0@} otherwise.
mapping|int decode(int|void partial) {
return codec->decode(infile->get_data()); //, partial);
}
//! Returns decoder status
//!
mapping get_status() {
return codec && codec->get_codec_status();
}
protected mixed _sprintf(int|void type) {
return type=='O' && sprintf("Audio.Codec(/* %O */)", codec);
}
}
#endif
|