New API calls burn_drive_extract_audio(), burn_drive_extract_audio_track()

This commit is contained in:
Thomas Schmitt 2013-05-23 15:43:19 +00:00
parent 46ecc07807
commit cf9d506b21
8 changed files with 238 additions and 5 deletions

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2013.05.21.081819" #define Cdrskin_timestamP "2013.05.23.154249"

View File

@ -27,6 +27,7 @@
#include "file.h" #include "file.h"
#include "async.h" #include "async.h"
#include "init.h" #include "init.h"
#include "util.h"
#include "libdax_msgs.h" #include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger; extern struct libdax_msgs *libdax_messenger;
@ -919,3 +920,161 @@ struct burn_source *burn_offst_source_new(
return src; return src;
} }
/* -------------------- WAVE file extractor ------------------- */
/* ts B30522 */
/* API
@param flag Bitfield for control purposes:
bit0= Report about progress by UPDATE message
bit3= Enable DAP : "flaw obscuring mechanisms like
audio data mute and interpolate"
*/
int burn_drive_extract_audio(struct burn_drive *drive,
int start_sector, int sector_count,
char *target_path, int flag)
{
int fd = -1, ret, todo, sector_no, val, min, sec, fr;
int sectors_done= 0, last_reported = 0;
off_t data_size, data_count = 0;
time_t last_pacified = 0, now;
char *msg = NULL, *buf = NULL;
BURN_ALLOC_MEM(msg, char, 4096);
BURN_ALLOC_MEM(buf, char, 24 * 2352);
fd = open(target_path, O_WRONLY | O_CREAT,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if (fd == -1) {
sprintf(msg, "Cannot open disk file for writing: %.4000s",
target_path);
libdax_msgs_submit(libdax_messenger, -1, 0x000201a1,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
msg, errno, 0);
ret = 0; goto ex;
}
/* WAV header */
strcpy(buf, "RIFF");
val = 4 + 8 + 16 + 8 + sector_count * 2352; /* ChunkSize */
burn_int_to_lsb(val, buf + 4);
strcpy(buf + 8, "WAVE");
strcpy(buf + 12, "fmt ");
burn_int_to_lsb(16, buf + 16); /* Subchunk1Size */
buf[20] = 1; /* AudioFormat */
buf[21] = 0;
buf[22] = 2; /* NumChannels */
buf[23] = 0;
burn_int_to_lsb(44100, buf + 24); /* SampleRate */
burn_int_to_lsb(176400, buf + 28); /* ByteRate */
buf[32] = 4; /* BlockAlign */
buf[33] = 0;
buf[34] = 16; /* BitsPerSample */
buf[35] = 0;
strcpy(buf + 36, "data");
burn_int_to_lsb(sector_count * 2352, buf + 40); /* Subchunk2Size */
ret = write(fd, buf, 44);
if (ret == -1)
goto write_error;
/* Audio data */
todo = sector_count;
sector_no = start_sector;
while (todo > 0) {
if (todo > 24)
data_size = 24 * 2352;
else
data_size = todo * 2352;
ret = burn_read_audio(drive, sector_no, buf, data_size,
&data_count, flag & 8);
if (ret <= 0) {
sprintf(msg, "Failure to read audio sectors");
libdax_msgs_submit(libdax_messenger, -1, 0x000201a4,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
goto ex;
}
ret = write(fd, buf, data_count);
if (ret == -1) {
write_error:;
sprintf(msg,
"Error while writing to disk file: %.4000s",
target_path);
libdax_msgs_submit(libdax_messenger, -1, 0x000201a2,
LIBDAX_MSGS_SEV_FAILURE,
LIBDAX_MSGS_PRIO_HIGH,
msg, errno, 0);
ret = 0; goto ex;
}
todo -= data_count / 2352;
sectors_done += data_count / 2352;
sector_no += data_count / 2352;
if ((flag & 1) && (now = time(NULL)) - last_pacified >= 1) {
last_pacified = now;
burn_lba_to_msf(sectors_done, &min, &sec, &fr);
sprintf(msg,
"Minutes:seconds of audio data read: %2d:%2.2d (%6.2f MB)",
min, sec,
((double) sectors_done) * 2352.0 / 1048576.0);
libdax_msgs_submit(libdax_messenger, -1, 0x000201a3,
LIBDAX_MSGS_SEV_UPDATE,
LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 1);
last_reported = sectors_done;
}
}
if ((flag & 1)) {
burn_lba_to_msf(sectors_done, &min, &sec, &fr);
sprintf(msg,
"Minutes:seconds of audio data read: %2d:%2.2d (%6.2f MB)",
min, sec, ((double) sectors_done) * 2352.0 / 1048576.0);
libdax_msgs_submit(libdax_messenger, -1, 0x000201a3,
LIBDAX_MSGS_SEV_UPDATE,
LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
last_reported = sectors_done;
}
ret = 1;
ex:;
BURN_FREE_MEM(buf);
BURN_FREE_MEM(msg);
if (fd != -1)
close(fd);
return ret;
}
/* ts B30522 */
/* API
@param flag Bitfield for control purposes:
bit0= Report about progress by UPDATE message
bit3= Enable DAP : "flaw obscuring mechanisms like
audio data mute and interpolate"
*/
int burn_drive_extract_audio_track(struct burn_drive *drive,
struct burn_track *track,
char *target_path, int flag)
{
int ret;
struct burn_toc_entry toc_entry;
burn_track_get_entry(track, &toc_entry);
if (!(toc_entry.extensions_valid & 1)) {
/* Can only happen if burn_disc_cd_toc_extensions() is skipped
in mmc_read_toc_al().
*/
libdax_msgs_submit(libdax_messenger, -1, 0x00000004,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Internal libburn error: Outdated burn_toc_entry format encountered",
errno, 0);
return -1;
}
ret = burn_drive_extract_audio(drive, toc_entry.start_lba,
toc_entry.track_blocks,
target_path, flag & (1 | 8));
return ret;
}

View File

@ -2273,7 +2273,7 @@ int burn_cdtext_from_session(struct burn_session *s,
array of packs shall be removed. array of packs shall be removed.
@param num_packs The number of 18 byte packs in text_packs. @param num_packs The number of 18 byte packs in text_packs.
@param start_tno The start number of track counting, if known from @param start_tno The start number of track counting, if known from
CD table-of-content or orther sources. CD table-of-content or other sources.
Submit 0 to enable the attempt to read it and the Submit 0 to enable the attempt to read it and the
track_count from pack type 0x8f. track_count from pack type 0x8f.
@param track_count The number of tracks, if known from CD table-of-content @param track_count The number of tracks, if known from CD table-of-content
@ -3922,6 +3922,49 @@ int burn_read_audio(struct burn_drive *d, int sector_no,
char data[], off_t data_size, off_t *data_count, int flag); char data[], off_t data_size, off_t *data_count, int flag);
/* ts B30522 */
/** Extract an interval of audio sectors from CD and store it as a WAVE
audio file on hard disk.
@param drive The drive from which to read.
@param start_sector The logical block address of the first audio sector
which shall be read.
@param sector_count The number of audio sectors to be read.
Each sector consists of 2352 bytes.
@param target_path The address of the file where to store the extracted
audio data. Will be opened O_WRONLY | O_CREAT.
The file name should have suffix ".wav".
@param flag Bitfield for control purposes:
bit0= Report about progress by UPDATE messages
bit3= Enable DAP : "flaw obscuring mechanisms like
audio data mute and interpolate"
@since 1.3.2
*/
int burn_drive_extract_audio(struct burn_drive *drive,
int start_sector, int sector_count,
char *target_path, int flag);
/* ts B30522 */
/** Extract all audio sectors of a track from CD and store them as a WAVE
audio file on hard disk.
@param drive The drive from which to read.
@param track The track which shall be extracted.
@param target_path The address of the file where to store the extracted
audio data. Will be opened O_WRONLY | O_CREAT.
The file name should have suffix ".wav".
@param flag Bitfield for control purposes:
bit0= Report about progress by UPDATE messages
bit3= Enable DAP : "flaw obscuring mechanisms like
audio data mute and interpolate"
@since 1.3.2
*/
int burn_drive_extract_audio_track(struct burn_drive *drive,
struct burn_track *track,
char *target_path, int flag);
/* ts A70904 */ /* ts A70904 */
/** Inquire whether the drive object is a real MMC drive or a pseudo-drive /** Inquire whether the drive object is a real MMC drive or a pseudo-drive
created by a stdio: address. created by a stdio: address.
@ -4080,7 +4123,7 @@ int libdax_audioxtr_read(struct libdax_audioxtr *xtr,
/** Try to obtain a file descriptor which will deliver extracted data /** Try to obtain a file descriptor which will deliver extracted data
to normal calls of read(2). This may fail because the format is to normal calls of read(2). This may fail because the format is
unsuitable for that, but ".wav" is ok. If this call succeeds the xtr unsuitable for that, but WAVE (.wav) is ok. If this call succeeds the xtr
object will have forgotten its file descriptor and libdax_audioxtr_read() object will have forgotten its file descriptor and libdax_audioxtr_read()
will return a usage error. One may use *fd after libdax_audioxtr_destroy() will return a usage error. One may use *fd after libdax_audioxtr_destroy()
and will have to close it via close(2) when done with it. and will have to close it via close(2) when done with it.

View File

@ -44,6 +44,8 @@ burn_drive_convert_fs_adr;
burn_drive_convert_scsi_adr; burn_drive_convert_scsi_adr;
burn_drive_d_get_adr; burn_drive_d_get_adr;
burn_drive_equals_adr; burn_drive_equals_adr;
burn_drive_extract_audio;
burn_drive_extract_audio_track;
burn_drive_free_speedlist; burn_drive_free_speedlist;
burn_drive_get_adr; burn_drive_get_adr;
burn_drive_get_all_profiles; burn_drive_get_all_profiles;

View File

@ -327,6 +327,11 @@ int libdax_msgs__sev_to_text(int severity, char **severity_name,
} }
/*
@param flag Bitfield for control purposes
bit0= If direct output to stderr:
CarriageReturn rather than LineFeed
*/
int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code, int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code,
int severity, int priority, char *msg_text, int severity, int priority, char *msg_text,
int os_errno, int flag) int os_errno, int flag)
@ -345,7 +350,8 @@ int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code,
if(ret>0) if(ret>0)
sprintf(sev_text,"%s : ",sev_name); sprintf(sev_text,"%s : ",sev_name);
fprintf(stderr,"%s%s%s\n",m->print_id,sev_text,textpt); fprintf(stderr, "%s%s%s%c", m->print_id, sev_text, textpt,
(flag & 1) ? '\r' : '\n');
if(os_errno!=0) { if(os_errno!=0) {
ret= libdax_msgs_lock(m,0); ret= libdax_msgs_lock(m,0);
if(ret<=0) if(ret<=0)

View File

@ -302,7 +302,9 @@ int libdax_msgs_refer(struct libdax_msgs **pt, struct libdax_msgs *o, int flag);
@param priority The LIBDAX_MSGS_PRIO_* number of the event. @param priority The LIBDAX_MSGS_PRIO_* number of the event.
@param msg_text Printable and human readable message text. @param msg_text Printable and human readable message text.
@param os_errno Eventual error code from operating system (0 if none) @param os_errno Eventual error code from operating system (0 if none)
@param flag Bitfield for control purposes (unused yet, submit 0) @param flag Bitfield for control purposes
bit0= If direct output to stderr:
CarriageReturn rather than LineFeed
@return 1 on success, 0 on rejection, <0 for severe errors @return 1 on success, 0 on rejection, <0 for severe errors
*/ */
int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code, int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code,
@ -600,6 +602,10 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x0002019e (NOTE,HIGH) = Drive does not support media certification 0x0002019e (NOTE,HIGH) = Drive does not support media certification
0x0002019f (FAILURE,HIGH) = CD-TEXT binary pack array faulty 0x0002019f (FAILURE,HIGH) = CD-TEXT binary pack array faulty
0x000201a0 (WARNING,HIGH) = Maximum number of CD-TEXT blocks exceeded 0x000201a0 (WARNING,HIGH) = Maximum number of CD-TEXT blocks exceeded
0x000201a1 (FAILURE,HIGH) = Cannot open disk file for writing
0x000201a2 (FAILURE,HIGH) = Error while writing to disk file
0x000201a3 (UPDATE,HIGH) = Progress message of burn_drive_extract_audio()
0x000201a4 (FAILURE,HIGH) = Failure to read audio sectors
libdax_audioxtr: libdax_audioxtr:

View File

@ -328,3 +328,17 @@ char *burn_printify(char *msg)
return msg; return msg;
} }
/* ts B30521 */
void burn_int_to_lsb(int val, char *target)
{
unsigned char *buf;
buf = (unsigned char *) target;
buf[0] = val & 0xff;
buf[1] = (val >> 8) & 0xff;
buf[2] = (val >> 16) & 0xff;
buf[3] = (val >> 24) & 0xff;
}

View File

@ -8,4 +8,7 @@ int burn_util_make_printable_word(char **text, int flag);
char *burn_sfile_fgets(char *line, int maxl, FILE *fp); char *burn_sfile_fgets(char *line, int maxl, FILE *fp);
char *burn_printify(char *msg); char *burn_printify(char *msg);
/* ts B30521 */
void burn_int_to_lsb(int val, char *target);
#endif #endif