From 58ef3bbc6cf66b9334eef13e7dfbcf3b4a5a0913 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= Date: Fri, 26 Jul 2013 22:52:51 +0300 Subject: [PATCH] doc: remove mad documentation This is the _VLC_ source code. --- doc/mad/API | 262 ----------------------------------------- doc/mad/DESIGN | 63 ---------- doc/mad/joe_drew.txt | 174 --------------------------- doc/mad/rob_leslie.txt | 124 ------------------- 4 files changed, 623 deletions(-) delete mode 100644 doc/mad/API delete mode 100644 doc/mad/DESIGN delete mode 100644 doc/mad/joe_drew.txt delete mode 100644 doc/mad/rob_leslie.txt diff --git a/doc/mad/API b/doc/mad/API deleted file mode 100644 index 83a8731cf5..0000000000 --- a/doc/mad/API +++ /dev/null @@ -1,262 +0,0 @@ -MAD API documentation collected from e-mails of Joe Drew and Rob Leslie. -The original e-mails can be found in the docs directory. They contain the -same information as is presented below. - -INDEX -====== -1. I/O Synchronous Mode -2. Low-level API - - - -1. I/O SYNCHRONOUS MODE (extract from Joe Drew) -=============================================== -MAD operates with callbacks for functions. Each of these functions is -expected to return type enum mad_flow; this allows you to control the -decoding process. - -MAD always outputs 32-bit (well, mad_fixed_t) little-endian data. Take -this into account when outputting samples to the sound card. -Related to the above, since MAD outputs type mad_fixed_t, unless you can -output with 32-bit accuracy (most sound cards can't), you will have to -quantize, round, dither, etc these samples to 16-bit (or whatever you -need.) While there is a sample routine in minimad.c, if you want good -quality you'll either want to roll your own or take a look in madplay's -sources. - -Integral to understanding MAD: MAD is a decoding library only. You -handle input and output; you're responsible for fast-forwarding and -rewinding, if you want that type of functionality. All that MAD will do -is take input from you, decode the MPEG frames, give you some -information about them, and give you the decoded PCM data. - -Now, the nitty-gritty information. - -First, you need a mad_decoder struct. This holds all information about -how you want your stream decoded, such as input/output functions, error -handling functions, etc. - -mad_decoder_init() sets this structure up for you. - -struct mad_decoder decoder; -struct my_playbuf playbuf; - -mad_decoder_init(&decoder, &playbuf, input_func, header_func, /*filter*/ -0, output_func, /*error*/ 0, /* message */ 0); - -In this example, the function called to get more data is set to -input_func, the function called after MPEG headers have been decoded is -header_func, the function called after all sound data has been decoded -to PCM (for output) is output_func, and the filter, error, and message -functions are unset. - -Now, MAD runs in a constant decoding loop. It runs something along the -following lines: - -if I'm out of data - call input_func -if input_func says there's no more data, - quit -decode the header and call header_func -decode the mpeg audio data -call the filter function -call the output function -loop - -Now, this is an oversimplification obviously. The important thing to -realise is that at every step of the process you can tell MAD what to -do. - -Since all of these functions return enum mad_flow, you can tell MAD to -do any of the following: - -enum mad_flow { - MAD_FLOW_CONTINUE = 0x0000, /* Keep decoding this stream */ - MAD_FLOW_STOP = 0x0010, /* Stop decoding this stream, but exit - normally */ - MAD_FLOW_BREAK = 0x0011, /* Stop decoding this stream, and exit - with an error */ - MAD_FLOW_IGNORE = 0x0020 /* Don't decode this frame, - but continue afterwards */ -}; - -Most of the time you'll probably want to return MAD_FLOW_CONTINUE. In -every case, you'll have to return one of these values from the functions -you define. - -This is the definition of each of the functions: - -enum mad_flow (*input_func)(void *, struct mad_stream *); -enum mad_flow (*header_func)(void *, struct mad_header const *); -enum mad_flow (*filter_func)(void *, struct mad_stream const *, struct -mad_frame *); -enum mad_flow (*output_func)(void *, struct mad_header const *, struct -mad_pcm *); -enum mad_flow (*error_func)(void *, struct mad_stream *, struct -mad_frame *); -enum mad_flow (*message_func)(void *, void *, unsigned int *); - -In each of these functions the void* pointer passed to the function is -your "playbuf" structure. This can hold whatever you want - for example, -song title, length, number of frames - just remember to re-cast it to -the type you've defined. - -input_func takes a mad_stream pointer. Most of the time what you'll want -to do is something along the lines of the following: - -if (more_data_available) - buffer = refill_buffer(); - mad_stream_buffer(stream, buffer, length_of_buffer); - return MAD_FLOW_CONTINUE; -else - return MAD_FLOW_STOP; - -(On many systems you'll want to use mmap() for this.) - -header_func takes a mad_header pointer. This contains most of the -important information about a given frame; in constant bitrate files, it -can contain most of the important information about the stream. It will -give you the length of that frame, using mad_timer_t; the audio layer; -extension; bitrate... the list is long. Read frame.h or mad.h in the -frame.h area for more information. -Again, return MAD_FLOW_{CONTINUE,STOP,BREAK} depending on outside -conditions. - -The only other function I have firsthand information on is output_func; -in this case, you are given a pointer to struct mad_pcm. This gives you -the sampling rate, number of channels, and number of samples per -channel; doing something like the following should work: - -mad_fixed_t *left_channel = pcm->samples[0], *right_channel = -pcm->samples[1]; -int nsamples = pcm->length; -signed int sample; -unsigned char * buffer = some_buffer; -unsigned char * ptr = buffer; - -while (nsamples--) -{ - sample = (signed int) do_downsample(*left_ch++) - - *ptr++ = (unsigned char) (sample >> 0); - *ptr++ = (unsigned char) (sample >> 8); - - sample = (signed int) do_downsample(*right_ch++) - - *ptr++ = (unsigned char) (sample >> 0); - *ptr++ = (unsigned char) (sample >> 8); -} - -output buffer to device. - -Be sure to handle the big-endian case (autoconf can test for this), and -also the mono (1 channel) case. See mad.c in mpg321, at the end of the -file, for an example. - -Information on the other (error, filter, message) functions would be -appreciated, though I think in knowing this information anyone should be -able to puzzle it out. - -Now that the decoder is set up with all these callback functions, you -call - -mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC); - -and then - -mad_decoder_finish(&decoder); - -Once you've called mad_decoder_finish, you can re-use the decoder -struct, if you're, for example, within a playlist. Incidentally, all MAD -structures have similar mad_(whatever)_init and mad_(whatever)_finish -functions. - -I hope this helps people get their feet wet with MAD. Read the source, -and particularly mad.h - there are a lot of things there you might not -expect. Rob has done a good job in making MAD a complete solution. :) - - -2. LOW-LEVEL API (extract from Rob Leslie) -========================================== - -By way of clarification, MAD also has a low-level API which does not use -callbacks. You can control the entire decoding process yourself more or less -as follows: - - /* load buffer with your MPEG audio data */ - - mad_stream_buffer(&stream, buffer, buflen); - - while (1) { - mad_frame_decode(&frame, &stream); - mad_synth_frame(&synth, &frame); - - /* output PCM samples in synth.pcm */ - } - -This is vastly simplified, but it shows the general idea. mad_frame_decode() -decodes the next frame's header and subband samples. mad_synth_frame() takes -those subband samples and synthesizes PCM samples. - -It is also possible to call mad_header_decode() before mad_frame_decode(). -This just gives you the frame's header info, in case that's all you want, or -perhaps to help you decide whether you want to decode the rest of the frame. - -As Joe mentions, each of the stream, frame, and synth structs needs to be -initialized and "finished" before and after use: - - struct mad_stream stream; - struct mad_frame frame; - struct mad_synth synth; - - mad_stream_init(&stream); - mad_frame_init(&frame); - mad_synth_init(&synth); - - /* ... */ - - mad_synth_finish(&synth); - mad_frame_finish(&frame); - mad_stream_finish(&stream); - -You can work with just a struct mad_header instead of a struct mad_frame if -you only want to decode frame headers. - -Joe writes: -> MAD always outputs 32-bit (well, mad_fixed_t) little-endian data. Take -> this into account when outputting samples to the sound card. - -This isn't quite right: the mad_fixed_t type is not necessarily little-endian. -It's the same endianness as the native integer types. Also, it's only -guaranteed to be *at least* 32 bits wide. - -The fixed-point sample format is important to understand, and I recommend -reading the comments in libmad/fixed.h. The thing to remember when converting -MAD's fixed-point integer samples to 16-bit PCM (or whatever) is that MAD -encodes samples as numbers in the full-scale range [-1.0, +1.0) where the -binary point is placed 28 (MAD_F_FRACBITS) bits to the left of the integer. -However, you need to be prepared to handle clipping as some numbers may be -less than -1.0 (-MAD_F_ONE) or greater than or equal to +1.0 (MAD_F_ONE, aka -1 << MAD_F_FRACBITS). - -> Information on the other (error, filter, message) functions would be -> appreciated, though I think in knowing this information anyone should be -> able to puzzle it out. - -In the high-level API, the error callback function is called whenever a -decoding error occurs. The error number is in stream->error. - -The filter callback function is called after decoding a frame, but before -synthesis. Here it is possible to modify the frame's subband samples, for -example to perform a uniform attenuation/amplification, or to do other special -processing in the frequency domain. - -The message callback function is only used with MAD_DECODER_MODE_ASYNC, and is -called whenever the parent process sends a message via mad_decoder_message(). -This callback can generate a reply by overwriting the message buffer that is -passed to it. (The size of the reply must be the same or smaller than the -message.) - - - - diff --git a/doc/mad/DESIGN b/doc/mad/DESIGN deleted file mode 100644 index 637def8c5e..0000000000 --- a/doc/mad/DESIGN +++ /dev/null @@ -1,63 +0,0 @@ -File: Plugin mad for vlc is based upon libmad from the mad distribution. -Author: Jean-Paul Saman - -Directories: -============ -vlc/plugins/mad : mad audio decoder plugin for vlc - -Interface functions -=================== -The following interface functions are implemented in the mad plugin. - -decoder_Probe : vlc probes for plugin capabilities -decoder_Run : vlc starts a decoder plugin by calling this function -InitThread : routine to do some initializations -EndThread : cleanup function - -The following functions are callback functions for the mad decoder library: - -libmad_input : called when input data is needed -libmad_output : called whenever a frame has been decoded -libmad_header : called upon decoding of only a frame header -libmad_messages : libmad messages -libmad_error : called whenever an error occurred during the decoding process - -Design: (ASCII art) -======= -It represents the function call flow viewed from the vlc main program. The main program is in charge of allocating decoders, -initializing, starting and stopping them. - - --------------- - | | - | libmad | - --------------- - ^ - | - --------------- - | | - | mad | - _______________ - ^ - | - ________________________ - | | - | vlc plugin interface | - ________________________ - - -Interface view: -=============== - [mad decoder plugin] - ---------------------- - vlc decoder interface -> | mad_adec mad_libmad | -> libmad - ----------------------- - -Rationel: -======== -Keeping libmad as a separate library on the system, either dynamic or statically linked in, makes maintenance so much simpeler. -Merging with a new libmad version should be straight forward as long as the interface stays stable. -There is another benefit: Disk (actually flash ROM) resources and memory are very limited on a iPaq. -Other programs or utilities like madplay and BBplay can make use of the same libmad version we do. In this way -limiting the needed storage place on disk (flash ROM). Also this is only possible when the interface stays the same. - - diff --git a/doc/mad/joe_drew.txt b/doc/mad/joe_drew.txt deleted file mode 100644 index 97dbab90d0..0000000000 --- a/doc/mad/joe_drew.txt +++ /dev/null @@ -1,174 +0,0 @@ -Subject: [mad-dev] Some information about programming with MAD (in synchronous mode) - -As the author of mpg321, I too faced the problem of MAD not being -documented. However, in looking at minimad.c, and re-writing mpg321 to -use MAD, I came to understand it better. Here's some information which -will help anybody start out with MAD: - -First, some basic information. -MAD operates with callbacks for functions. Each of these functions is -expected to return type enum mad_flow; this allows you to control the -decoding process. -MAD always outputs 32-bit (well, mad_fixed_t) little-endian data. Take -this into account when outputting samples to the sound card. -Related to the above, since MAD outputs type mad_fixed_t, unless you can -output with 32-bit accuracy (most sound cards can't), you will have to -quantize, round, dither, etc these samples to 16-bit (or whatever you -need.) While there is a sample routine in minimad.c, if you want good -quality you'll either want to roll your own or take a look in madplay's -sources. -Integral to understanding MAD: MAD is a decoding library only. You -handle input and output; you're responsible for fast-forwarding and -rewinding, if you want that type of functionality. All that MAD will do -is take input from you, decode the MPEG frames, give you some -information about them, and give you the decoded PCM data. - -Now, the nitty-gritty information. - -First, you need a mad_decoder struct. This holds all information about -how you want your stream decoded, such as input/output functions, error -handling functions, etc. - -mad_decoder_init() sets this structure up for you. - -struct mad_decoder decoder; -struct my_playbuf playbuf; - -mad_decoder_init(&decoder, &playbuf, input_func, header_func, /*filter*/ -0, output_func, /*error*/ 0, /* message */ 0); - -In this example, the function called to get more data is set to -input_func, the function called after MPEG headers have been decoded is -header_func, the function called after all sound data has been decoded -to PCM (for output) is output_func, and the filter, error, and message -functions are unset. - -Now, MAD runs in a constant decoding loop. It runs something along the -following lines: - -if I'm out of data - call input_func -if input_func says there's no more data, - quit -decode the header and call header_func -decode the mpeg audio data -call the filter function -call the output function -loop - -Now, this is an oversimplification obviously. The important thing to -realise is that at every step of the process you can tell MAD what to -do. - -Since all of these functions return enum mad_flow, you can tell MAD to -do any of the following: - -enum mad_flow { - MAD_FLOW_CONTINUE = 0x0000, /* Keep decoding this stream */ - MAD_FLOW_STOP = 0x0010, /* Stop decoding this stream, but exit - normally */ - MAD_FLOW_BREAK = 0x0011, /* Stop decoding this stream, and exit - with an error */ - MAD_FLOW_IGNORE = 0x0020 /* Don't decode this frame, - but continue afterwards */ -}; - -Most of the time you'll probably want to return MAD_FLOW_CONTINUE. In -every case, you'll have to return one of these values from the functions -you define. - -This is the definition of each of the functions: - -enum mad_flow (*input_func)(void *, struct mad_stream *); -enum mad_flow (*header_func)(void *, struct mad_header const *); -enum mad_flow (*filter_func)(void *, struct mad_stream const *, struct -mad_frame *); -enum mad_flow (*output_func)(void *, struct mad_header const *, struct -mad_pcm *); -enum mad_flow (*error_func)(void *, struct mad_stream *, struct -mad_frame *); -enum mad_flow (*message_func)(void *, void *, unsigned int *); - -In each of these functions the void* pointer passed to the function is -your "playbuf" structure. This can hold whatever you want - for example, -song title, length, number of frames - just remember to re-cast it to -the type you've defined. - -input_func takes a mad_stream pointer. Most of the time what you'll want -to do is something along the lines of the following: - -if (more_data_available) - buffer = refill_buffer(); - mad_stream_buffer(stream, buffer, length_of_buffer); - return MAD_FLOW_CONTINUE; -else - return MAD_FLOW_STOP; - -(On many systems you'll want to use mmap() for this.) - -header_func takes a mad_header pointer. This contains most of the -important information about a given frame; in constant bitrate files, it -can contain most of the important information about the stream. It will -give you the length of that frame, using mad_timer_t; the audio layer; -extension; bitrate... the list is long. Read frame.h or mad.h in the -frame.h area for more information. -Again, return MAD_FLOW_{CONTINUE,STOP,BREAK} depending on outside -conditions. - -The only other function I have firsthand information on is output_func; -in this case, you are given a pointer to struct mad_pcm. This gives you -the sampling rate, number of channels, and number of samples per -channel; doing something like the following should work: - -mad_fixed_t *left_channel = pcm->samples[0], *right_channel = -pcm->samples[1]; -int nsamples = pcm->length; -signed int sample; -unsigned char * buffer = some_buffer; -unsigned char * ptr = buffer; - -while (nsamples--) -{ - sample = (signed int) do_downsample(*left_ch++) - - *ptr++ = (unsigned char) (sample >> 0); - *ptr++ = (unsigned char) (sample >> 8); - - sample = (signed int) do_downsample(*right_ch++) - - *ptr++ = (unsigned char) (sample >> 0); - *ptr++ = (unsigned char) (sample >> 8); -} - -output buffer to device. - -Be sure to handle the big-endian case (autoconf can test for this), and -also the mono (1 channel) case. See mad.c in mpg321, at the end of the -file, for an example. - -Information on the other (error, filter, message) functions would be -appreciated, though I think in knowing this information anyone should be -able to puzzle it out. - -Now that the decoder is set up with all these callback functions, you -call - -mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC); - -and then - -mad_decoder_finish(&decoder); - -Once you've called mad_decoder_finish, you can re-use the decoder -struct, if you're, for example, within a playlist. Incidentally, all MAD -structures have similar mad_(whatever)_init and mad_(whatever)_finish -functions. - -I hope this helps people get their feet wet with MAD. Read the source, -and particularly mad.h - there are a lot of things there you might not -expect. Rob has done a good job in making MAD a complete solution. :) - --- -Joe Drew - -Please encrypt email sent to me. diff --git a/doc/mad/rob_leslie.txt b/doc/mad/rob_leslie.txt deleted file mode 100644 index fbe49e4848..0000000000 --- a/doc/mad/rob_leslie.txt +++ /dev/null @@ -1,124 +0,0 @@ -From - Mon Nov 5 09:19:09 2001 -Return-Path: -Received: from smtp01.wxs.nl ([195.121.5.15]) by po05.wxs.nl - (Netscape Messaging Server 4.15) with ESMTP id GLLMFJ00.3DF for - ; Mon, 22 Oct 2001 10:33:19 +0200 -Received: from surveyor.mars.org ([216.98.134.66]) by - smtp01.wxs.nl (Netscape Messaging Server 4.15) with ESMTP id - GLLMFZ00.C2Z for ; Mon, 22 Oct 2001 10:33:35 +0200 -Received: from surveyor.mars.org (localhost [127.0.0.1]) - by surveyor.mars.org (8.9.3/8.9.3/Debian 8.9.3-21) with ESMTP id BAA07654; - Mon, 22 Oct 2001 01:32:07 -0700 -Received: from mars.org (localhost [127.0.0.1]) - by surveyor.mars.org (8.9.3/8.9.3/Debian 8.9.3-21) with ESMTP id BAA07629 - for ; Mon, 22 Oct 2001 01:31:30 -0700 -Message-Id: <200110220831.BAA07629@surveyor.mars.org> -X-Authentication-Warning: surveyor.mars.org: Host localhost [127.0.0.1] claimed to be mars.org -From: Rob Leslie -To: mad-dev@lists.mars.org -Subject: Re: [mad-dev] Some information about programming with MAD (in synchronous mode) -In-reply-to: Your message of "21 Oct 2001 16:13:19 EDT." - <1003695199.24019.56.camel@pisces> -Mime-Version: 1.0 (generated by tm-edit 7.106) -Content-Type: text/plain; charset=US-ASCII -Sender: mad-dev-admin@lists.mars.org -Errors-To: mad-dev-admin@lists.mars.org -X-BeenThere: mad-dev@lists.mars.org -X-Mailman-Version: 2.0.1 -Precedence: bulk -List-Help: -List-Post: -List-Subscribe: , - -List-Id: MAD developer's mailing list -List-Unsubscribe: , - -List-Archive: -Date: Mon, 22 Oct 2001 01:31:30 -0700 -X-Mozilla-Status: 8011 -X-Mozilla-Status2: 00000000 -X-UIDL: 1879-1001307689 - -Joe Drew wrote some good info on the MAD high-level API that I hope will be -helpful to others. - -By way of clarification, MAD also has a low-level API which does not use -callbacks. You can control the entire decoding process yourself more or less -as follows: - - /* load buffer with your MPEG audio data */ - - mad_stream_buffer(&stream, buffer, buflen); - - while (1) { - mad_frame_decode(&frame, &stream); - mad_synth_frame(&synth, &frame); - - /* output PCM samples in synth.pcm */ - } - -This is vastly simplified, but it shows the general idea. mad_frame_decode() -decodes the next frame's header and subband samples. mad_synth_frame() takes -those subband samples and synthesizes PCM samples. - -It is also possible to call mad_header_decode() before mad_frame_decode(). -This just gives you the frame's header info, in case that's all you want, or -perhaps to help you decide whether you want to decode the rest of the frame. - -As Joe mentions, each of the stream, frame, and synth structs needs to be -initialized and "finished" before and after use: - - struct mad_stream stream; - struct mad_frame frame; - struct mad_synth synth; - - mad_stream_init(&stream); - mad_frame_init(&frame); - mad_synth_init(&synth); - - /* ... */ - - mad_synth_finish(&synth); - mad_frame_finish(&frame); - mad_stream_finish(&stream); - -You can work with just a struct mad_header instead of a struct mad_frame if -you only want to decode frame headers. - -Joe writes: -> MAD always outputs 32-bit (well, mad_fixed_t) little-endian data. Take -> this into account when outputting samples to the sound card. - -This isn't quite right: the mad_fixed_t type is not necessarily little-endian. -It's the same endianness as the native integer types. Also, it's only -guaranteed to be *at least* 32 bits wide. - -The fixed-point sample format is important to understand, and I recommend -reading the comments in libmad/fixed.h. The thing to remember when converting -MAD's fixed-point integer samples to 16-bit PCM (or whatever) is that MAD -encodes samples as numbers in the full-scale range [-1.0, +1.0) where the -binary point is placed 28 (MAD_F_FRACBITS) bits to the left of the integer. -However, you need to be prepared to handle clipping as some numbers may be -less than -1.0 (-MAD_F_ONE) or greater than or equal to +1.0 (MAD_F_ONE, aka -1 << MAD_F_FRACBITS). - -> Information on the other (error, filter, message) functions would be -> appreciated, though I think in knowing this information anyone should be -> able to puzzle it out. - -In the high-level API, the error callback function is called whenever a -decoding error occurs. The error number is in stream->error. - -The filter callback function is called after decoding a frame, but before -synthesis. Here it is possible to modify the frame's subband samples, for -example to perform a uniform attenuation/amplification, or to do other special -processing in the frequency domain. - -The message callback function is only used with MAD_DECODER_MODE_ASYNC, and is -called whenever the parent process sends a message via mad_decoder_message(). -This callback can generate a reply by overwriting the message buffer that is -passed to it. (The size of the reply must be the same or smaller than the -message.) - -Cheers, - -rob