Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: How to play HTOA in Foobar? (Read 5989 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

How to play HTOA in Foobar?

Hi,

is there any option / component to detect and display HTOA as a separate track in a file with embedded cue sheet in Foobar? If not, what is commonly done to play HTOA in Foobar? Editing the embedded CUE to make the hidden track a non-hidden one? :)


Thanks a lot

How to play HTOA in Foobar?

Reply #1
I don't know about Foobar, but dBpoweramp allows for HOTA ripping (assuming your drive is capable).

How to play HTOA in Foobar?

Reply #2
ES1998, you may want to actually read the post.

g0a is asking about playing HTOA (i.e. TRACK 01, INDEX 00) in foobar2000.

I don't know of a way to show a 'track 0' or such, but one simple albeit limited solution is to load the audio image on its own (i.e. without the cue sheet). This will begin playback right from the start, rather than from the TRACK 01, INDEX 00 marker.

How to play HTOA in Foobar?

Reply #3
is there any option / component to detect and display HTOA as a separate track in a file with embedded cue sheet in Foobar?

AFAIK, no.

Quote
If not, what is commonly done to play HTOA in Foobar? Editing the embedded CUE to make the hidden track a non-hidden one?

I don't know it this is a common way to handle HTOA, but you can create a seprate edited cue sheet, and if you want to renumber the HTOA track, an APL link file from the edited cue sheet.

For instance, if the original cue sheet starts like this:

Code: [Select]
REM GENRE "Alternative Rock"
REM DATE 2003
PERFORMER "Blur"
TITLE "Think Tank"
FILE "Blur - Think Tank.flac" WAVE
  TRACK 01 AUDIO
    TITLE "Ambulance"
    PERFORMER "Blur"
    INDEX 00 00:00:00
    INDEX 01 06:48:69
  TRACK 02 AUDIO
    TITLE "Out Of Time"
    PERFORMER "Blur"
    INDEX 00 11:56:36
    INDEX 01 11:57:60
...

Create a new cue sheet like this:

Code: [Select]
REM GENRE Alternative Rock
REM DATE 2003
PERFORMER "Blur"
TITLE "Think Tank"
FILE "Blur - Think Tank.flac" WAVE
  TRACK 01 AUDIO
    TITLE "Hidden Track"
    INDEX 01 00:00:00
  TRACK 02 AUDIO
    TITLE "trash this"
    INDEX 01 06:48:69
 

If you want to renumber the HTOA track to be the last track in the album you can create an APL link file set from this new two-track cue album. For APL support you must  have the Monkey's Audio decoding component installed (the audio file doesn't need to be in the Monkey's Audio format).

Later on only the APL file that points to HTOA is needed for playback and storing file tags. You can delete the other files.

How to play HTOA in Foobar?

Reply #4
Interesting post about APL files! They seem to be quite useful for some things like this; I wonder if the format (or something similar) will continue to be supported/updated, since development on Monkey's Audio (barring API/UI fixes) seems quite slow, particularly since 2006.

How to play HTOA in Foobar?

Reply #5
I rip all my CDs to FLAC images including HTOA data with EAC. As far as I know, there is still no extension that would allow to detect HTOA in those FLAC images with foobar2000. The only halfway convenient way to play those tracks is to manually edit the embedded CUE sheets.

How difficult would it be to write an extension that would list HTOA data as track 0 in foobar2000 if the length of the pregap is above a specified limit (an idea I've already mentioned earlier http://www.hydrogenaudio.org/forums/index....t&p=782471). If the limit is set to a very large (default) value no HTOA track 0 would be shown and one would have the current behaviour. This way one could easily play and search as well (!!) for CDs with hidden tracks.

Since I have no experience in writing foobar2000 extensions, I don't know how difficult this would be. Is this too deep in the area of core functions in foobar2000? I have plenty of experience in general programming though - so if some experts think this is doable I might dive into it. So, I'm curious about opinions of more experienced forum members. Thanks in advance. 

How to play HTOA in Foobar?

Reply #6
If you start playing the image .FLAC file rather than the cuesheet, it will start from the beginning.

Of course, you will not be able to skip to the next track without a track boundary.

 

How to play HTOA in Foobar?

Reply #7
The functionality for cue sheet files and embedded cue sheets is contained in the file cue_parser.h in the foobar2000 SDK. This might help finding cue sheets with hidden tracks. Making these tracks accessible - i.e. findable and playable - is another matter however. You cannot change the behaviour of input implementations from another component.

How to play HTOA in Foobar?

Reply #8
Porcus: is there a way of playing a FLAC image without loading the content of the embedded CUE sheet? Couldn't figure out how to do this. So the only way I can play HTOA tracks is by editing the CUE sheet so far.

How to play HTOA in Foobar?

Reply #9
Foosion: From your comment it looks that the "track list" is generated in one of the core functions of foobar2000 and this can not be modified by an extension/component, right? So maybe the main developers could implement this? I mean in pseudo code this would look pretty simple:

if (Time(T01.I01)-Time(T01.I00) > HTOALimit):
    ListTrack(T01.I00,0)

Essentially just a simple if statement. The only new parameter would be the time limit HTOALimit that determines when a hidden track is long enough to be listed as track 0. The ListTrack function (I don't know how this is actually done in foobar2000) takes an index (here T01.I00) and assignes a track number (here 0).

So my guess is this might not be too difficult to implement for the main developers but might be a super-cool new feature . Or do I miss something here?

How to play HTOA in Foobar?

Reply #10
From your comment it looks that the "track list" is generated in one of the core functions of foobar2000 and this can not be modified by an extension/component, right?
Not quite, the code for cue sheet parsing is contained in the SDK itself, more specifically in the foobar2000_sdk_helpers library. This code is compiled into each component that supports cue sheets. So even if this code is changed, every such component needs to be recompiled for the changes to take effect. On the other hand foo_input_std contains the support for cue sheet files and since this comes with the foobar2000 installer, it has to be updated by Peter.

I glanced over the cue sheet code in foobar2000_sdk_helpers and I think the change is not that trivial as you hope it would be. The reason is that the code is based on the design decision that every TRACK in the cue sheet is mapped to a track in foobar2000. Different indexes are represented as meta data in foobar2000 which can be retrieved in title formatting code via the $info() function. Specifically
  • INDEX 01 is available as $info(referenced_offset) if is greater than zero.
  • The difference between INDEX 01 and INDEX 00 is available as $info(pregap) if it is greater than zero.
  • INDEX 02 is available as $info(index 02), INDEX 03 as $info(index 03), etc.
I haven't tested it but it should be like that according to this code from cuesheet_index_list.cpp:
Code: [Select]
void t_cuesheet_index_list::to_infos(file_info & p_out) const
{
double base = m_positions[1];

if (base > 0) {
p_out.info_set("referenced_offset",cuesheet_format_index_time(base));
}

if (m_positions[0] < base)
p_out.info_set("pregap",cuesheet_format_index_time(base - m_positions[0]));
else
p_out.info_remove("pregap");

p_out.info_remove("index 00");
p_out.info_remove("index 01");

for(unsigned n=2;n<count;n++)
{
char namebuffer[16];
sprintf_s(namebuffer,"index %02u",n);
double position = m_positions[n] - base;
if (position > 0)
p_out.info_set(namebuffer,cuesheet_format_index_time(position));
else
p_out.info_remove(namebuffer);
}
}