New API calls burn_drive_extract_audio(), burn_drive_extract_audio_track()
This commit is contained in:
parent
1887b0b938
commit
167d73e268
@ -1 +1 @@
|
||||
#define Cdrskin_timestamP "2013.05.21.081819"
|
||||
#define Cdrskin_timestamP "2013.05.23.154249"
|
||||
|
159
libburn/file.c
159
libburn/file.c
@ -27,6 +27,7 @@
|
||||
#include "file.h"
|
||||
#include "async.h"
|
||||
#include "init.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "libdax_msgs.h"
|
||||
extern struct libdax_msgs *libdax_messenger;
|
||||
@ -919,3 +920,161 @@ struct burn_source *burn_offst_source_new(
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -2273,7 +2273,7 @@ int burn_cdtext_from_session(struct burn_session *s,
|
||||
array of packs shall be removed.
|
||||
@param num_packs The number of 18 byte packs in text_packs.
|
||||
@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
|
||||
track_count from pack type 0x8f.
|
||||
@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);
|
||||
|
||||
|
||||
/* 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 */
|
||||
/** Inquire whether the drive object is a real MMC drive or a pseudo-drive
|
||||
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
|
||||
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()
|
||||
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.
|
||||
|
@ -44,6 +44,8 @@ burn_drive_convert_fs_adr;
|
||||
burn_drive_convert_scsi_adr;
|
||||
burn_drive_d_get_adr;
|
||||
burn_drive_equals_adr;
|
||||
burn_drive_extract_audio;
|
||||
burn_drive_extract_audio_track;
|
||||
burn_drive_free_speedlist;
|
||||
burn_drive_get_adr;
|
||||
burn_drive_get_all_profiles;
|
||||
|
@ -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 severity, int priority, char *msg_text,
|
||||
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)
|
||||
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) {
|
||||
ret= libdax_msgs_lock(m,0);
|
||||
if(ret<=0)
|
||||
|
@ -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 msg_text Printable and human readable message text.
|
||||
@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
|
||||
*/
|
||||
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
|
||||
0x0002019f (FAILURE,HIGH) = CD-TEXT binary pack array faulty
|
||||
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:
|
||||
|
@ -328,3 +328,17 @@ char *burn_printify(char *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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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_printify(char *msg);
|
||||
|
||||
/* ts B30521 */
|
||||
void burn_int_to_lsb(int val, char *target);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user