📄 cdda2wav.c
字号:
} if (*s1 == '\0' && *s2 == '\0') return 0; if (*s1 == '\0') return -1; if (*s2 == '\0') return +1; return tolower(*s1) - tolower(*s2); } return -1;}#endif#if !defined (HAVE_STRTOUL) || (HAVE_STRTOUL != 1)static unsigned int strtoul __PR(( const char *s1, char **s2, int base ));static unsigned int strtoul(s1, s2, base) const char *s1; char **s2; int base;{ long retval; if (base == 10) { /* strip zeros in front */ while (*s1 == '0') s1++; } if (s2 != NULL) { *s2 = astol(s1, &retval); } else { (void) astol(s1, &retval); } return (unsigned long) retval; }#endifstatic unsigned long SectorBurst;#if (SENTINEL > CD_FRAMESIZE_RAW)error block size for overlap check has to be < sector size#endifstatic voidswitch_to_realtime_priority __PR((void));#ifdef HAVE_SYS_PRIOCNTL_H#include <sys/priocntl.h>#include <sys/rtpriocntl.h>static voidswitch_to_realtime_priority(){ pcinfo_t info; pcparms_t param; rtinfo_t rtinfo; rtparms_t rtparam; int pid; pid = getpid(); /* get info */ strcpy(info.pc_clname, "RT"); if (-1 == priocntl(P_PID, pid, PC_GETCID, (void *)&info)) comerr("Cannot get priority class id priocntl(PC_GETCID)\n"); movebytes(info.pc_clinfo, &rtinfo, sizeof(rtinfo_t)); /* set priority not to the max */ rtparam.rt_pri = rtinfo.rt_maxpri - 2; rtparam.rt_tqsecs = 0; rtparam.rt_tqnsecs = RT_TQDEF; param.pc_cid = info.pc_cid; movebytes(&rtparam, param.pc_clparms, sizeof(rtparms_t)); needroot(0); if (-1 == priocntl(P_PID, pid, PC_SETPARMS, (void *)¶m)) comerr("Cannot set priority class parameters priocntl(PC_SETPARMS)\n"); dontneedroot();}#else#if defined _POSIX_PRIORITY_SCHEDULING#include <sched.h>static voidswitch_to_realtime_priority(){#ifdef _SC_PRIORITY_SCHEDULING if (sysconf(_SC_PRIORITY_SCHEDULING) == -1) { errmsg("WARNING: RR-scheduler not available, disabling.\n"); } else#endif { int sched_fifo_min, sched_fifo_max; struct sched_param sched_parms; sched_fifo_min = sched_get_priority_min(SCHED_FIFO); sched_fifo_max = sched_get_priority_max(SCHED_FIFO); sched_parms.sched_priority = sched_fifo_max - 1; needroot(0); if (-1 == sched_setscheduler(getpid(), SCHED_FIFO, &sched_parms) && global.quiet != 1) perror("cannot set posix realtime scheduling policy"); dontneedroot(); }}#else#if defined(__CYGWIN32__)/* * NOTE: Base.h has a second typedef for BOOL. * We define BOOL to make all local code use BOOL * from Windows.h and use the hidden __SBOOL for * our global interfaces. */#define BOOL WBOOL /* This is the Win BOOL */#define format __format#include <Windows32/Base.h>#include <Windows32/Defines.h>#include <Windows32/Structures.h>#include <Windows32/Functions.h>#undef formatstatic voidswitch_to_realtime_priority(){ /* set priority class */ if (FALSE == SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS)) { fprintf(stderr, "No realtime priority possible.\n"); return; } /* set thread priority */ if (FALSE == SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST)) { fprintf(stderr, "Could not set realtime priority.\n"); }}#elsestatic voidswitch_to_realtime_priority(){}#endif#endif#endif/* signal handler for process communication */static void set_nonforked __PR((int status));static void set_nonforked(status) int status;{ PRETEND_TO_USE(status); global.parent_died = 1;#if defined DEBUG_CLEANUPfprintf( stderr, "SIGPIPE received from %s\n.", child_pid == 0 ? "Child" : "Parent");#endif if (child_pid == 0) kill(getppid(), SIGINT); else kill(child_pid, SIGINT); exit(9);}static long lSector;static long lSector_p2;static double rate = 44100 / UNDERSAMPLING;static int bits = BITS_P_S;static char fname[200];static char audio_type[10];static long BeginAtSample;static unsigned long SamplesToWrite; static unsigned minover;static unsigned maxover;static unsigned long calc_SectorBurst __PR((void));static unsigned long calc_SectorBurst(){ unsigned long SectorBurstVal; SectorBurstVal = min(global.nsectors, (global.iloop + CD_FRAMESAMPLES-1) / CD_FRAMESAMPLES); if ( lSector+(int)SectorBurst-1 >= lSector_p2 ) SectorBurstVal = lSector_p2 - lSector; return SectorBurstVal;}/* if PERCENTAGE_PER_TRACK is defined, the percentage message will reach * 100% every time a track end is reached or the time limit is reached. * * Otherwise if PERCENTAGE_PER_TRACK is not defined, the percentage message * will reach 100% once at the very end of the last track. */#define PERCENTAGE_PER_TRACKstatic int do_read __PR((myringbuff *p, unsigned *total_unsuccessful_retries));static int do_read (p, total_unsuccessful_retries) myringbuff *p; unsigned *total_unsuccessful_retries;{ unsigned char *newbuf; int offset; unsigned int retry_count; unsigned int added_size; static unsigned oper = 200; /* how many sectors should be read */ SectorBurst = calc_SectorBurst();#define MAX_READRETRY 12 retry_count = 0; do {#ifdef DEBUG_READS fprintf(stderr, "reading from %lu to %lu, overlap %u\n", lSector, lSector + SectorBurst -1, global.overlap);#endif#ifdef DEBUG_BUFFER_ADDRESSES fprintf(stderr, "%p %l\n", p->data, global.pagesize); if (((unsigned)p->data) & (global.pagesize -1) != 0) { fprintf(stderr, "Address %p is NOT page aligned!!\n", p->data); }#endif ReadCdRom( get_scsi_p(), p->data, lSector, SectorBurst ); if (NULL == (newbuf = synchronize( p->data, SectorBurst*CD_FRAMESAMPLES, nSamplesToDo-global.iloop ))) { /* could not synchronize! * Try to invalidate the cdrom cache. * Increase overlap setting, if possible. */ /*trash_cache(p->data, lSector, SectorBurst);*/ if (global.overlap < global.nsectors - 1) { global.overlap++; lSector--; SectorBurst = calc_SectorBurst();#ifdef DEBUG_DYN_OVERLAP fprintf(stderr, "using increased overlap of %u\n", global.overlap);#endif } else { lSector += global.overlap - 1; global.overlap = 1; SectorBurst = calc_SectorBurst(); } } else break; } while (++retry_count < MAX_READRETRY); if (retry_count == MAX_READRETRY && newbuf == NULL && global.verbose != 0) { (*total_unsuccessful_retries)++; } if (newbuf) { offset = newbuf - ((unsigned char *)p->data); } else { offset = global.overlap * CD_FRAMESIZE_RAW; } set_offset(p,offset); /* how much has been added? */ added_size = SectorBurst * CD_FRAMESAMPLES - offset/4; if (newbuf && nSamplesToDo != global.iloop) { minover = min(global.overlap, minover); maxover = max(global.overlap, maxover); /* should we reduce the overlap setting ? */ if (offset > CD_FRAMESIZE_RAW && global.overlap > 1) {#ifdef DEBUG_DYN_OVERLAP fprintf(stderr, "decreasing overlap from %u to %u (jitter %d)\n", global.overlap, global.overlap-1, offset - (global.overlap)*CD_FRAMESIZE_RAW);#endif global.overlap--; SectorBurst = calc_SectorBurst(); } } if (global.iloop >= added_size) global.iloop -= added_size; else global.iloop = 0; if (global.verbose) { unsigned per;#ifdef PERCENTAGE_PER_TRACK /* Thomas Niederreiter wants percentage per track */ unsigned start_in_track = max(BeginAtSample, g_toc[current_track-1].dwStartSector*CD_FRAMESAMPLES); per = min(BeginAtSample+nSamplesToDo, g_toc[current_track].dwStartSector*CD_FRAMESAMPLES) - start_in_track; per = (BeginAtSample+nSamplesToDo-global.iloop - start_in_track )/(per/100);#else per = global.iloop ? (nSamplesToDo-global.iloop)/(nSamplesToDo/100) : 100;#endif if (global.overlap > 0) { fprintf(stderr, "\r%2d/%2d/%2d/%7d %3d%%", minover, maxover, global.overlap, newbuf ? offset - global.overlap*CD_FRAMESIZE_RAW : 9999999, per); fflush(stderr); } else if (oper != per) { fprintf(stderr, "\r%3d%%", per); fflush(stderr); oper = per; } } lSector += SectorBurst - global.overlap;#if defined PERCENTAGE_PER_TRACK && defined HAVE_FORK_AND_SHAREDMEM while (lSector >= (int)g_toc[current_track].dwStartSector) { current_track++; }#endif return offset;}static unsigned long do_write __PR((myringbuff *p));static unsigned long do_write (p) myringbuff *p;{ int current_offset; unsigned int InSamples; current_offset = get_offset(p); /* how many bytes are available? */ InSamples = global.nsectors*CD_FRAMESAMPLES - current_offset/4; /* how many samples are wanted? */ InSamples = min((nSamplesToDo-nSamplesDone),InSamples); /* when track end is reached, close current file and start a new one */ while ((nSamplesDone < nSamplesToDo) && (InSamples != 0)) { long unsigned int how_much = InSamples; long int left_in_track; left_in_track = (int)g_toc[current_track].dwStartSector*CD_FRAMESAMPLES - (int)(BeginAtSample+nSamplesDone);if (left_in_track < 0) { fprintf(stderr, "internal error: negative left_in_track:%ld\n",left_in_track);} if (bulk) how_much = min(how_much, (unsigned long) left_in_track);#ifdef MD5_SIGNATURES if (global.md5count) { MD5Update (&global.context, ((unsigned char *)p->data) +current_offset, min(global.md5count,how_much)); global.md5count -= min(global.md5count,how_much); }#endif if ( SaveBuffer ( p->data + current_offset/4, how_much, &nSamplesDone) ) { if (global.have_forked == 1) { /* kill parent */ kill(getppid(), SIGINT); } exit(20); } global.nSamplesDoneInTrack += how_much; SamplesToWrite -= how_much; /* move residual samples upto buffer start */ if (how_much < InSamples) movebytes( (char *)(p->data) + current_offset + how_much*4, (char *)(p->data) + current_offset, (InSamples - how_much) * 4); if ((unsigned long) left_in_track < InSamples) { if (bulk) { /* finish sample file for this track */ CloseAudio(global.fname_base, current_track, bulk, global.channels, global.nSamplesDoneInTrack, global.audio_out); any_signal = 0; } else if (SamplesToWrite == 0) { /* finish sample file for this track */ CloseAudio(global.fname_base, track, bulk, global.channels, (unsigned int) nSamplesToDo, global.audio_out); } if (global.verbose) { if (global.tracktitle[current_track -1] != NULL) { fprintf( stderr, " track %2u '%s' successfully recorded\n", current_track, global.tracktitle[current_track-1]); } else { fprintf( stderr, " track %2u successfully recorded\n", current_track); } } global.nSamplesDoneInTrack = 0; if ( bulk && SamplesToWrite > 0 ) { if ( !global.no_file ) { char *tmp_fname; /* build next filename */ tmp_fname = get_next_name(); if (tmp_fname != NULL) { strncpy(global.fname_base , tmp_fname, sizeof global.fname_base); global.fname_base[sizeof(global.fname_base)-1]=0; } tmp_fname = cut_extension(global.fname_base); tmp_fname[0] = '\0'; if (global.multiname == 0) { sprintf(fname, "%s_%02u.%s",global.fname_base,current_track+1, audio_type); } else { sprintf(fname, "%s.%s",global.fname_base, audio_type); } OpenAudio( fname, rate, bits, global.channels, (g_toc[current_track].dwStartSector - g_toc[current_track-1].dwStartSector)*CD_FRAMESIZE_RAW, global.audio_out); } } current_track++; } InSamples -= how_much; } /* end while */ return nSamplesDone;}#define PRINT_OVERLAP_INIT \ if (global.verbose) { \ if (global.overlap > 0) \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -