Andreas Schulz wrote:
> OK, here we go..

Sorry this too me so long to get to.

> This is against the CVS as of today (26.04.2009).
> In contrast to my first approach, there is now a module
> prontocodes that is statically linked to concordance and
> provides just the basic stuff to convert pronto hex codes.

I'm not super fond of this approach. Is there a reason not to have it be a
library? You prevent congruity from having this functionality.

I think it might be nice to be able to have a file of pronto hex codes (my
limited understanding is that this is common), so we may want to have a "-L
pronto.txt -P" type invocation that will read from a file and learn all codes.

Given such a use-case I can see congruity wanting to support this. And I
don't know if there's a generic pronto open source library out there, but it
might be nice to provide one.

> It will only accept raw modulated hex format, i.e. Pronto
> codes starting with 0000 ....
> The complete hex code must be input as a single line of 
> hexadecimal words, separated by blanks (which seems to be 
> the usual format of these codes), without any number base 
> markers (like 0x.... or h....), just like:
> 0000 1234 5678 9ABC DEF0 ....

It would be nice to allow 0x versions.

> See attachments for the patch to concordance (concordance-pronto.patch)
> and the additional static library prontocodes.h/.c.

I've included my code review below. Nothing too major, but tons of style
things, and a few cleanups, and one or two things I didn't follow. A few
more general things though:

- Please add documentation. You don't include anything in the README or in
the man page
- Is this tested on both windows and linux?
- In future version, please make a patch that includes the new files ("diff
-Nru" will include new files)

protocodes.h

> #ifndef PRONTOCODES_H
> #define PRONTOCODES_H
>
> #ifndef uint32_t
> #define uint32_t unsigned int
> #endif

Why is this necessary?

>
> /*
>  * return codes:
>  */
> #define PCO_RETURN_OK         0
> #define PCO_ERROR_BAD_CODE    1  /* could not find all required values */
> #define PCO_ERROR_OUTOFMEM    2  /* failed to malloc returned arrays */
> #define PCO_ERROR_NOT_IMPL   11  /* not yet implemented */

Why the skip?

> /*
>  * Translate a return value into an actual error message. Pass
>  * in the int you received, get back a string.
>  */
> const char *pco_strerror(int err);

Can your prefix be pcodes_ ?

Or, if you make a shared library, lpc_


>
> /*
>  * Native Pronto code data structure. For raw format, once/repeat_signal
>  * contain word pairs for mark/space durations (in carrier clock cycles).
>  *
>  * Note: the internal Pronto format header counts mark/space pairs; for
>  *       convenience, we count total marks + spaces instead , i.e. twice
>  *       the Pronto counts.
>  *
>  * For decoded formats, format_id determines the encoding and once/
>  * repeat_signal contain the corresponding address/command codes
>  * (or whatever data is needed for the specific encoding):
>  * For reference, the original names from Evgueni's document have
>  * been added in brackets <>:
>  *
>  * format_id             <wFmtId>:
>  *                       determines format (raw or several decoded)
>  * carrier_clock_divider <wFrqDiv>:
>  *                       IR carrier clock in internal units
>  * once_signal_length    <nOnceSeq>:
>  *                       length of once_signal (total of marks+spaces ->
> even number)
>  * repeat_signal_length  <nRepeatSeq>:
>  *                       length of repeat_signal (total of marks+spaces ->
> even number)
>  * *once_signal          *<OncePulses>:
>  *                       sequence to send once for command execution
>  * *repeat_signal        *<RepeatPulses>:
>  *                       sequence to send repeatedly for command repetition
>  */

Please ensure your lines are <=80 chars.


> /*
>  * Read from string:
>  * Allocates memory for once/repeat_signal in result, caller is responsible
>  * for deallocation.
>  */

Line-length.

prontocodes.c


> #define PRONTO_FMTID_RAW_MOD    0x0000 /* – raw oscillated code (with
> carrier) */
> #define PRONTO_FMTID_RAW_UNMOD  0x0100 /* – raw unmodulated code (no
carrier) */

line-length

> /*
>  * - predefined formats:
>  */
> #define PRONTO_FMTID_UDB_INDEX  0x8000 /* – index to UDB */
>       /* - variable length: */

beginning of line, please.

> #define PRONTO_FMTID_VAR_PREDEF 0x7000 /* – predefined code of variable
> length */
>       /* - fixed length: */

Same.

I would remove the "- " from the first "predefined formats" line, so that
these to will stick out to the right with the "- ", since that seems to be
your goal. But please don't indent the comments.

> /*
>  * Translate a return value into an actual error message. Pass in the int
>  * you received, get back a string.
>  */
>
> const char *pco_strerror(int err)

Remove blank line, please.

> {
>       switch (err) {
>               case PCO_RETURN_OK:
>               return "Success";

Extra indent, please.

>               break;
>               case PCO_ERROR_BAD_CODE:
>               return "Bad Pronto Hex format";

Same.

>               break;
>               case PCO_ERROR_OUTOFMEM:
>               return "Memory allocation failed";

Same.

>               break;
>               case PCO_ERROR_NOT_IMPL:
>               return "Function not yet implemented";

Same.

> /*
>  * read a hex word from source string:
>  */
>
> int _get_hex_word(char **a_string, char *string_end, uint32_t *result)

No blank line, please.

> {
>       int chars_read;
>       int err = 0;
>       if (*a_string <= string_end) {
>               err = sscanf(*a_string, "%4x%n", result, &chars_read);
>               if (err == 1) {

You probably want if err != -1. My understanding of %n is that you cannot
rely on it to not increment the "number of matched items." So really you
want to make sure you didn't err.


> /*
>  * read from string:
>  */
> int pco_sscanf_pronto_code(char *hex_string,
>              struct pco_pronto_code *pronto_code)
> {
>       char *hs_cursor = hex_string;
>       char *hs_end    = hex_string + strlen(hex_string) - 1;
>       uint32_t next_word;
>       uint32_t index = 0;

This is only used as a loop counter, please define it in those loops.

>
>       /* hex_string contains blank-separated 4-digit hex numbers */
>       if (_get_hex_word(&hs_cursor, hs_end, &next_word) != 1 ) {

No trailing space please. I'll just point this out here and let you fix all
of them.

>       /*
>        * following are lengths of once_signal and repeat_signal, counting
>        * mark/space duration pairs. We multiply them by 2 to store the total
>        * number of durations (marks + spaces) for each code:
>        */

Line-lengths.


>       /* allocate memory for sequences: */
>       if (pronto_code->once_signal_length > 0) {
>               pronto_code->once_signal   =
>                      calloc(pronto_code->once_signal_length, 
> sizeof(uint32_t));

Line-length.

>       }
>       if (pronto_code->repeat_signal_length > 0) {
>               pronto_code->repeat_signal =
>                      calloc(pronto_code->repeat_signal_length, 
> sizeof(uint32_t));

Line length.

>       }
>       for (index = 0; index < pronto_code->once_signal_length; index ++) {

index++.

Does "index ++" even compile?

>               if (_get_hex_word(&hs_cursor, hs_end, &next_word) != 1 ) {
>               return PCO_ERROR_BAD_CODE;

Extra indent.

>               }
>               pronto_code->once_signal[index] = next_word;
>       }
>       
>       for (index = 0; index < pronto_code->repeat_signal_length; index ++) {
>               if (_get_hex_word(&hs_cursor, hs_end, &next_word) != 1 ) {
>               return PCO_ERROR_BAD_CODE;

Extra indent.

>               }
>               pronto_code->repeat_signal[index] = next_word;
>       }
>       return PCO_RETURN_OK;
> }
>
> /*
>  * Conversion between different kinds of Pronto codes and IR signal streams:
>  */

Line-length.


> int _convert_raw_mod(struct pco_pronto_code source, uint32_t carrier_cycle,
>       uint32_t repetitions, uint32_t **ir_signal, uint32_t *ir_signal_length)
> {
>       uint32_t source_index = 0;

This is only used in the for loop below, so please define it there.

>       uint32_t ir_signal_index = 0;
>       uint32_t repeat_count = 0;

Please define repeat_count in the loop it's used in.

Please define ir_signal_index just before the first loop it's in. Normally I
wouldn't care so much about that one, but it'll make it more obvious there
are two counters in that loop which is otherwise a bit confusing.

>
>       /* basic validity check : */
>       if (((source.once_signal_length > 0) && (source.once_signal == NULL)) ||
>               ((source.repeat_signal_length > 0) && (source.repeat_signal == 
> NULL)) ||


Line-length.

>       /*
>        * alternating pairs of uint32_t wLEDflash, uint32_t wLEDoff in units
>        * of carrier cycles: just convert to microseconds and copy to 
> ir_signal:
>        */

Line-length.

>
>       /*
>        * add OnceSeq:
>        */
>       for ( source_index = 0; source_index < source.once_signal_length;
> source_index++ ) {

No head/tail space. Line-length.

>       /*
>        * add RepeatSeq as many times as requested:
>        */
>       for ( repeat_count = repetitions; repeat_count > 0; repeat_count-- ) {
>               for ( source_index = 0; source_index < 
> source.repeat_signal_length;
> source_index++ ) {

No head/tail space. Line-length.

>                       (*ir_signal)[ir_signal_index++] =
>                               carrier_cycle * 
> source.repeat_signal[source_index];
>               }
>       }
>       return PCO_RETURN_OK;

Line-length.

> int _convert_nec_0(struct pco_pronto_code source, uint32_t carrier_cycle,
>       uint32_t repetitions, uint32_t **ir_signal, uint32_t *ir_signal_length)
> {
> /*    uint32_t mark_cycles    = 0;
>       uint32_t space_cycles    = 0;
> */
>       return PCO_ERROR_BAD_CODE;
> } /* convert_nec_0 */

Please use a more verbose name, or at least add a good comment. What's nec?

Also, this function does nothing... why?


> /*
>  * decode Pronto format to ir signal stream and carrier clock.
>  * repetitions determines the repetitions of repeat_signal
>  * part of the pronto code - 0 means that repeat_signal is
>  * not included at all.
>  */
> int pco_pronto_to_ir_signal(
>       struct pco_pronto_code source, uint32_t repetitions,

the first parameter can fit on the first line.

>       /*
>        * convert carrier freq from Pronto cycles to Hz and µs:
>        */
>       if (source.carrier_clock_divider != 0 ) {
>               *carrier_freq = PRONTO_CLOCK/source.carrier_clock_divider;
>               carrier_cycle = 1000000/(*carrier_freq);    /* in

Please use spaces before/after the math operators.

Please put the comment on the line above, but itself. That's (a) the
preferred style in concordance and (b) will keep it from line wrapping.

> microseconds */
>       }
>
>       switch (source.format_id) {
>       case PRONTO_FMTID_RAW_MOD: /* learned (raw) cmds */
>               err = _convert_raw_mod(source, carrier_cycle, repetitions, 
> ir_signal,
> ir_signal_length);
>               break;

In general, I prefer this indentation-style of switch-statements, but it's
not what our codebase uses, so please conform.

Also, you have significant line-length issues.


>
>       case PRONTO_FMTID_RAW_UNMOD:
>               /*
>                * basically the same as raw_mod, just no modulation with 
> carrier.
>                * Replacing dummy carrier from Pronto format ; on/off times are
>                * still multiples of (dummy) carrier cycles in pronto code:
>                */
>               *carrier_freq = 0;
>               err = _convert_raw_mod(source, carrier_cycle, repetitions, 
> ir_signal,
> ir_signal_length);


I don't quite follow. If the carrier_freq is dummy in this case, then
doesn't carrier_cycle not make any sense the way you calculated it above?

Also, line-length.


>               break;
>       /*
>        * Predefined formats have different structure, but for the reason of
>        * compatibility with format 0000, fields wFrqDiv, nOnceSeq, nRepeatSeq
>        * leave as dummy, so that code “looks” the same.
>        * aOnceSeq and aRepeatSeq are replaced with sCode, that consist real
>        * code info. Also, nOnceSeq and nRepeatSeq must meet the condition
>        * (nOnceSeq + nRepeatSeq) * 2 = sizeOf(sCode):
>        * Carrier clock is usually determined by the encoding, so it has to
>        * be returned by the encoding functions.
>        */

Line-length.


> --- Makefile.am       14 Apr 2008 01:55:46 -0000      1.7
> +++ Makefile.am       26 Apr 2009 22:14:23 -0000
> @@ -1,5 +1,5 @@
>  bin_PROGRAMS = concordance
> -concordance_SOURCES = concordance.c
> +concordance_SOURCES = concordance.c prontocodes.h prontocodes.c

No, just the C file which will include the header file.

> --- concordance.c     6 Apr 2009 20:34:48 -0000       1.38
> +++ concordance.c     26 Apr 2009 22:14:23 -0000
...
>  char get_cmd(char *prompt, char *allowed, char def) {
>       char result = 0;
>       char got_key;
> @@ -274,7 +302,7 @@ int learn_ir_commands(uint8_t *data, uin
>               }
>               printf("\nKey name : <%s> : \n", key_names[index]);
>               user_cmd = get_cmd(
> -                     "[L]earn, [N]ext, [P]revious, [Q]uit",
> +                     "[L]earn, Pronto [H]ex code, [N]ext, [P]revious, 
> [Q]uit",

Line length

> +                     case 'H':
> +                     case 'h': /* requested to get Pronto (from stdin): */
> +                             err = get_pronto_code(&carrier_clock, 
> &ir_signal,
> +                                     &ir_signal_length);
> +                             if (err != 0) {
> +                                     printf("??? Failed: %s - try again!\n",
> +                                             pco_strerror(err));


How about a nicer error message. Like:

   Decoding Pronto Hex code failed: %s

?


-- 
Phil Dibowitz                             p...@ipom.com
Open Source software and tech docs        Insanity Palace of Metallica
http://www.phildev.net/                   http://www.ipom.com/

"Be who you are and say what you feel, because those who mind don't matter
 and those who matter don't mind."
 - Dr. Seuss


Attachment: signature.asc
Description: OpenPGP digital signature

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
concordance-devel mailing list
concordance-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/concordance-devel

Reply via email to