Skip to main content
Topic: Non-compliant cuesheet handling discussion (Read 12114 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Non-compliant cuesheet handling discussion

I am unable to load certain forms of CUE file created by EAC in this version. The error message is as follows:

Unable to open item for playback (Error parsing cuesheet: invalid index list (line 39)):

This behavior is new in 0.9.4, previously the same QUE sheet would load (but would play the same track twice) so you can argue the new behavior is an improvement 

Here is an example CUE sheet that will now cause Foobar2000 to barf:

Code: [Select]
REM GENRE Classical
REM DATE 2005
REM DISCID E60B7311
REM COMMENT "ExactAudioCopy v0.95b4"
PERFORMER "Ricercar Consorft - Philippe Pierlot"
TITLE "Bach - Actus tragicus"
FILE "Gleichwie der Regen und Schnee vom Himmel fällt  (BWV 18) - Sinfonia.wav" WAVE
  TRACK 01 AUDIO
TITLE "Gleichwie der Regen und Schnee vom Himmel fällt  (BWV 18) - Sinfonia"
PERFORMER "Ricercar Consorft - Philippe Pierlot"
INDEX 01 00:00:00
FILE "Recitativo - Gleichwie der Regen und Schnee vom Himmel fällt.wav" WAVE
  TRACK 02 AUDIO
TITLE "Recitativo - Gleichwie der Regen und Schnee vom Himmel fällt"
PERFORMER "Ricercar Consorft - Philippe Pierlot"
INDEX 01 00:00:00
FILE "Recitativo - Mein Gott, hier wird mein Herze sein.wav" WAVE
  TRACK 03 AUDIO
TITLE "Recitativo - Mein Gott, hier wird mein Herze sein"
PERFORMER "Ricercar Consorft - Philippe Pierlot"
INDEX 01 00:00:00
FILE "Aria - Mein Seelenschatz ist Gottes Wort.wav" WAVE
  TRACK 04 AUDIO
TITLE "Aria - Mein Seelenschatz ist Gottes Wort"
PERFORMER "Ricercar Consorft - Philippe Pierlot"
INDEX 01 00:00:00
FILE "Choral - Ich bitt, o Herr, aus Herzens Grund.wav" WAVE
  TRACK 05 AUDIO
TITLE "Choral - Ich bitt, o Herr, aus Herzens Grund"
PERFORMER "Ricercar Consorft - Philippe Pierlot"
INDEX 01 00:00:00
  TRACK 06 AUDIO
TITLE "Gottes Zeit ist die allerbeste Zeit (Actus tragicus, BWV 106) - Sonatina"
PERFORMER "Ricercar Consorft - Philippe Pierlot"
INDEX 00 01:09:45
FILE "Gottes Zeit ist die allerbeste Zeit (Actus tragicus, BWV 106) - Sonatina.wav" WAVE
INDEX 01 00:00:00
FILE "Coro con Choral - Gottes Zeit ist die allerbeste Zeit.wav" WAVE
  TRACK 07 AUDIO  [color=#3333FF]<---------Line 39[/color]
TITLE "Coro con Choral - Gottes Zeit ist die allerbeste Zeit"
PERFORMER "Ricercar Consorft - Philippe Pierlot"
INDEX 01 00:00:00
FILE "Lento-Vivace-Andante - Ach, Herr, lehre uns bedenken.wav" WAVE
  TRACK 08 AUDIO
TITLE "Lento-Vivace-Andante - Ach, Herr, lehre uns bedenken"
PERFORMER "Ricercar Consorft - Philippe Pierlot"
INDEX 01 00:00:00
FILE "Aria - In deine Hände befehl ich meinen Geist.wav" WAVE
  TRACK 09 AUDIO
TITLE "Aria - In deine Hände befehl ich meinen Geist"
PERFORMER "Ricercar Consorft - Philippe Pierlot"
INDEX 01 00:00:00
FILE "Coro - Glorie, Lob, Ehr und Herrlichkeit.wav" WAVE
  TRACK 10 AUDIO
TITLE "Coro - Glorie, Lob, Ehr und Herrlichkeit"
PERFORMER "Ricercar Consorft - Philippe Pierlot"
INDEX 01 00:00:00
  TRACK 11 AUDIO
TITLE "Nach dir, Herr, verlanget mich (BWV 150) - Sinfonia"
PERFORMER "Ricercar Consorft - Philippe Pierlot"
INDEX 00 02:26:45
FILE "Nach dir, Herr, verlanget mich (BWV 150) - Sinfonia.wav" WAVE
INDEX 01 00:00:00
FILE "Coro - Nach dir, Herr, verlanget mich.wav" WAVE
  TRACK 12 AUDIO
TITLE "Coro - Nach dir, Herr, verlanget mich"
PERFORMER "Ricercar Consorft - Philippe Pierlot"
INDEX 01 00:00:00
FILE "Aria - Doch bin und bleibe ich vergnügt.wav" WAVE
  TRACK 13 AUDIO
TITLE "Aria - Doch bin und bleibe ich vergnügt"
PERFORMER "Ricercar Consorft - Philippe Pierlot"
INDEX 01 00:00:00
FILE "Coro - Leite mich in deiner Wahrheit.wav" WAVE
  TRACK 14 AUDIO
TITLE "Coro - Leite mich in deiner Wahrheit"
PERFORMER "Ricercar Consorft - Philippe Pierlot"
INDEX 01 00:00:00
FILE "Aria - Zedern müssen von den Winden.wav" WAVE
  TRACK 15 AUDIO
TITLE "Aria - Zedern müssen von den Winden"
PERFORMER "Ricercar Consorft - Philippe Pierlot"
INDEX 01 00:00:00
FILE "Coro - Meine Augen sehen stets zu dem Herrn.wav" WAVE
  TRACK 16 AUDIO
TITLE "Coro - Meine Augen sehen stets zu dem Herrn"
PERFORMER "Ricercar Consorft - Philippe Pierlot"
INDEX 01 00:00:00
  TRACK 17 AUDIO
TITLE "Ciaccona - Meine Tage in dem Leide"
PERFORMER "Ricercar Consorft - Philippe Pierlot"
INDEX 00 02:10:12
FILE "Ciaccona - Meine Tage in dem Leide.wav" WAVE
INDEX 01 00:00:00


Thanks for any comments

--dsdreamer

Non-compliant cuesheet handling discussion

Reply #1
@dsdreamer : use [codebox] please.

 

Non-compliant cuesheet handling discussion

Reply #2
@dsdreamer

It's a non-compliant cuesheet.

Non-compliant cuesheet handling discussion

Reply #3
@dsdreamer

It's a non-compliant cuesheet.


Yes, you are right.  So what is the best thing to do here: be standards compliant but perhaps not live up to users' expectations (however unreasonable), or find a way to go with the flow as Burrn does?

I think my answer to the above differs from what the authors of Foobar2000 think, and that's their right. The problem is that EAC isn't going to change anytime soon in this respect, either.  Oh well.

--dsdreamer

Non-compliant cuesheet handling discussion

Reply #4
When ripping CDs as track files, then it only makes sence to use the default way of appending the pause areas between tracks to the previous track, as it emulates a stand alone CD player the most. The cuesheets that matches this way of ripping is unfortunetly non-compliant, but i would then recommend that for playback, then you just load the tracks into fb2k without the cuesheets, and then first when you want to burn an album, then you can load the non-compliant cuesheets into a burning app that supports them like eg. Burrrn or EAC.

Non-compliant cuesheet handling discussion

Reply #5
My Way to handle non-compliant cue-sheets:

Code: [Select]
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.LinkedList;

public class Cue2Compliant {

private static final int START = 0;
private static final int HEADERPASSED = 1;
private static final int FILEPASSED = 2;
private static final int TRACKPASSED =3;
private static final int INDEX00PASSED = 4;
private static final int INDEX01PASSED = 5;

private static final String FILE="FILE";
private static final String TRACK = "TRACK";
private static final String INDEX00 = "INDEX 00";
private static final String INDEX01 = "INDEX 01";

private static final String REMPAUSE = "REM PAUSE";

public Cue2Compliant(String path) {
File f = new File (path);
cue2Compliant(f);
}

private void cue2Compliant(File f) {
try {
if (f.isDirectory()) {
dir2Compliant(f);
} else {
file2Compliant(f);
}
} catch (Exception e) {
System.out.println(e.toString());
}
}

private void dir2Compliant(File dir){
File f [] = dir.listFiles();
for (int i = 0; i < f.length; i++) {
cue2Compliant(f[i]);
}
}

private void file2Compliant(File f){
String name = f.getName();
if (!name.toLowerCase().endsWith(".cue")) {
return;
}
System.out.println ("Progressing: " + f.getAbsolutePath());
process (f);
}

private void process (File f) {
try {
BufferedReader br = new BufferedReader(new FileReader (f));
LinkedList clean = new LinkedList ();
int state = START;
int trackLink = -1;
int index00Link = -1;
while (br.ready()) {
String line = br.readLine();
String lineT = line.trim().toUpperCase();
switch (state) {
case START:
if (lineT.startsWith(FILE)) {
state = FILEPASSED;
}
clean.add(line);
break;
case FILEPASSED:
if (lineT.startsWith(TRACK)) {
state = TRACKPASSED;
trackLink = clean.size();
}
clean.add(line);
break;
case TRACKPASSED:
if (lineT.startsWith(INDEX00)) {
state = INDEX00PASSED;
index00Link = clean.size();
} else if (lineT.startsWith(INDEX01)) {
state = INDEX01PASSED;
} else if (lineT.startsWith(TRACK)) {
trackLink = clean.size();
}
clean.add(line);
break;
case INDEX01PASSED:
if (lineT.startsWith(TRACK)) {
state = TRACKPASSED;
trackLink = clean.size();
} else if (lineT.startsWith(FILE)) {
state = FILEPASSED;
}
clean.add(line);
break;
case INDEX00PASSED:
if (lineT.startsWith(INDEX01)) {
state = INDEX01PASSED;
clean.add(line);
} else if (lineT.startsWith(FILE)){
LinkedList tmp = new LinkedList();
state = FILEPASSED;
for (int i = clean.size()-1;  i >= index00Link; i--) {
String moveLine = (String) clean.remove(i);
String moveLineT = moveLine.trim().toUpperCase();
if (moveLineT.startsWith(INDEX00)) {
moveLine = moveLine.substring(0, moveLine.toUpperCase().indexOf(INDEX00)) + REMPAUSE + moveLineT.substring(INDEX00.length());
}
tmp.add(0, moveLine);
}
for (int i = 0; i < tmp.size(); i++) {
clean.add(trackLink + i, tmp.get(i));
}
clean.add(trackLink + tmp.size(), line);
} else {
clean.add(line);
}
}
}
br.close();
f.createNewFile();
BufferedWriter bw = new BufferedWriter(new FileWriter(f));
for (int i = 0; i < clean.size(); i++) {
bw.write((String)clean.get(i));
bw.newLine();
}
bw.close();

} catch (Exception e) {
System.out.println(e.toString());
}

}
public static void main(String[] args) {

if (args.length != 1) {
System.out.println("Usage: Cue2Compliant <cue-file>");
System.out.println("Usage: Cue2Compliant <directory>");
System.exit(1);
}
Cue2Compliant cue = new Cue2Compliant(args[0]);

}

}
Code: [Select]
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.LinkedList;

public class Cue2NonCompliant {

private static final int START = 0;
private static final int HEADERPASSED = 1;
private static final int FILEPASSED = 2;
private static final int TRACKPASSED =3;
private static final int INDEX00PASSED = 4;
private static final int INDEX01PASSED = 5;
private static final int PAUSEPASSED = 6;
private static final int PAUSEFILEPASSED = 7;

private static final String FILE="FILE";
private static final String TRACK = "TRACK";
private static final String INDEX00 = "INDEX 00";
private static final String INDEX01 = "INDEX 01";
private static final String REMPAUSE = "REM PAUSE";

public Cue2NonCompliant(String path) {
File f = new File (path);
cue2NonCompliant(f);
}

private void cue2NonCompliant(File f) {
try {
if (f.isDirectory()) {
dir2NonCompliant(f);
} else {
file2NonCompliant(f);
}
} catch (Exception e) {
System.out.println(e.toString());
}
}

private void dir2NonCompliant(File dir){
File f [] = dir.listFiles();
for (int i = 0; i < f.length; i++) {
cue2NonCompliant(f[i]);
}
}

private void file2NonCompliant(File f){
String name = f.getName();
if (!name.toLowerCase().endsWith(".cue")) {
return;
}
System.out.println ("Progressing: " + f.getAbsolutePath());
process (f);
}

private void process (File f) {
try {
BufferedReader br = new BufferedReader(new FileReader (f));
LinkedList clean = new LinkedList ();
LinkedList tmp = null;
int state = START;
while (br.ready()) {
String line = br.readLine();
String lineT = line.trim().toUpperCase();
switch (state) {
case START:
if (lineT.startsWith(FILE)) {
state = FILEPASSED;
}
clean.add(line);
break;
case FILEPASSED:
if (lineT.startsWith(TRACK)) {
state = TRACKPASSED;
}
clean.add(line);
break;
case TRACKPASSED:
if (lineT.startsWith(INDEX01)) {
state = INDEX01PASSED;
}
clean.add(line);
break;
case INDEX01PASSED:
if (lineT.startsWith(REMPAUSE)) {
state = PAUSEPASSED;
tmp = new LinkedList();
line = line.substring(0, line.toUpperCase().indexOf(REMPAUSE)) + INDEX00 + lineT.substring(REMPAUSE.length());
tmp.add(line);
} else if (lineT.startsWith(FILE)) {
state = FILEPASSED;
clean.add(line);
} else {
clean.add(line);
}
break;
case PAUSEPASSED:
if (lineT.startsWith(FILE)) {
state = PAUSEFILEPASSED;
}
tmp.add(line);
break;
case PAUSEFILEPASSED:
if (lineT.startsWith(INDEX01)) {
state = INDEX01PASSED;
for (int i = 0; i < tmp.size(); i++) {
clean.add(tmp.get(i));
}
}
clean.add(line);
break;
}
}
br.close();
f.createNewFile();
BufferedWriter bw = new BufferedWriter(new FileWriter(f));
for (int i = 0; i < clean.size(); i++) {
bw.write((String)clean.get(i));
bw.newLine();
}
bw.close();

} catch (Exception e) {
System.out.println(e.toString());
}

}
public static void main(String[] args) {

if (args.length != 1) {
System.out.println("Usage: Cue2NonCompliant <cue-file>");
System.out.println("Usage: Cue2NonCompliant <directory>");
System.exit(1);
}
Cue2NonCompliant cue = new Cue2NonCompliant(args[0]);

}

}

Non-compliant cuesheet handling discussion

Reply #6
@dsdreamer: support for non-compliant cue sheets was dropped in v0.9 beta 7, so that's a long time ago.

Another way to convert non-compliant cue sheets (and the corresponding seperate wav files at once) is using Moitah's CUETools: http://www.hydrogenaudio.org/forums/index....st&p=368385

EDIT: btw, if you don't want to use a single wav(lossless encoded file) then there's absolutely no need for a cue sheets. just load the seperate tracks directly into foobar and forget about the cue sheet (use "*.CUE" to exclude all cue sheets for example).

Non-compliant cuesheet handling discussion

Reply #7
EDIT: btw, if you don't want to use a single wav(lossless encoded file) then there's absolutely no need for a cue sheets. just load the seperate tracks directly into foobar and forget about the cue sheet (use "*.CUE" to exclude all cue sheets for example).

If you add meta-information into the CUE (e.g REM DATE "1983", REM GENRE "Pop", REM MYTAG "Bla") and you want to use/display/modify this information somehow, it would have been nice, if foobar would support CUEs and these meta-information. In this case, loading the seperate tracks does not help.

Please no "why not doing it this or that way?". It seems, that some people around rip their suff and create non-compliant CUE's. It is sad that some people try to force them to change their way of archiving their music by removing support out of their software.

Non-compliant cuesheet handling discussion

Reply #8
I used to have some "sperate tracks + non-compliant cue sheet" rips myself when I still used fb2k 0.8, but I had to convert them all because I wanted to be up-to-date with the latest fb2k instead of being stuck with v0.9b6.

Now playback support is not the only issue someone with "sperate tracks + non-compliant cue sheet" who's loading the cue sheet files will notice:

When loading the external .cue file then fb2k will only edit this external cue sheet. All meta data that does not fit into a cue sheet (composer, totaldisks, etc) will simply be omitted.

If somone wants to have the full freedom of adding any meta data he wants to lossless rips he must use embedded cue sheets now in case he has a "to single wav"-rip. If he has a "to seperate files"-rip he must use the files directly since embedded cue sheets are not possible with "seperate files". Only when fb2k has loaded the cue sheet from a tag it will add non-cuesheet-specific meta data to (the tags of) the files again.

The only meta data that is supported by cue sheets is this:

track number (TRACK), artist (PERFORMER), album title (global TITLE), year/date (REM DATE), genre (REM GENRE), CATALOG, ISRC, discid (REM DISCID), replaygain info (REM REPLAYGAIN_*_*), album artist (when global PERFORMER and track PERFORMER differ) and of course track title (track's TITLE)... (may be incomplete). Those are the basic things you will need most of the time and they are quite sufficient IMHO... still that's it! REM is not used by fb2k to add more (unsupported) meta data, only exception might be REM COMMENT, I think.

So practically this is just another reason why using "sperate tracks + non-compliant cue sheet" now sucks with fb2k. Personally I made peace with this issue a long time ago and in the end I love using single files+embedded cue sheets.

Non-compliant cuesheet handling discussion

Reply #9
I too have som troubles with non-standard cue-sheets.

The problem would be easy to fix, if it wasn't for the fact that my cue-sheets are in the tags of my APE images (images of whole CDs, not tracks).

Track information is displayed properly, but when trying to play the track, the following comes up:

Code: [Select]
Unable to open item for playback (Error parsing cuesheet: expected WAVE, MP3 or AIFF, got : "APE" (line 3)):
"f:\Selvrippet\Lossless\Sound Tracks\Shine (OST)\Shine (OST) - CD1.APE" / index: 1


And when trying to edit the cue-sheet from Foobar2k, the following comes up

Code: [Select]
Could not write info (Error parsing cuesheet: expected WAVE, MP3 or AIFF, got : "APE" (line 3)) to:
"f:\Selvrippet\Lossless\Sound Tracks\Shine (OST)\Shine (OST) - CD1.APE" / index: 1


This actually is quite lame, as I actually need to open an Hex-editor just to change it, and apparently, Foobar2k is perfectly capable of reading the info in the cue-sheet.

Non-compliant cuesheet handling discussion

Reply #10
Not so lame  because you can edit cuesheet in foobar by only selecting one track of the album/ape file followed by context menu>utils>edit cuesheet.

(Possibly i'm using a plugin which offers the feature)

Non-compliant cuesheet handling discussion

Reply #11
The problem would be easy to fix, if it wasn't for the fact that my cue-sheets are in the tags of my APE images (images of whole CDs, not tracks).

Track information is displayed properly, but when trying to play the track, the following comes up:

Code: [Select]
Unable to open item for playback (Error parsing cuesheet: expected WAVE, MP3 or AIFF, got : "APE" (line 3)):
"f:\Selvrippet\Lossless\Sound Tracks\Shine (OST)\Shine (OST) - CD1.APE" / index: 1
That is foobars punishment. In the case of CUEs I'd say foobar is not an appropriate player for you. I mean, hey, if even geeks get trouble with the cue issue... The cue parser is way too strict and it's sad fb2k refuses to play, as there is otherwise no technical reason not to play the audiofile. This cue story tells a lot about the dark sides of this project.

Non-compliant cuesheet handling discussion

Reply #12
I too have som troubles with non-standard cue-sheets.
...
Code: [Select]
Unable to open item for playback (Error parsing cuesheet: expected WAVE, MP3 or AIFF, got : "APE" (line 3)):
"f:\Selvrippet\Lossless\Sound Tracks\Shine (OST)\Shine (OST) - CD1.APE" / index: 1
This looks like a totally different issue.  It looks like your cuesheets are using:

FILE "\path\to\file\file.ape" APE

This should be:

FILE "\path\to\file\file.ape" WAVE
I'm on a horse.

Non-compliant cuesheet handling discussion

Reply #13
I'm perfectly aware of this, but it's a pain, nonetheless not to be able to edit this in foobar, having to use a Hex-editor instead. It's doubly annoying, since foobar2k apparently is able to extract the information from the cue-sheet, and therefore should not have a problem to playback the track.

Non-compliant cuesheet handling discussion

Reply #14
I'm perfectly aware of this, but it's a pain, nonetheless not to be able to edit this in foobar, having to use a Hex-editor instead.

As I said, you mustn't if you do this manually.

Non-compliant cuesheet handling discussion

Reply #15
why use a hex editor? Cue sheets are just text files.

Non-compliant cuesheet handling discussion

Reply #16

I'm perfectly aware of this, but it's a pain, nonetheless not to be able to edit this in foobar, having to use a Hex-editor instead.

As I said, you mustn't if you do this manually.



This must be some plugin. Any help finding out which plugin it is, will be appreciated (-:

EDIT: Found out, checking my FLACs with external cue-sheets that it isn't a plugin. So the approach apparently doesn't work with non-compliant cue-sheets. (I.e. it's still as lame as before)

Non-compliant cuesheet handling discussion

Reply #17
I too have som troubles with non-standard cue-sheets.
...
Code: [Select]
Unable to open item for playback (Error parsing cuesheet: expected WAVE, MP3 or AIFF, got : "APE" (line 3)):
"f:\Selvrippet\Lossless\Sound Tracks\Shine (OST)\Shine (OST) - CD1.APE" / index: 1
This looks like a totally different issue.  It looks like your cuesheets are using:

FILE "\path\to\file\file.ape" APE

This should be:

FILE "\path\to\file\file.ape" WAVE



I have experienced the same problem described above.  Upgrading from foobar 8.x to 9.x broke the handling of embedded cuesheets.  I figured out what changes were necessary to get the album information to display properly, but it is time-consuming when your library almost entirely consists of single-album "ape" files with embedded cuesheets.

Incidentally, I was just trying to update some such files in foobar2000 0.9.4, but after editing the embedded cuesheet and reloading the file info, the "embedded cuesheet" property (under properties -> general) still reads "no", and the changes don't appear to have taken effect (the individual tracks are not recognized, etc.).  Ah, I've got it working now: it is necessary to rescan the library or remove and then readd the file to the playlist in order for the changes to appear.  Is this a known issue?

 
SimplePortal 1.0.0 RC1 © 2008-2019