RE: [MP3 ENCODER] TagItem issues...

2000-09-28 Thread Robert Hegemann

Mathew Hendry schrieb am Don, 28 Sep 2000:
> > From: Mathew Hendry 
> > 
> >  is pre-ANSI and non-standard - use  for 
> > the standard stuff. Should be
> > 
> >   va_start(ap)
> 
> Oops! I mean
> 
>   va_start(ap, lastarg)
> 
> where ap is your va_list and lastarg is the last non-variadic parameter.
> 
> >   va_arg(ap, type)
> 
> And not forgetting
> 
>   va_end(ap)
> 
> although on most systems it doesn't do much. Best to be compliant if
> possible, though...
> 
> -- Mat.


Seeing all those stuff and having printf in mind with all its 
affinity to trash the output, I'm getting more and more to the
conclusion, the best way would be to have one function for 
every parameter to set. This way it will be easier to check
for valid ranges etc.

But Frank already pointed that out.



Ciao Robert


--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



RE: [MP3 ENCODER] TagItem issues...

2000-09-28 Thread Mathew Hendry

> From: Mathew Hendry 
> 
>  is pre-ANSI and non-standard - use  for 
> the standard stuff. Should be
> 
>   va_start(ap)

Oops! I mean

  va_start(ap, lastarg)

where ap is your va_list and lastarg is the last non-variadic parameter.

>   va_arg(ap, type)

And not forgetting

  va_end(ap)

although on most systems it doesn't do much. Best to be compliant if
possible, though...

-- Mat.
--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



RE: [MP3 ENCODER] TagItem issues...

2000-09-28 Thread Mathew Hendry

> -Original Message-
> From: David Balazic [mailto:[EMAIL PROTECTED]]
> 
> Sigbjřrn Skjćret wrote:
> > >/* in my man page va_start has only one argument (ap) ... */
> > 
> > Your man-page is wrong then I think, the second argument is 
> so that va_arg()
> > knows where to start (ie, it makes ap point to the next argument).
> 
> HP-UX 10.20 man varargs say that it has only one arg.
> /usr/include/varargs.h on the same system has definitions
> with both two or one argument. Which one is used is dependent 
> on some preprocessor variables ( platform/CPU type , I guess ).
> 
> A linux libc5 system has a definition in include files with 
> one arg too.

 is pre-ANSI and non-standard - use  for the standard
stuff. Should be

  va_start(ap)
  va_arg(ap, type)

-- Mat.
--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-28 Thread David Balazic

Frank Klemm wrote:
> 
> ::  /* Usage :
> ::  lame_set_parameters(gfp, LAME_SAMP_FREQ__INT, 44100 ,
> ::  LAME_NR_CHANNELS__INT , 2 ,
> ::  LAME_LOW_PASS_VALUE__FLOAT , 16.050 ,
> ::  LAME_LOW_PASS_WIDTH__FLOAT , 0.75,
> ::  LAME_COMMENT__STRING , "This is cool" ,
> ::  LAME_END_MARKER);
> ::
> ::  LAME_END_MARKER informs the lame_set_parameters to stop reading values,
> ::  as AFAIK
> ::  there is not other way to determine whether all the args has been read
> ::
> ::  the __FLOAT and __INT attachments are there only to help illustrate my
> ::  idea,
> ::  but could be helpful in the actual implementation too
> ::
> ::  */
> ::
> One function, but is this simple?
> 
> No error checking,

Well , your functions below don't even have a return code.
But the compiler can not check if the arguments are of the correct type,
as already noticed.

> a lot of really strange constants, mixing Hz and kHz.

What strange constants ? The tag names ? You need somehow to
differentiate
between them, just the same as you used different names for each
function.
The names I used and the parameters were just as an example, I'm not
saying
that samp.freq. should be Hz in integer and filter band in kHz float !

> Do
> you like bugs? Do you love bugs? Do you buy a car with only one joystick to
> do all operations (including wheel- and oil-change)?

No. No. There are no such cars :-)

> Only one joystick, that means very simple operations! Welcome on the graveyard.
> 
> typedef struct {
> void*  ptr;
> const size_t   size;
> size_t len;
> } bytebuffer_t;
> 
> bytebuffer_t  bb;
> 
> LAME* gfp;
> 
> gfp = lame_open ();
> lame_set_samplefreq( gfp, 44100.0 );
> lame_set_channels  ( gfp, 2 );
> lame_set_lowpass   ( gfp, 16050.0 );
> lame_set_lowpass_width ( gfp,   750.0 );
> lame_set_lowpass_type  ( gfp, lame_filter_chebychev, 8, 0.5 );
> lame_set_comment   ( gfp, "This is not error prone" );
> lame_add_comment   ( gfp, "Developers will not hate lame developers" );
> lame_add_comment   ( gfp, "Lame developers do not need a body guard" );

What more error checking is involved in the above than in my example ? 
Off course this is a valid alternative to tagitems.
I not saying "use tagitems", but "if you use tagitems, then this idea of
mine
would make it better".

I don't think the following code example is related to the tagitems
topic.

> alloc_bytebuffer ( &bb, 16384 );
> 
> error = lame_encode_buffer ( gfp, &bb, 88200, channel_left, 
>channel_right );
> if (error)
> lame_perror ( "The following error occured", error );
> fwrite ( fp, 1, bb.len, bb.ptr );
> 
> error = lame_encode_interleaved_buffer ( gfp, &bb, 88200, interleaved_buffer );
> if (error)
> lame_perror ( "The following error occured", error );
> fwrite ( fp, 1, bb.len, bb.ptr );
> 
> error = lame_encode_finish ( gfp, &bb );
> if (error)
> lame_perror ( "The following error occured", error );
> fwrite ( fp, 1, bb.len, bb.ptr );
> 
> if ( bb.size > 16384 )
> printf ( "BitBuffer was increased by a subroutine, instead of crashing!\n" );
> 
> free_bytebuffer ( &bb );
> 
> error = lame_close ( gfp );
> if (error)
> lame_perror ( "Shit, the last operation and a error", error );
> 
> --
> Mit freundlichen Grüßen
> Frank Klemm
> 
> eMail | [EMAIL PROTECTED]   home: [EMAIL PROTECTED]
> phone | +49 (3641) 64-2721home: +49 (3641) 390545
> sMail | R.-Breitscheid-Str. 43, 07747 Jena, Germany
> 
> --
> MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )

-- 
David Balazic
--
"Be excellent to each other." - Bill & Ted
- - - - - - - - - - - - - - - - - - - - - -
--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-28 Thread David Balazic

Sigbjřrn Skjćret wrote:
> >/* in my man page va_start has only one argument (ap) ... */
> 
> Your man-page is wrong then I think, the second argument is so that va_arg()
> knows where to start (ie, it makes ap point to the next argument).

HP-UX 10.20 man varargs say that it has only one arg.
/usr/include/varargs.h on the same system has definitions
with both two or one argument. Which one is used is dependent 
on some preprocessor variables ( platform/CPU type , I guess ).

A linux libc5 system has a definition in include files with one arg too.

 
> >> I can still implement a way to have the tag also contain the type of the
> >> parameter, but since the general consensus seemed to be that this would be
> >> too complicated I went for this approach... ;)
> >But your existing tag "contain" the type , at least as much as they
> >would in my method.
> 
> What I meant was that I could device another way of passing the tags that
> would allow me to supply information of the parameters type (ptr/float/int),
> but this isn't too convenient at the calling end.
> 
> >#ifdef YOU
> >#define SOME_TAG some_int_value
> >#else
> >#define SOME_TAG some_int_value
> >#end
> 
> What was the purpose of this?

To demonstrate that your tags have the same as much type information
as mine :-)
 
> >Unless I use
> >SOME_TAG__WARNING_THIS_IS_FLOAT_AND_NOT_INT_OR_ANYTHING_ELSE,
> >but that is not the point , since it would work both with your and my
> >code.
> 
> The advantage of having 3 different functions is also that you at a later
> stage can change the type of the internal parameter, and still accept the
> old without having to add a duplicate tag (f.ex. if you change from int to
> float, then you can just add the tag to lame_set_float(), and add a cast in
> lame_set_int)...

Oh ,  code complexity for the sake of backward compatibility :-)


-- 
David Balazic
--
"Be excellent to each other." - Bill & Ted
- - - - - - - - - - - - - - - - - - - - - -
--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-27 Thread Frank Klemm

::  /* Usage :
::  lame_set_parameters(gfp, LAME_SAMP_FREQ__INT, 44100 ,
::  LAME_NR_CHANNELS__INT , 2 ,
::  LAME_LOW_PASS_VALUE__FLOAT , 16.050 ,
::  LAME_LOW_PASS_WIDTH__FLOAT , 0.75,
::  LAME_COMMENT__STRING , "This is cool" ,
::  LAME_END_MARKER);
::  
::  LAME_END_MARKER informs the lame_set_parameters to stop reading values,
::  as AFAIK
::  there is not other way to determine whether all the args has been read 
::  
::  the __FLOAT and __INT attachments are there only to help illustrate my
::  idea,
::  but could be helpful in the actual implementation too
::  
::  */
::
One function, but is this simple?

No error checking, a lot of really strange constants, mixing Hz and kHz. Do
you like bugs? Do you love bugs? Do you buy a car with only one joystick to
do all operations (including wheel- and oil-change)? 
Only one joystick, that means very simple operations! Welcome on the graveyard.


typedef struct {
void*  ptr;
const size_t   size;
size_t len;
} bytebuffer_t;

bytebuffer_t  bb;

LAME* gfp;

gfp = lame_open ();
lame_set_samplefreq( gfp, 44100.0 );
lame_set_channels  ( gfp, 2 );
lame_set_lowpass   ( gfp, 16050.0 );
lame_set_lowpass_width ( gfp,   750.0 );
lame_set_lowpass_type  ( gfp, lame_filter_chebychev, 8, 0.5 );
lame_set_comment   ( gfp, "This is not error prone" );
lame_add_comment   ( gfp, "Developers will not hate lame developers" );
lame_add_comment   ( gfp, "Lame developers do not need a body guard" );

alloc_bytebuffer ( &bb, 16384 );

error = lame_encode_buffer ( gfp, &bb, 88200, channel_left, channel_right 
);
if (error)
lame_perror ( "The following error occured", error );
fwrite ( fp, 1, bb.len, bb.ptr );

error = lame_encode_interleaved_buffer ( gfp, &bb, 88200, interleaved_buffer );
if (error)
lame_perror ( "The following error occured", error );
fwrite ( fp, 1, bb.len, bb.ptr );

error = lame_encode_finish ( gfp, &bb );
if (error)
lame_perror ( "The following error occured", error );
fwrite ( fp, 1, bb.len, bb.ptr );

if ( bb.size > 16384 )
printf ( "BitBuffer was increased by a subroutine, instead of crashing!\n" );

free_bytebuffer ( &bb );

error = lame_close ( gfp );
if (error)
lame_perror ( "Shit, the last operation and a error", error );

-- 
Mit freundlichen Grüßen
Frank Klemm
 
eMail | [EMAIL PROTECTED]   home: [EMAIL PROTECTED]
phone | +49 (3641) 64-2721home: +49 (3641) 390545
sMail | R.-Breitscheid-Str. 43, 07747 Jena, Germany

--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-27 Thread Sigbjørn Skjæret

>> This is how it looks now, better than using va_arg() at each case imho...
>Why is it better ?
>You wasted an additional variable and gained ( maybe ) some code space
>by not doing a function call ( or maybe it is a macro , probably
>platform dependant ) every time.

It's usually a (rather messy) macro. ;)

>By writing almost the same code 3 times you increase the likehood of
>bugs 3 times :-)
>Alltough most of the code would be repeated anyway.

True, but there's not much space for error. ;)

[...]
>#define CASE(TAG,elem,type) case LAME_ ## TAG : gfp -> elem =
>va_arg(args, type); break;
>  CASE( SET_SAMPLING_FREQ , samp_freq, int   )
[...]

That's actually not a bad idea...

>/* in my man page va_start has only one argument (ap) ... */

Your man-page is wrong then I think, the second argument is so that va_arg()
knows where to start (ie, it makes ap point to the next argument).

>> I can still implement a way to have the tag also contain the type of the
>> parameter, but since the general consensus seemed to be that this would be
>> too complicated I went for this approach... ;)
>But your existing tag "contain" the type , at least as much as they
>would in my method.

What I meant was that I could device another way of passing the tags that
would allow me to supply information of the parameters type (ptr/float/int),
but this isn't too convenient at the calling end.

>#ifdef YOU
>#define SOME_TAG some_int_value
>#else
>#define SOME_TAG some_int_value
>#end

What was the purpose of this?

>Unless I use
>SOME_TAG__WARNING_THIS_IS_FLOAT_AND_NOT_INT_OR_ANYTHING_ELSE,
>but that is not the point , since it would work both with your and my
>code.

The advantage of having 3 different functions is also that you at a later
stage can change the type of the internal parameter, and still accept the
old without having to add a duplicate tag (f.ex. if you change from int to
float, then you can just add the tag to lame_set_float(), and add a cast in
lame_set_int)...


- CISC

--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-27 Thread David Balazic

Sigbjřrn Skjćret wrote:
> 
> >> and parsing gets abit more messy...
> >How ?
> [...]
> 
> This is how it looks now, better than using va_arg() at each case imho...

Why is it better ?
You wasted an additional variable and gained ( maybe ) some code space
by not doing a function call ( or maybe it is a macro , probably
platform dependant ) every time.

By writing almost the same code 3 times you increase the likehood of
bugs 3 times :-)
Alltough most of the code would be repeated anyway.

My "more clear" version of the day :
( after the code are some more replyes to the original message )




int lame_set_parameters(lama_global_flags *gfp,...) 
{
  va_list args;
  LAME_TAG_TYPE current_tag;
  va_start(args);
  current_tag = va_arg(args,LAME_TAG_TYPE);

  while(current_tag != LAME_TAG_END )
  {
#define CASE(TAG,elem,type) case LAME_ ## TAG : gfp -> elem =
va_arg(args, type); break;

switch(current_tag) {
  CASE( SET_SAMPLING_FREQ , samp_freq, int   )
  CASE( SET_NR_CHAN   , nr_channels  , int   )
  CASE( FILTER_WIDTH  , filter_width , float )
  CASE( SOME_COMMENT  , some_comment , char* )

  /* some other integer, string or float or whatever parameters 
. */

#undef CASE

  default : return RET_TAG_ERROR_CODE;  /* also print a warning ?
probably not if this is a library.
  default : return -current_tag; so the app knows which tag is
problematic
 or maybe return the position of the
bad tag ? */
}
current_tag = va_arg(args,LAME_TAG_TYPE);
  }
  va_end(args);
}


Here is the old version for reference :
( there is a bug already !
  it should be lame_struct -> xxx and not
  lame_struct.xxx
)

lame_set_parameters(lama_global_flags *lame_struct,...) 
{
  va_list args;
  LAME_TAG_TYPE current_tag;
  va_start(args);
  current_tag = va_arg(args,LAME_TAG_TYPE);

  while(current_tag != LAME_TAG_END )
  {
switch(current_tag) {
  case LAME_SET_SAMPLING_FREQ : lame_struct.samp_freq =
va_arg(args,int); break;
  case LAME_SET_NR_CHAN :   lame_struct.nr_channels =
va_arg(args,int); break;
  case LAME_FILTER_WIDTH :  lame_struct.filter_width =
va_arg(args,float); break;
  /* some other integer, string or float or whatever parameters */

}
current_tag = va_arg(args,LAME_TAG_TYPE);
  }
  va_end(args);
}


 
> void lame_set_int(lame_global_flags *gfp, lame_param_tag tag1, ...)
> {
>va_list ap;
>int param;   /* (varargs promotes integrals to int) */
> 
>va_start(ap, tag1);

/* in my man page va_start has only one argument (ap) ... */

>while (tag1 != TAG_END)
>{
>  param = va_arg(ap, int);
> 
>  switch (tag1)
>  {
>case LAMEtag1:
>  gfp->test1 = param;
>  break;
> 
>case LAMEtag2:
>  gfp->test2 = param;
>  break;
> 
>default:
>  break;
>  }
> 
>  tag1 = va_arg(ap, lame_param_tag);
>}
>va_end(ap);
> }
> 
> I can still implement a way to have the tag also contain the type of the
> parameter, but since the general consensus seemed to be that this would be
> too complicated I went for this approach... ;)

But your existing tag "contain" the type , at least as much as they
would 
in my method.

#ifdef YOU
#define SOME_TAG some_int_value
#else
#define SOME_TAG some_int_value
#end

Unless I use
SOME_TAG__WARNING_THIS_IS_FLOAT_AND_NOT_INT_OR_ANYTHING_ELSE,
but that is not the point , since it would work both with your and my
code.


I'm in hurry, forgive any mistakes :-)
 
> - CISC
> 
> --
> MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )

-- 
David Balazic
--
"Be excellent to each other." - Bill & Ted
- - - - - - - - - - - - - - - - - - - - - -
--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-27 Thread Sigbjørn Skjæret

>> and parsing gets abit more messy...
>How ?
[...]

This is how it looks now, better than using va_arg() at each case imho...


void lame_set_int(lame_global_flags *gfp, lame_param_tag tag1, ...)
{
   va_list ap;
   int param;   /* (varargs promotes integrals to int) */

   va_start(ap, tag1);
   while (tag1 != TAG_END)
   {
 param = va_arg(ap, int);

 switch (tag1)
 {
   case LAMEtag1:
 gfp->test1 = param;
 break;

   case LAMEtag2:
 gfp->test2 = param;
 break;

   default:
 break;
 }

 tag1 = va_arg(ap, lame_param_tag);
   }
   va_end(ap);
}


I can still implement a way to have the tag also contain the type of the
parameter, but since the general consensus seemed to be that this would be
too complicated I went for this approach... ;)


- CISC

--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-27 Thread David Balazic

Sigbjřrn Skjćret wrote:
> >there is not other way to determine whether all the args has been read
> >the __FLOAT and __INT attachments are there only to help illustrate my
> >idea,
> >but could be helpful in the actual implementation too
> 
> Yes, but this still requires the parameters to be correct,

I don't think there is a way to make it work with incorrect
parameters :-)

> and parsing gets abit more messy...

How ?

The 3 functions method , the one for int parameters :
lame_set_parameter_int(lama_global_flags *lame_struct,...) 
{
  va_list args;
  LAME_TAG_TYPE current_tag;
  va_start(args);
  current_tag = va_arg(args,LAME_TAG_TYPE);

  while(current_tag != LAME_TAG_END )
  {
switch(current_tag) {
  case LAME_SET_SAMPLING_FREQ :  lame_struct.samp_freq =
va_arg(args,int); break;
  case LAME_SET_NR_CHAN :lame_struct.nr_channels =
va_arg(args,int); break;
 /* some other integer parameters */ 
}
current_tag = va_arg(args,LAME_TAG_TYPE);
  }
  va_end(args);
}

the "unified function version :

lame_set_parameters(lama_global_flags *lame_struct,...) 
{
  va_list args;
  LAME_TAG_TYPE current_tag;
  va_start(args);
  current_tag = va_arg(args,LAME_TAG_TYPE);

  while(current_tag != LAME_TAG_END )
  {
switch(current_tag) {
  case LAME_SET_SAMPLING_FREQ : lame_struct.samp_freq =
va_arg(args,int); break;
  case LAME_SET_NR_CHAN :   lame_struct.nr_channels =
va_arg(args,int); break;
  case LAME_FILTER_WIDTH :  lame_struct.filter_width =
va_arg(args,float); break;
  /* some other integer, string or float or whatever parameters */

}
current_tag = va_arg(args,LAME_TAG_TYPE);
  }
  va_end(args);
}


-- 
David Balazic
--
"Be excellent to each other." - Bill & Ted
- - - - - - - - - - - - - - - - - - - - - -
--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-27 Thread Sigbjørn Skjæret

>> o main.c can't hold lame_global_flags, change lame_init() to allocate and
>>   return a pointer to lame_global_flags.
>> o Move lame_global_flags out of lame.h, it should never be accessed
>> externally.
>I think we have to keep the old interface, since several applications
>use it.  So lame_global_flags will still have to be instantiated by the
>calling program and exposed to the calling program.  I dont think this
>is incompatiable with a shared library?

Yes, it is, because the structure itself can expand and change at any given
time internally, and if it's allocated and/or changed externally it will most
surely get corrupted by any program using a different version of the structure
than the library itself...


- CISC

--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-27 Thread Sigbjørn Skjæret

>IIRC, if you use varargs then the compiler can't detect if the supplied
>parameters
>are of wrong type. Example :
[...]
>The compiler won't notice that the parameter is of wrong type
>and when the function will try to extract an int from the stack,
>it will get garbage.

This is indeed true, and that's why I chose to divide the function in 3 to
clarify this to the user.

>But if this is of no concern , then a simpler interface can be used :
[...]
>LAME_END_MARKER informs the lame_set_parameters to stop reading values,
>as AFAIK

This is exactly how my current interface works (based on TagItems when passed
on stack).

>there is not other way to determine whether all the args has been read 
>the __FLOAT and __INT attachments are there only to help illustrate my
>idea,
>but could be helpful in the actual implementation too

Yes, but this still requires the parameters to be correct, and parsing gets
abit more messy...


- CISC

--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-27 Thread Takehiro Tominaga

> "R" == Robert Hegemann <[EMAIL PROTECTED]> writes:

R> Mark Taylor schrieb am Die, 26 Sep 2000:
>> I think we have to keep the old interface, since several
>> applications use it.  So lame_global_flags will still have to
>> be instantiated by the calling program and exposed to the
>> calling program.  I dont think this is incompatiable with a
>> shared library?
>> 
>> Mark

R>  Doing so would require to recompile every client if we add an
R> entry in lame_global_flags, even if the client will not care
R> about the new entry.

Yes, That is the most heavy problem. even worse, changing compiler
or compiler option will make it require to recompile every client.

R>  The client shouldn't know about internal data structures.  So,
R> doing as Frank previously suggested would be OK.

I agree, too.
--- 
Takehiro TOMINAGA // may the source be with you!
--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-27 Thread David Balazic



Sigbjřrn Skjćret wrote:
> 
> >> >This way there is no need to parse any strings, we don't pass
> >> >any pointers, the setup routine would just be a big switch/case.
> >> This is basically the way TagItems work when passed on stack, in fact, that
> >> combined with another identical function that does float we're pretty much
> >> set.
> >   Why do we need float at this point ??
> 
> Because several of the parsed arguments are floats?
> 
> Well, anyway, I just finished up the following:
> 
> /* Set a parameter with string-pointer */
> void lame_set_string(lame_global_flags *gfp, lame_param_tag tag1, ...);
> 
> /* Set a parameter with float or double value (varargs promotes floats to double) */
> void lame_set_float(lame_global_flags *gfp, lame_param_tag tag1, ...);
> 
> /* Set a parameter with char, short or int value (varargs promotes integrals to int) 
>*/
> void lame_set_int(lame_global_flags *gfp, lame_param_tag tag1, ...);

IIRC, if you use varargs then the compiler can't detect if the supplied
parameters
are of wrong type. Example :

/* sample freq is an int , but be supply a float */
lame_set_int(gfp, LAME_SAMP_FREQ, 44101.213 );

The compiler won't notice that the parameter is of wrong type
and when the function will try to extract an int from the stack,
it will get garbage.


But if this is of no concern , then a simpler interface can be used :

lame_set_parameters(lame_global_flags *gfp, ...);
/* or this one , as the type of the first argument is always the same */
lame_set_parameters(lame_global_flags *gfp, lame_param_tag tag1, ...);

/* Usage :
lame_set_parameters(gfp, LAME_SAMP_FREQ__INT, 44100 ,
LAME_NR_CHANNELS__INT , 2 ,
LAME_LOW_PASS_VALUE__FLOAT , 16.050 ,
LAME_LOW_PASS_WIDTH__FLOAT , 0.75,
LAME_COMMENT__STRING , "This is cool" ,
LAME_END_MARKER);

LAME_END_MARKER informs the lame_set_parameters to stop reading values,
as AFAIK
there is not other way to determine whether all the args has been read 

the __FLOAT and __INT attachments are there only to help illustrate my
idea,
but could be helpful in the actual implementation too

*/


 
> This can cater for any kind of parameter, and the functions themselves are
> very simple, yet can take several parameters in a row...
> 
> Should I start implementing this now, or wait after 3.87 release?
> 
> Mark?
> 
> What needs to be changed to make a real shared library:
> 
> o Exchange all direct access to lame_global_flags in parse.c with calls to
>   lame_set_xxx().
> 
> o main.c can't hold lame_global_flags, change lame_init() to allocate and
>   return a pointer to lame_global_flags.
> 
> o Move lame_global_flags out of lame.h, it should never be accessed externally.
> 
> o ..and any other changes still needed for re-entrance ofcos.
> 
> - CISC
> 
> --
> MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )

-- 
David Balazic
--
"Be excellent to each other." - Bill & Ted
- - - - - - - - - - - - - - - - - - - - - -
--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-27 Thread Frank Klemm

::  Sigbjørn Skjæret schrieb am Die, 26 Sep 2000:
::  > > Why do we need float at this point ??
::  > 
::  > Because several of the parsed arguments are floats?
::  
::  ie. frequencies could be passed in Hertz as ints,
::  was just something to think about now while we
::  change the API anyway
::  
What about not integer value sampling frequencies? For stand alone audio
rounding is no problem. But for audio/video and unbuffered streaming this
may produce really unnecessary problems.

For instance AIFF stores sampling frequency as 80 bit-IEEE-754 long double.

Avoid problems instead of patching the results of this problems.

-- 
Mit freundlichen Grüßen
Frank Klemm
 
eMail | [EMAIL PROTECTED]   home: [EMAIL PROTECTED]
phone | +49 (3641) 64-2721home: +49 (3641) 390545
sMail | R.-Breitscheid-Str. 43, 07747 Jena, Germany

--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-27 Thread Robert Hegemann

Mark Taylor schrieb am Die, 26 Sep 2000:
> I think we have to keep the old interface, since several applications
> use it.  So lame_global_flags will still have to be instantiated by the
> calling program and exposed to the calling program.  I dont think this
> is incompatiable with a shared library?
> 
> Mark

Doing so would require to recompile every client if we add
an entry in lame_global_flags, even if the client will not 
care about the new entry.

The client shouldn't know about internal data structures.
So, doing as Frank previously suggested would be OK.


Ciao Robert

--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-26 Thread Mark Taylor


> 
> Should I start implementing this now, or wait after 3.87 release?
> 
Hi CISC,

3.87 was released last night.  It's mostly just to have a 
last release before the code re-orginization that Takehiro
is going to do this week.  That will involve splitting
the C code into a frontend and library directory.  
So it would be good if we could hold off on all commits
until this is done.  



> 
> What needs to be changed to make a real shared library:
> 
> o Exchange all direct access to lame_global_flags in parse.c with calls to
>   lame_set_xxx().
> 
> o main.c can't hold lame_global_flags, change lame_init() to allocate and
>   return a pointer to lame_global_flags.
> 
> o Move lame_global_flags out of lame.h, it should never be accessed externally.
> 
> o ..and any other changes still needed for re-entrance ofcos.
> 
> 

I think we have to keep the old interface, since several applications
use it.  So lame_global_flags will still have to be instantiated by the
calling program and exposed to the calling program.  I dont think this
is incompatiable with a shared library?

Mark










--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-26 Thread Sigbjørn Skjæret

>> >Why do we need float at this point ??
>> Because several of the parsed arguments are floats?
>   ie. frequencies could be passed in Hertz as ints,
>   was just something to think about now while we
>   change the API anyway

Yes, but no reason not to have the possibility there. ;)

>> Should I start implementing this now, or wait after 3.87 release?
>   I think 3.87 is already out, CVS is tagged 3.88 alpha 1

Ah, yes, so I see...

>   You may get in contact with Takehiro to see what will be done
>   next.

Takehiro, wanna drop me a line when you are finished moving stuff about? ;)


- CISC

--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-26 Thread Robert Hegemann

Sigbjørn Skjæret schrieb am Die, 26 Sep 2000:
> > Why do we need float at this point ??
> 
> Because several of the parsed arguments are floats?

ie. frequencies could be passed in Hertz as ints,
was just something to think about now while we
change the API anyway

> Should I start implementing this now, or wait after 3.87 release?

I think 3.87 is already out, CVS is tagged 3.88 alpha 1

You may get in contact with Takehiro to see what will be done
next.


Ciao Robert

--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-26 Thread Sigbjørn Skjæret

>This sounds more complex than my proposed "void*" change. Keep in mind:
 More complex, but not that hard.
>>>"KISS".
>> I'm not even gonna ask. ;)
> "Keep It Simple, Stupid".
[...]

Right, well, I believe that's exactly what it is now. ;)


- CISC

--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-26 Thread Sigbjørn Skjæret

>> >This way there is no need to parse any strings, we don't pass
>> >any pointers, the setup routine would just be a big switch/case.
>> This is basically the way TagItems work when passed on stack, in fact, that
>> combined with another identical function that does float we're pretty much
>> set.
>   Why do we need float at this point ??

Because several of the parsed arguments are floats?

Well, anyway, I just finished up the following:

/* Set a parameter with string-pointer */
void lame_set_string(lame_global_flags *gfp, lame_param_tag tag1, ...);

/* Set a parameter with float or double value (varargs promotes floats to double) */
void lame_set_float(lame_global_flags *gfp, lame_param_tag tag1, ...);

/* Set a parameter with char, short or int value (varargs promotes integrals to int) */
void lame_set_int(lame_global_flags *gfp, lame_param_tag tag1, ...);


This can cater for any kind of parameter, and the functions themselves are
very simple, yet can take several parameters in a row...

Should I start implementing this now, or wait after 3.87 release?

Mark?


What needs to be changed to make a real shared library:

o Exchange all direct access to lame_global_flags in parse.c with calls to
  lame_set_xxx().

o main.c can't hold lame_global_flags, change lame_init() to allocate and
  return a pointer to lame_global_flags.

o Move lame_global_flags out of lame.h, it should never be accessed externally.

o ..and any other changes still needed for re-entrance ofcos.


- CISC

--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-26 Thread Alexander Leidinger

On 25 Sep, Sigbjørn Skjæret wrote:

> simply making a new TagItems interface which allows you to specify the
> type of data the TagItem contains. This will be much better in the long
> run, and will allow the TagItems to contain any type of data.
This sounds more complex than my proposed "void*" change. Keep in mind:
>>> More complex, but not that hard.
>>"KISS".
> 
> I'm not even gonna ask. ;)

---snip---
KISS Principle /kis' prin'si-pl/ n. 

 "Keep It Simple,
   Stupid".  A maxim often invoked when discussing design to fend off
   creeping featurism and control development complexity. 
   Possibly related to the marketroid maxim on sales
   presentations, "Keep It Short and Simple".
---snip---

Bye,
Alexander.

-- 
   I believe the technical term is "Oops!"

http://www.Leidinger.net   Alexander @ Leidinger.net
  GPG fingerprint = 7423 F3E6 3A7E B334 A9CC  B10A 1F5F 130A A638 6E7E

--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-25 Thread Frank Klemm

::  
::  proposal:
::  
::  int lame_open(); 
::  // allocates internal structures
::  
::  int lame_set_param( int handle, LameParameter Parameter, int Value );
::  // assigns Lame's parameter a value
::
a) Not every variable is an integer. C programmer try to store everything
   (food, women, cars ;-) in an int, but from the state of good programming
   style this is brain dead and not far from FORTRAN 4.

b) Brain dead interfaces creates things like:

   double d = 3.14159265358979;
   float  f = d;
   func ( *(int*)&f );  // transmit float value through int
   func ( (int)stdout );// fails on sizeof(void*) > sizeof(int)

c) It is wise to return the actual parameter

d) it is wise to return an status word (error code)

e) it is wise not to use in-band-signaling for error codes

f) Sometimes it is useful to change some parameters atomically
   (For RT systems this is often an indispensable need).

So we got something like:

int lame_set_param ( 
inthandle, 
LameParameter  ParameterType, 
... );
// assigns Lame's parameter a value

Examples:

long double ld;
double  d;
int i1;
int i2;
FILE*   fp;

ld = 44055.938461538;   // NTSC PCM, lips synchr.
printf ( "Input fs is %lf, ", ld );
err = lame_set_param ( lh, Lame_LD_InputSampleFreq, &ld )
printf ( "set to %lf.\n", ld );

i1 = 128000;
i2 = 256000;
printf ( "VBR bitrate should be between %7.3f...%7.3f, ", i1*1.e-3, i2*1.e-3 );
err = lame_set_param ( lh, Lame_I2_VBRBitrateRange, &i1, &i2 )
printf ( "set to %7.3f...%7.3f\n", i1*1.e-3, i2*1.e-3 );

fp = fopen ( "report", "w" );
err = lame_set_param ( lh, Lame_fp_Reportfp, &fp );

Another question: Why not using a set of functions to setup parameters.
It is not more difficult, but less, it does not disable type checking and
link checking. 

This is also something I call: "cosmetic fake simplification".
It:

   * moves complexity instead of reducing (virtual hiding)
   * disables type checking
   * disables functionality checking by the linker
   * it clouds errors (compile/link time => run time or later)

Okay. It's C ;-)


::  int lame_init_params( int handle );
::  // fills up rest of needed parameters by default values
::
Not necessary. Can be done by lame_encode stuff.

lame__flags has an internal flag:

0: invalid, before open() or after close()
1: valid, open() was done, ready for setup
2: the first lame_encode_...() stuff was called (finalization of params)


::  
::  usual lame_encode() stuff
::  
::  void lame_close( int handle );
::  // frees all allocated internal structures
::  
::  
::  just enumerate all parameters LAME will use, we can allways append
::  new ones if needed. A 32 bit int should provide us enough internal 
::  parameters ;)
::  
::  typedef enum{
::  lp_bitrate,
::  lp_vbrmode,
::  lp_vbrquality,
::  lp_vbrmin,
::  lp_vbrmax,
::  lp_crc,
::  :
::  } LameParameter;
::
Another point is: It is not wise to mix
  -vbr -b  and -cbr -b
I would use three parameters for -vbr -b, -vbr -B and -cbr -b.
  
::  
::  // different channel modes
::  #define CM_MONO 1
::  #define CM_LR_STEREO 2
::  #define CM_J_STEREO 3
::  #define CM_MS_STEREO 4
::  ...
::  
::  Example setup sequence:
::  
::  handle = lame_open();
::  
::  lame_set_param( handle, lp_bitrate, 128 );
::  lame_set_param( handle, lp_crc, FALSE );
::  lame_set_param( handle, lp_original, FALSE );
::  lame_set_param( handle, lp_channelmode, CM_J_STEREO );
::  lame_set_param( handle, lp_quality, 2 );
::  
::  lame_set_param( handle, lp_lowpass, 5500 );
::  lame_set_param( handle, lp_lowpasswidth, 500 );
::  lame_set_param( handle, lp_highpass, 100 );
::  
::  lame_set_param( handle, lp_resample, 11025 );
::  
::  lame_set_param( handle, lp_voice, TRUE );
::  
::  lame_init_params( handle );
::  
::  
::  
::  lame_close( handle ); 
::  
::  This way there is no need to parse any strings, we don't pass
::  any pointers, the setup routine would just be a big switch/case.
::
An additional demultiplexer/multiplexer.

::  
handle = lame_open ();

lame_set_cbr_bitrate  ( handle, 128000 );
lame_set_crc  ( handle, disable );
lame_set_genuine  ( handle, false );
lame_set_channel_mode ( handle, channelmode_jstereo );
lame_set_quality  ( handle, 100-2*100/9 );  // arbitrary values are scaled 
(bad=0,best=100)
lame_set_lowpass  ( handle, 5500.0 );
lame_set_lowpass_width( handle,  500.0 );
lame_set_lowpass_width_ratio ( handle,  0.0909 );
lame_set_highpass ( handle,  100.0 );

lame_set_output_samplefreq ( handle, 11025.0 );

lame_set_presets  ( handle, preset_voice );



lame_close ( handle ); 


Handles have advantages and disadvantage

Re: [MP3 ENCODER] TagItem issues...

2000-09-25 Thread Robert Hegemann

Sigbjørn Skjæret schrieb am Mon, 25 Sep 2000:
> [...]
> >This way there is no need to parse any strings, we don't pass
> >any pointers, the setup routine would just be a big switch/case.
> 
> This is basically the way TagItems work when passed on stack, in fact, that
> combined with another identical function that does float we're pretty much
> set.

Why do we need float at this point ??

> 
> 
> - CISC

Ciao Robert
--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-25 Thread Sigbjørn Skjæret

>Why not something like:
>lame_set_float(char *variable_name, float val);
>lame_set_int(char *variable_name, int val);

Hey, gr8, idea, and maybe another with void*?

>But this brings up another question: The code is going to do a lot of
>parsing, and it looks like each variable will require several lines of
>code?  If that is the case, then we dont actually save anything and we
>might as well just creating a short function for every variable?  This
>way there are no type casting problems.

Ah, no, I just got a gr8 idea, what we need is 3 functions:

lame_set_string(lame_global_flags *gfp, StringItem tag1, ...);
lame_set_float(lame_global_flags *gfp, FloatItem tag1, ...);
lame_set_int(lame_global_flags *gfp, IntItem tag1, ...);

Dead simple parsing using 3 different TagItem clones, and you can pass
several items at once (within the same type anyway).


- CISC

--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-25 Thread Sigbjørn Skjæret

[...]
>This way there is no need to parse any strings, we don't pass
>any pointers, the setup routine would just be a big switch/case.

This is basically the way TagItems work when passed on stack, in fact, that
combined with another identical function that does float we're pretty much
set.


- CISC

--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-25 Thread Mark Taylor


> 
> >>>The first proposal is IMHO enough for everyday use, the second is for
> >>>architectures which didn't allow lossless transportation of information
> >>>between a void* and an integer type (in case you use ti_data to contain
> >>>the information instead of a pointer to the information).
> >> Only "problem" I can see immediately with void* is that all values needs to
> >> be casted, which wasn't strictly necessary with unsigned long, and float/
> >> double still needs to be temporarily stored. :P
> >I'm waiting for your solution which didn't need casts (and remember the
> >mail which talked about casts in lame).
> 
> Eheh, well, we'll see what I can cook up. ;)
> 
> 
> - CISC
> 

Why not something like:


lame_set_float(char *variable_name, float val);
lame_set_int(char *variable_name, int val);

But this brings up another question: The code is going to do a lot of
parsing, and it looks like each variable will require several lines of
code?  If that is the case, then we dont actually save anything and we
might as well just creating a short function for every variable?  This
way there are no type casting problems.

Mark




--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-25 Thread Robert Hegemann

I think we can make a very simple library setup stuff:

proposal:

int lame_open(); 
// allocates internal structures

int lame_set_param( int handle, LameParameter Parameter, int Value );
// assigns Lame's parameter a value

int lame_init_params( int handle );
// fills up rest of needed parameters by default values

usual lame_encode() stuff

void lame_close( int handle );
// frees all allocated internal structures


just enumerate all parameters LAME will use, we can allways append
new ones if needed. A 32 bit int should provide us enough internal 
parameters ;)

typedef enum{
lp_bitrate,
lp_vbrmode,
lp_vbrquality,
lp_vbrmin,
lp_vbrmax,
lp_crc,
:
} LameParameter;

// different channel modes
#define CM_MONO 1
#define CM_LR_STEREO 2
#define CM_J_STEREO 3
#define CM_MS_STEREO 4
...

Example setup sequence:

handle = lame_open();

lame_set_param( handle, lp_bitrate, 128 );
lame_set_param( handle, lp_crc, FALSE );
lame_set_param( handle, lp_original, FALSE );
lame_set_param( handle, lp_channelmode, CM_J_STEREO );
lame_set_param( handle, lp_quality, 2 );

lame_set_param( handle, lp_lowpass, 5500 );
lame_set_param( handle, lp_lowpasswidth, 500 );
lame_set_param( handle, lp_highpass, 100 );

lame_set_param( handle, lp_resample, 11025 );

lame_set_param( handle, lp_voice, TRUE );

lame_init_params( handle );



lame_close( handle ); 

This way there is no need to parse any strings, we don't pass
any pointers, the setup routine would just be a big switch/case.



Ciao Robert


--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-25 Thread Sigbjørn Skjæret

 1.) Floats and doubles will lose all it's precision (this can be simply
 avoided by passing the string-pointer from arg-parsing and converting
 when parsing TagItems instead)
>>>What about passing the pointer to the float/double instead?
>> Sure, but that means you will have to temporarily store the value somewhere
>> else.
>Yes. Are there many fixed values in lame?

If you read parse.c you'll see that there's a few values that's atof()ed
straight in.

 simply making a new TagItems interface which allows you to specify the
 type of data the TagItem contains. This will be much better in the long
 run, and will allow the TagItems to contain any type of data.
>>>This sounds more complex than my proposed "void*" change. Keep in mind:
>> More complex, but not that hard.
>"KISS".

I'm not even gonna ask. ;)

>>>The first proposal is IMHO enough for everyday use, the second is for
>>>architectures which didn't allow lossless transportation of information
>>>between a void* and an integer type (in case you use ti_data to contain
>>>the information instead of a pointer to the information).
>> Only "problem" I can see immediately with void* is that all values needs to
>> be casted, which wasn't strictly necessary with unsigned long, and float/
>> double still needs to be temporarily stored. :P
>I'm waiting for your solution which didn't need casts (and remember the
>mail which talked about casts in lame).

Eheh, well, we'll see what I can cook up. ;)


- CISC

--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-25 Thread Alexander Leidinger

On 24 Sep, Sigbjørn Skjæret wrote:
>>> 1.) Floats and doubles will lose all it's precision (this can be simply
>>> avoided by passing the string-pointer from arg-parsing and converting
>>> when parsing TagItems instead)
>>What about passing the pointer to the float/double instead?
> 
> Sure, but that means you will have to temporarily store the value somewhere
> else.

Yes. Are there many fixed values in lame?

>>> simply making a new TagItems interface which allows you to specify the type
>>> of data the TagItem contains. This will be much better in the long run, and
>>> will allow the TagItems to contain any type of data.
>>This sounds more complex than my proposed "void*" change. Keep in mind:
> 
> More complex, but not that hard.

"KISS".

>>the Amiga TagItem implementation was done with 32bit pointers in mind
>>and not with portability. An (IMHO) more elegant (and still simple)
>>solution for the data part would look like
> [...]
>>The first proposal is IMHO enough for everyday use, the second is for
>>architectures which didn't allow lossless transportation of information
>>between a void* and an integer type (in case you use ti_data to contain
>>the information instead of a pointer to the information).
> 
> Only "problem" I can see immediately with void* is that all values needs to
> be casted, which wasn't strictly necessary with unsigned long, and float/
> double still needs to be temporarily stored. :P

I'm waiting for your solution which didn't need casts (and remember the
mail which talked about casts in lame).

Bye,
Alexander.

-- 
   Intel: where Quality is job number 0.9998782345!

http://www.Leidinger.net   Alexander @ Leidinger.net
  GPG fingerprint = 7423 F3E6 3A7E B334 A9CC  B10A 1F5F 130A A638 6E7E

--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-24 Thread Sigbjørn Skjæret

>> 1.) Floats and doubles will lose all it's precision (this can be simply
>> avoided by passing the string-pointer from arg-parsing and converting
>> when parsing TagItems instead)
>What about passing the pointer to the float/double instead?

Sure, but that means you will have to temporarily store the value somewhere
else.

>> 3.) 64bit pointers will be truncated (not too much trouble unless you have
>> and use more than 4gig of memory in your machine).
>Don't keep the AmigaOS compatibility of my functions (see bellow why)
>and change the data part (ti_Data) of the struct to "void*".

Hmmm, yes, maybe, if the compiler allows it. ;)

>> simply making a new TagItems interface which allows you to specify the type
>> of data the TagItem contains. This will be much better in the long run, and
>> will allow the TagItems to contain any type of data.
>This sounds more complex than my proposed "void*" change. Keep in mind:

More complex, but not that hard.

>the Amiga TagItem implementation was done with 32bit pointers in mind
>and not with portability. An (IMHO) more elegant (and still simple)
>solution for the data part would look like
[...]
>The first proposal is IMHO enough for everyday use, the second is for
>architectures which didn't allow lossless transportation of information
>between a void* and an integer type (in case you use ti_data to contain
>the information instead of a pointer to the information).

Only "problem" I can see immediately with void* is that all values needs to
be casted, which wasn't strictly necessary with unsigned long, and float/
double still needs to be temporarily stored. :P


- CISC

--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )



Re: [MP3 ENCODER] TagItem issues...

2000-09-24 Thread Alexander Leidinger

On 23 Sep, Sigbjørn Skjæret wrote:
> Ok, after thinking about this for a while, and experimenting a little, I
> thought of a couple of issues with using TagItems to pass configuration
> settings in LAME...
> 
> 1.) Floats and doubles will lose all it's precision (this can be simply
> avoided by passing the string-pointer from arg-parsing and converting
> when parsing TagItems instead)

What about passing the pointer to the float/double instead?

> 3.) 64bit pointers will be truncated (not too much trouble unless you have
> and use more than 4gig of memory in your machine).

Don't keep the AmigaOS compatibility of my functions (see bellow why)
and change the data part (ti_Data) of the struct to "void*".

> I've been thinking about simply ditching AmigaOS TagItem compatability, and

I think there's no need to use any Amiga library in the LAME library, so
it didn't buys you anything to keep the compatibility (or use the real
Amiga functions). If you improve the usability of the LAME TagItem
(like) implementation then go for it.

> simply making a new TagItems interface which allows you to specify the type
> of data the TagItem contains. This will be much better in the long run, and
> will allow the TagItems to contain any type of data.

This sounds more complex than my proposed "void*" change. Keep in mind:
the Amiga TagItem implementation was done with 32bit pointers in mind
and not with portability. An (IMHO) more elegant (and still simple)
solution for the data part would look like
  void *ti_data;
or
  union { void *pointer; unsigned long number; } ti_data; 
instead of just
  unsigned long ti_data;
  
The first proposal is IMHO enough for everyday use, the second is for
architectures which didn't allow lossless transportation of information
between a void* and an integer type (in case you use ti_data to contain
the information instead of a pointer to the information).

Bye,
Alexander.

-- 
The dark ages were caused by the Y1K problem.

http://www.Leidinger.net   Alexander @ Leidinger.net
  GPG fingerprint = 7423 F3E6 3A7E B334 A9CC  B10A 1F5F 130A A638 6E7E

--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )