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 "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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
|
@ -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:
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user