INTERACT FORUM

Please login or register.

Login with username, password and session length
Advanced search  
Pages: [1]   Go Down

Author Topic: New Input (Decoder) Interface 11.1.146+  (Read 4900 times)

scthom

  • Citizen of the Universe
  • *****
  • Posts: 621
New Input (Decoder) Interface 11.1.146+
« on: March 16, 2006, 08:04:50 pm »

Please let me know when the SDK is updated, or what, if anything, I should do to update the flac decoder to work with 11.1.146+.
Logged

JimH

  • Administrator
  • Citizen of the Universe
  • *****
  • Posts: 72442
  • Where did I put my teeth?
Re: New Input (Decoder) Interface 11.1.146+
« Reply #1 on: March 16, 2006, 08:35:02 pm »

11.1.146 was killed.  11.1.147 should work.  It was our fault.  I'm sorry for the problem.
Logged

scthom

  • Citizen of the Universe
  • *****
  • Posts: 621
Re: New Input (Decoder) Interface 11.1.146+
« Reply #2 on: March 17, 2006, 04:25:36 pm »

So does that mean there is no change to the interface?  There were some messages in the 146 thread that indicated there may have been an interface change.
Logged

JimH

  • Administrator
  • Citizen of the Universe
  • *****
  • Posts: 72442
  • Where did I put my teeth?
Re: New Input (Decoder) Interface 11.1.146+
« Reply #3 on: March 17, 2006, 05:41:08 pm »

The change was revised so it should not affect you.
Logged

scthom

  • Citizen of the Universe
  • *****
  • Posts: 621
Re: New Input (Decoder) Interface 11.1.146+
« Reply #4 on: March 18, 2006, 11:26:52 am »

I believe you, but ....  ;D

There's a CD burning problem. See this thread http://yabb.jriver.com/interact/index.php?topic=32644.0.

The last time the CD burning problem cropped up, there was a problem with a new data object that I didn't know about. See this thread  http://yabb.jriver.com/interact/index.php?topic=29696.0.

So I'm just checking to make sure there's nothing new.

[Later]
I'm still looking through my code to make sure it's not me.  I've tested my 1.5 decoder on 120, 140, and 145 so far and they all fail.  1.4 decoder has worked on 120 and 148.  So most likely it's me.

[Later yet]
The biggest change between 1.4 and 1.5 was the switch to JRReader instead of CFiles.  There were no other substantive differences that I could find after spending most of the day looking at it.  However, I do notice that there are two new "GetInformation" entries, 19 and 20, that aren't in the SDK/MJInputSource.h enum.  What are they for??

[So much later it's the next day]
Weird.  I did find what the problem was.  There's some major mojo going on between the base MJInputSource class and the plugins in terms of the m_nLengthBlocks variable because the only way it works correctly is if I have the variable defined (overridden) in my class but I do not respond to GetInformation 12 which is the m_nLengthBlocks response.  If I let the base class handle the request, then it works.  If I respond from my class it doesn't work whether I have the variable defined or not.  But the responses ought to be the same either way.

Still want to know what GetInformation 19 and 20 are.
Logged

scthom

  • Citizen of the Universe
  • *****
  • Posts: 621
Re: New Input (Decoder) Interface 11.1.146+
« Reply #5 on: March 19, 2006, 10:57:36 pm »

Also, a few more questions about the input SDK.  It's not clear from the documentation and the example (Ogg), if I'm supposed to be overriding some of the functions in MJInputSource.h/.cpp.

For example, the two functions GetSamples and ResetInternalBuffer are listed as virtual in the header file, which implies that I'm supposed to override them.  However, they seem to be pretty fully implemented in the cpp file.  The Ogg example doesn't override either one.  But it does override AddDataToBuffer which is also listed as virtual.

Are the Bookmarks and Chapters GetInformation queries in InputSource intended to support cue sheets?  Since flac allows cue data, can I support these with that data?  Or are these intended for a particular format?
Logged

John Gateley

  • Citizen of the Universe
  • *****
  • Posts: 4957
  • Nice haircut
Re: New Input (Decoder) Interface 11.1.146+
« Reply #6 on: March 20, 2006, 10:50:11 am »

19 and 20 are (I think) blocks to skip for the header and footer. (19 is the header). You probably don't need these.

About m_nLengthBlocks: the correct use is to set this in the Open function. The CMJInputSource doesn't really do anything with this variable besides report it when asked. Did you try this already?

j

John Gateley

  • Citizen of the Universe
  • *****
  • Posts: 4957
  • Nice haircut
Re: New Input (Decoder) Interface 11.1.146+
« Reply #7 on: March 20, 2006, 10:59:24 am »

Bookmarks are used in Audible support, Chapters are used for DVDs. I'm not sure if these can be adapted to cue support or not.

GetSamples and ResetInternalBuffer are fully implemented, though they can be overridden if needed. AddDataToBuffer has only a default error implementation (return -1), so you MUST override and implement this function.

j

scthom

  • Citizen of the Universe
  • *****
  • Posts: 621
Re: New Input (Decoder) Interface 11.1.146+
« Reply #8 on: March 20, 2006, 06:07:59 pm »

About m_nLengthBlocks: the correct use is to set this in the Open function. The CMJInputSource doesn't really do anything with this variable besides report it when asked. Did you try this already?

I do it from the Open function but it's actually in a callback when the metadata has been analyzed.  I don't think it's a problem.

The wierd part is that I can't use the one from the base class MJInputSource, I have to override it as a variable in my class.  But the response to the query can't come from my class it has to come from the base class (MJInputSource).  If I try to respond to GetInformation 12 from within my class it will fail the burn.
Logged

John Gateley

  • Citizen of the Universe
  • *****
  • Posts: 4957
  • Nice haircut
Re: New Input (Decoder) Interface 11.1.146+
« Reply #9 on: March 21, 2006, 09:53:51 am »

The wierd part is that I can't use the one from the base class MJInputSource, I have to override it as a variable in my class.  But the response to the query can't come from my class it has to come from the base class (MJInputSource).  If I try to respond to GetInformation 12 from within my class it will fail the burn.

If I understand: this means you have two variables:

MyClass::m_nLengthInputBlocks
MJInputSource::m_nLengthInputBlocks

You change MyClass::m_nLengthInputBlocks to be the length of the input in blocks, but MJInputSource::m_nLengthInputBlocks is initialized to 0 and never changed.

So, when the GetInformation 12 is called to your class, it is returning the "correct" value, but when it is called in the base class it is returning 0.

Is this correct?

j

scthom

  • Citizen of the Universe
  • *****
  • Posts: 621
Re: New Input (Decoder) Interface 11.1.146+
« Reply #10 on: March 21, 2006, 08:15:02 pm »

If I understand the class object model correctly (which is entirely not possible  ?), then that's not right.

Once I use MJInputSource as a a base class, my class contains all of the same data objects and functions as the base class by default.  When I override the n_LengthBlocks in my class, it replaces the one in the base class.  For example, I could redefine it as a long int instead of an int.  In this case, I am not changing the definition, but leaving it as an int. 

Same goes for functions, so that if I define a new AddDataToBuffer function, it will use the one from my class as opposed to the one from the base class.  This is why I asked the question about the virtual functions in above posts (because virtual implies that the base class does not implement it and that my class must override and implement it).

All of that is true unless I explicitly use the base class by doing a dereference (MJInputSource::AddDataToBuffer or MJInputSource::n_LengthBlocks).  Then it uses the one from the class that I dereference (the base class in this case).

So what happens in the FLAC plugin is that I have to override the n_LengthBlocks in my class, but I have to let the base class respond by doing a MJInputSource::GetInformation(nInfoID = 12, pResult) and let the base class respond with the n_LengthBlocks information.  If I do the response (same n_LengthBlocks, same _sprintf response) then it doesn't work.

I tried all four possibilities (variable in my class, variable not in my class, respond in my class, respond in base class) and only the variable in my class, respond in base class worked correctly.  Which based on the class object model is not intuitive.

PS I don't have a degree in computer science but I did sleep at a Holiday Inn Express last night ( ;D)
Logged

John Gateley

  • Citizen of the Universe
  • *****
  • Posts: 4957
  • Nice haircut
Re: New Input (Decoder) Interface 11.1.146+
« Reply #11 on: March 22, 2006, 09:54:49 am »

(I didn't sleep much last night, up late doing taxes).

There are virtual function, but there are no virtual variables.
Here's a code snippet to show the difference.

class CBase {
  int m_Var;
public:
  CBase() { m_Var = 1; }
  int virtual Get1() { return m_Var; }
  int virtual Get2() { return 0; }
};

class CDerived : public CBase {
  int m_Var;
public:
  CDerived() { m_Var = 2; }
  int virtual Get2() { return m_Var; }
};

  CDerived Foo;
  printf("Case 1: %d\n", Foo.Get1());
  printf("Case 2: %d\n", Foo.Get2());

This prints:

Case 1: 1
Case 2: 2

In particular: Get1 (which is not overridden in CDerived) can
never access the m_Var of CDerived. In fact, there is no way
to write a function in CBase which accesses the variables
of CDerived. You must access these via virtual functions that
are overriden by CDerived.

So the original question is: why does returning 0 for m_nInputLengthBlocks
work?

j

scthom

  • Citizen of the Universe
  • *****
  • Posts: 621
Re: New Input (Decoder) Interface 11.1.146+
« Reply #12 on: March 22, 2006, 09:04:22 pm »

Why are you asking me, your kung fu is clearly stronger than mine  :P

I see what you mean about virtual variables not existing.  I told you it was entirely possible my understanding was wrong  :(  But technically, shouldn't Get1 in CBase not be virtual (since it's not overridden in the derived class), and same for Get2 in CDerived?  I guess because you've implemented them anyway it's not a problem.

So having my own m_nLengthBlocks prevents my class from using the base class one and updating it with correct data.  Then tossing the response to the base class causes MJInputSource to respond with the data in it's own m_nLengthBlocks, which is zero.

Maybe because anything other than zero is causing a problem?  That would be inside MC somewhere, so you'd think if it works in the other plugins it would work in mine, and vice versa if it doesn't work.  It only affects the burn to CD decoding and not the playing decoding.  And I believe only affects the length of the burn, since the portion that does get burned is correctly decoded, and I don't use it anywhere inside the plugin.
Logged

scthom

  • Citizen of the Universe
  • *****
  • Posts: 621
Re: New Input (Decoder) Interface 11.1.146+
« Reply #13 on: March 22, 2006, 09:42:52 pm »

Just had a thought, and double checked.

Zero is not what is getting sent back, it's -1.  The constructor in the base class initialized m_nLengthBlocks to -1.

I'll also double check that my definition of blocks was the same as yours (it's possible it works when I respond but I was giving the wrong size).  It's confusing because flac uses the term blocks all over the place and I bet I was giving you the wrong value.

That at least would explain why it doesn't work when I respond -- because I had the wrong size.

But there must be logic inside MC to still burn when it's not handled (-1).  So what happens when it doesn't know the block length?
Logged

scthom

  • Citizen of the Universe
  • *****
  • Posts: 621
Re: New Input (Decoder) Interface 11.1.146+
« Reply #14 on: March 22, 2006, 10:18:04 pm »

Not sure if your question is still out there, but I was right, I'm a bonehead.  Your block and my block were different, exactly 4 times.  Which is exactly the factor that the songs were short on the CDs.

Version 1.6.1 of the decoder now correctly handles the burn and the block length.

Thanks for talking this through.
Logged

John Gateley

  • Citizen of the Universe
  • *****
  • Posts: 4957
  • Nice haircut
Re: New Input (Decoder) Interface 11.1.146+
« Reply #15 on: March 23, 2006, 09:51:52 am »

Good deal, all settled then?

I made the Get1 virtual - it's a nice technique: make a virtual function with a default implementation that works most of the time, and then only override it when necessary. Often the base virtual function is a default: return a default value or something, and so any class that doesn't override it will do something reasonable, and classes that do override it provide the proper behavior.

j

scthom

  • Citizen of the Universe
  • *****
  • Posts: 621
Re: New Input (Decoder) Interface 11.1.146+
« Reply #16 on: March 23, 2006, 06:14:29 pm »

John, we're not done.  I thought it was OK.  I burned a CD last night and all seemed well but as I listened to it today there's some weird artifacts at the transitions, and the lengths are still messed up somewhere.  For those users out there still following this - use 1.6.0 not 1.6.1.

I copied from the SDK (MJRAWInputSource) directly, so I'm not sure.

How does MC use the LengthBlocks information differently if I return it as opposed to when I returned -1 ??  That is, what advantage is there to returning it at all?

[Later]
I've got it now, but there's still a conceptual bust.  The SDK (raw wav data) does not implement m_nLengthBlocks at all.  It uses m_nLengthMS as total blocks / sample rate / 1000.  Where total blocks is total "wide samples" in bytes (e.g. a sample from each channel -- NOTE: flac calls this a single sample).  For the SDK it actually calculates this from the file length in bytes.

But for a compressed file, I can't do that.  Duration depends on total samples, so I have to compute it as TotalWideSamples / SampleRate / 1000.  I think playback of a file uses this, because this seems to work fine.

My two incorrect assumptions were:
1. That the SDK was literally correct, and I was using TotalSamples / BlockAlign, which gave me 1/4 of the right number.  The burns were coming off with 25% of the right length, even though lengthMS was correct.
2. That the SDK was literally correct in the other way, and I was using TotalBytes / BlockAlign, which gave me about 60% of the right length, even though LengthMS was correct.

The correct way, is simply that m_nLengthBlocks is the TotalWideSamples.  You could have picked a better name for that variable ;D
Logged

John Gateley

  • Citizen of the Universe
  • *****
  • Posts: 4957
  • Nice haircut
Re: New Input (Decoder) Interface 11.1.146+
« Reply #17 on: March 24, 2006, 10:56:10 am »

Hi Scot,

The code that uses the m_nLengthBlocks looks like:

if(NumberBlocks < 0 && NumberMilliseconds > 0)
{
  Figure Length from Milliseconds
}
else
{
   Use blocks to figure length
}

This is why the "-1" was working, and using a value wasn't.

I think the key here is to realize that "block" is the same as "sample" (and sample may have been a better choice). "Number of blocks" / "block alignment" doesn't really make sense (that's the number you had that was off by a factor of 4), I'm not sure why number of bytes / block alignment didn't give the correct number of samples.

j

scthom

  • Citizen of the Universe
  • *****
  • Posts: 621
Re: New Input (Decoder) Interface 11.1.146+
« Reply #18 on: March 24, 2006, 06:27:15 pm »

I guess my question would be "why is LengthBlocks even needed?".  We already needed LengthMS for playing, seeking, and other file info.

I think total bytes only works on raw wav files -- for the compressed file, the file length is obviously not directly related to the number of samples.
Logged
Pages: [1]   Go Up