Implemented a first attempt of a .wav decapitator (ticket 38)
This commit is contained in:
parent
3c6f6de961
commit
f08a680b5e
@ -29,6 +29,8 @@ libburn_libburn_la_SOURCES = \
|
||||
libburn/lec.c \
|
||||
libburn/lec.h \
|
||||
libburn/libburn.h \
|
||||
libburn/libdax_audioxtr.h \
|
||||
libburn/libdax_audioxtr.c \
|
||||
libburn/libdax_msgs.h \
|
||||
libburn/libdax_msgs.c \
|
||||
libburn/mmc.c \
|
||||
@ -95,6 +97,7 @@ libinclude_HEADERS = \
|
||||
## Build test applications
|
||||
noinst_PROGRAMS = \
|
||||
test/libburner \
|
||||
test/dewav \
|
||||
test/iso \
|
||||
test/poll \
|
||||
test/toc \
|
||||
@ -106,6 +109,9 @@ bin_PROGRAMS = \
|
||||
test_libburner_CPPFLAGS = -Ilibburn
|
||||
test_libburner_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
|
||||
test_libburner_SOURCES = test/libburner.c
|
||||
test_dewav_CPPFLAGS = -Ilibburn
|
||||
test_dewav_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
|
||||
test_dewav_SOURCES = test/dewav.c
|
||||
test_poll_CPPFLAGS = -Ilibburn
|
||||
test_poll_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
|
||||
test_poll_SOURCES = test/poll.c
|
||||
|
196
trunk/libburn/libdax_audioxtr.c
Normal file
196
trunk/libburn/libdax_audioxtr.c
Normal file
@ -0,0 +1,196 @@
|
||||
|
||||
/* libdax_audioxtr
|
||||
Audio track data extraction facility of libdax and libburn.
|
||||
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
#include "libdax_msgs.h"
|
||||
extern struct libdax_msgs *libdax_messenger;
|
||||
|
||||
|
||||
/* Only this single source module is entitled to do this */
|
||||
#define LIBDAX_AUDIOXTR_H_INTERNAL 1
|
||||
|
||||
/* All clients of the extraction facility must do this */
|
||||
#include "libdax_audioxtr.h"
|
||||
|
||||
|
||||
int libdax_audioxtr_new(struct libdax_audioxtr **xtr, char *path, int flag)
|
||||
{
|
||||
int ret;
|
||||
struct libdax_audioxtr *o;
|
||||
|
||||
o= *xtr= (struct libdax_audioxtr *)malloc(sizeof(struct libdax_audioxtr *));
|
||||
if(o==NULL)
|
||||
return(-1);
|
||||
strncpy(o->path,path,LIBDAX_AUDIOXTR_STRLEN-1);
|
||||
o->path[LIBDAX_AUDIOXTR_STRLEN]= 0;
|
||||
o->fd= -1;
|
||||
strcpy(o->fmt,"unidentified");
|
||||
o->fmt_info[0]= 0;
|
||||
|
||||
o->wav_num_channels= 0;
|
||||
o->wav_sample_rate= 0;
|
||||
o->wav_bits_per_sample= 0;
|
||||
|
||||
ret= libdax_audioxtr_open(o,0);
|
||||
if(ret<=0)
|
||||
goto failure;
|
||||
|
||||
return(1);
|
||||
failure:
|
||||
libdax_audioxtr_destroy(xtr,0);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
||||
int libdax_audioxtr_destroy(struct libdax_audioxtr **xtr, int flag)
|
||||
{
|
||||
struct libdax_audioxtr *o;
|
||||
|
||||
o= *xtr;
|
||||
if(o==NULL)
|
||||
return(0);
|
||||
if(o->fd>=0 && strcmp(o->path,"-")!=0)
|
||||
close(o->fd);
|
||||
free((char *) o);
|
||||
*xtr= NULL;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static int libdax_audioxtr_open(struct libdax_audioxtr *o, int flag)
|
||||
{
|
||||
int ret;
|
||||
char msg[LIBDAX_AUDIOXTR_STRLEN+80];
|
||||
|
||||
if(strcmp(o->path,"-")==0)
|
||||
o->fd= 0;
|
||||
else
|
||||
o->fd= open(o->path, O_RDONLY);
|
||||
if(o->fd<0) {
|
||||
sprintf(msg,"Cannot open audio source file : %s",o->path);
|
||||
libdax_msgs_submit(libdax_messenger,-1,0x00020200,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
msg, errno, 0);
|
||||
return(-1);
|
||||
}
|
||||
ret= libdax_audioxtr_identify(o,0);
|
||||
if(ret<=0) {
|
||||
sprintf(msg,"Audio source file has unsuitable format : %s",o->path);
|
||||
libdax_msgs_submit(libdax_messenger,-1,0x00020201,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
msg, 0, 0);
|
||||
return(0);
|
||||
}
|
||||
ret= libdax_audioxtr_init_reading(o,0);
|
||||
if(ret<=0) {
|
||||
sprintf(msg,"Failed to prepare reading of audio data : %s",o->path);
|
||||
libdax_msgs_submit(libdax_messenger,-1,0x00020202,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
msg, 0, 0);
|
||||
return(0);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static int libdax_audioxtr_identify(struct libdax_audioxtr *o, int flag)
|
||||
{
|
||||
int ret;
|
||||
char buf[45];
|
||||
|
||||
/* currently this only works for MS WAVE files .wav */
|
||||
/* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */
|
||||
|
||||
ret= read(o->fd, buf, 44);
|
||||
if(ret<44)
|
||||
return(0);
|
||||
buf[44]= 0; /* as stopper for any string operations */
|
||||
|
||||
if(strncmp(buf,"RIFF",4)!=0) /* ChunkID */
|
||||
return(0);
|
||||
if(strncmp(buf+8,"WAVE",4)!=0) /* Format */
|
||||
return(0);
|
||||
if(strncmp(buf+12,"fmt ",4)!=0) /* Subchunk1ID */
|
||||
return(0);
|
||||
if(buf[16]!=16 || buf[17]!=0 || buf[18]!=0 || buf[19]!=0) /* Subchunk1Size */
|
||||
return(0);
|
||||
if(buf[20]!=1 || buf[21]!=0) /* AudioFormat must be 1 (Linear quantization) */
|
||||
return(0);
|
||||
|
||||
strcpy(o->fmt,".wav");
|
||||
o->wav_num_channels= libdax_audioxtr_to_int(o,(unsigned char *) buf+22,2,0);
|
||||
o->wav_sample_rate= libdax_audioxtr_to_int(o,(unsigned char *) buf+24,4,0);
|
||||
o->wav_bits_per_sample= libdax_audioxtr_to_int(o,(unsigned char *)buf+34,2,0);
|
||||
sprintf(o->fmt_info,
|
||||
".wav , num_channels=%d , sample_rate=%d , bits_per_sample=%d",
|
||||
o->wav_num_channels,o->wav_sample_rate,o->wav_bits_per_sample);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static unsigned libdax_audioxtr_to_int(struct libdax_audioxtr *o,
|
||||
unsigned char *bytes, int len, int flag)
|
||||
{
|
||||
unsigned int ret= 0;
|
||||
int i;
|
||||
|
||||
for(i= len-1; i>=0; i--)
|
||||
ret= ret*256+bytes[i];
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
static int libdax_audioxtr_init_reading(struct libdax_audioxtr *o, int flag)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* currently this only works for MS WAVE files .wav */;
|
||||
ret= lseek(o->fd,44,SEEK_SET);
|
||||
if(ret==-1)
|
||||
return(0);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int libdax_audioxtr_get_id(struct libdax_audioxtr *o,
|
||||
char **fmt, char **fmt_info,
|
||||
int *num_channels, int *sample_rate, int *bits_per_sample,
|
||||
int flag)
|
||||
{
|
||||
*fmt= o->fmt;
|
||||
*fmt_info= o->fmt_info;
|
||||
if(strcmp(o->fmt,".wav")==0) {
|
||||
*num_channels= o->wav_num_channels;
|
||||
*sample_rate= o->wav_sample_rate;
|
||||
*bits_per_sample= o->wav_bits_per_sample;
|
||||
} else
|
||||
*num_channels= *sample_rate= *bits_per_sample= 0;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int libdax_audioxtr_read(struct libdax_audioxtr *o,
|
||||
char buffer[], int buffer_size, int flag)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if(buffer_size<=0 || o->fd<0)
|
||||
return(-2);
|
||||
ret= read(o->fd,buffer,buffer_size);
|
||||
return(ret);
|
||||
}
|
||||
|
168
trunk/libburn/libdax_audioxtr.h
Normal file
168
trunk/libburn/libdax_audioxtr.h
Normal file
@ -0,0 +1,168 @@
|
||||
|
||||
/* libdax_audioxtr
|
||||
Audio track data extraction facility of libdax and libburn.
|
||||
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||
*/
|
||||
|
||||
#ifndef LIBDAX_AUDIOXTR_H_INCLUDED
|
||||
#define LIBDAX_AUDIOXTR_H_INCLUDED 1
|
||||
|
||||
/* Public Macros */
|
||||
|
||||
#define LIBDAX_AUDIOXTR_STRLEN 4096
|
||||
|
||||
|
||||
/* Public Opaque Handles */
|
||||
|
||||
/** Extractor object encapsulating intermediate states of extraction.
|
||||
The clients of libdax_audioxtr shall only allocate pointers to this
|
||||
struct and get a storage object via libdax_audioxtr_new().
|
||||
Appropriate initial value for the pointer is NULL.
|
||||
*/
|
||||
struct libdax_audioxtr;
|
||||
|
||||
|
||||
/* Public Functions */
|
||||
|
||||
/* Calls initiated from inside libdax/libburn */
|
||||
|
||||
|
||||
/* Calls from applications (to be forwarded by libdax/libburn) */
|
||||
|
||||
|
||||
/** Open an audio file, check wether suitable, create extractor object.
|
||||
@param xtr Opaque handle to extractor. Gets attached extractor object.
|
||||
@param path Address of the audio file to extract. "-" is stdin (but might
|
||||
be not suitable for all futurely supported formats).
|
||||
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||
@return >0 success, <=0 failure
|
||||
*/
|
||||
int libdax_audioxtr_new(struct libdax_audioxtr **xtr, char *path, int flag);
|
||||
|
||||
|
||||
/** Obtain identification parameters of opened audio source.
|
||||
@param xtr Opaque handle to extractor
|
||||
@param fmt Gets pointed to the audio file format id text: ".wav"
|
||||
@param fmt_info Gets pointed to a format info text telling parameters
|
||||
@param num_channels e.g. 1=mono, 2=stereo, etc
|
||||
@param sample_rate e.g. 11025, 44100
|
||||
@param bits_per_sample e.g. 8= 8 bits per sample, 16= 16 bits ...
|
||||
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||
@return >0 success, <=0 failure
|
||||
*/
|
||||
int libdax_audioxtr_get_id(struct libdax_audioxtr *xtr,
|
||||
char **fmt, char **fmt_info,
|
||||
int *num_channels, int *sample_rate,
|
||||
int *bits_per_sample, int flag);
|
||||
|
||||
|
||||
/** Obtain next buffer full of extracted data in desired format (only raw audio
|
||||
for now).
|
||||
@param xtr Opaque handle to extractor
|
||||
@param buffer Gets filled with extracted data
|
||||
@param buffer_size Maximum number of bytes to be filled into buffer
|
||||
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||
@return >0 number of valid buffer bytes,
|
||||
0 End of file
|
||||
-1 operating system reports error
|
||||
-2 usage error by application
|
||||
*/
|
||||
int libdax_audioxtr_read(struct libdax_audioxtr *xtr,
|
||||
char buffer[], int buffer_size, int flag);
|
||||
|
||||
|
||||
/** Clean up after extraction and destroy extractor object.
|
||||
@param xtr Opaque handle to extractor, *xtr is allowed to be NULL,
|
||||
*xtr is set to NULL by this function
|
||||
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||
@return 1 = destroyed object, 0 = was already destroyed
|
||||
*/
|
||||
int libdax_audioxtr_destroy(struct libdax_audioxtr **xtr, int flag);
|
||||
|
||||
|
||||
|
||||
#ifdef LIDBAX_AUDIOXTR________________
|
||||
|
||||
|
||||
-- place documentation text here ---
|
||||
|
||||
|
||||
#endif /* LIDBAX_AUDIOXTR_________________ */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*Never* set this macro outside libdax_audioxtr.c !
|
||||
The entrails of this facility are not to be seen by
|
||||
the other library components or the applications.
|
||||
*/
|
||||
#ifdef LIBDAX_AUDIOXTR_H_INTERNAL
|
||||
|
||||
/* Internal Structures */
|
||||
|
||||
/** Extractor object encapsulating intermediate states of extraction */
|
||||
struct libdax_audioxtr {
|
||||
|
||||
/* Source of the encoded audio data */
|
||||
char path[LIBDAX_AUDIOXTR_STRLEN];
|
||||
|
||||
/* File descriptor to path */
|
||||
int fd;
|
||||
|
||||
/* Format identifier. E.g. ".wav" */
|
||||
char fmt[80];
|
||||
|
||||
/* Format parameter info text */
|
||||
char fmt_info[LIBDAX_AUDIOXTR_STRLEN];
|
||||
|
||||
|
||||
/* Format dependent parameters */
|
||||
|
||||
/* MS WAVE Format */
|
||||
/* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */
|
||||
|
||||
/* 1= mono, 2= stereo, etc. */
|
||||
int wav_num_channels;
|
||||
|
||||
/* 8000, 44100, etc. */
|
||||
int wav_sample_rate;
|
||||
|
||||
/* 8 bits = 8, 16 bits = 16, etc. */
|
||||
int wav_bits_per_sample;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* Internal Functions */
|
||||
|
||||
/** Open the audio source pointed to by .path and evaluate suitability.
|
||||
@return -1 failure to open, 0 unsuitable format, 1 success
|
||||
*/
|
||||
static int libdax_audioxtr_open(struct libdax_audioxtr *o, int flag);
|
||||
|
||||
|
||||
/** Identify format and evaluate suitability.
|
||||
@return 0 unsuitable format, 1 format is suitable
|
||||
*/
|
||||
static int libdax_audioxtr_identify(struct libdax_audioxtr *o, int flag);
|
||||
|
||||
|
||||
/** Convert a byte string into a number (currently only little endian)
|
||||
@return The resulting number
|
||||
*/
|
||||
static unsigned libdax_audioxtr_to_int(struct libdax_audioxtr *o,
|
||||
unsigned char *bytes, int len, int flag);
|
||||
|
||||
|
||||
/** Prepare for reading of first buffer.
|
||||
@return 0 error, 1 success
|
||||
*/
|
||||
static int libdax_audioxtr_init_reading(struct libdax_audioxtr *o, int flag);
|
||||
|
||||
|
||||
|
||||
#endif /* LIBDAX_AUDIOXTR_H_INTERNAL */
|
||||
|
||||
|
||||
#endif /* ! LIBDAX_AUDIOXTR_H_INCLUDED */
|
||||
|
@ -330,6 +330,11 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||
0x00020116 (FATAL,HIGH) = Track mode has unusable value
|
||||
0x00020117 (FATAL,HIGH) = toc_entry of drive is already in use
|
||||
|
||||
libdax_audioxtr:
|
||||
0x00020200 (SORRY,HIGH) = Cannot open audio source file
|
||||
0x00020201 (SORRY,HIGH) = Audio source file has unsuitable format
|
||||
0x00020202 (SORRY,HIGH) = Failed to prepare reading of audio data
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user