void main(int argc, char *argv[]) { double scale, rscale; /* page scale */ double waste, rwaste; /* amount wasted */ double vshift, hshift; /* page centring shifts */ int rotate; double inwidth = -1; double inheight = -1; Paper *paper; PageSpec *specs; #ifdef PAPER if ( (paper = findpaper(PAPER)) != (Paper *)0 ) { inwidth = width = (double)PaperWidth(paper); inheight = height = (double)PaperHeight(paper); } #endif vshift = hshift = 0; rotate = 0; infile = stdin; outfile = stdout; verbose = 1; for (program = *argv++; --argc; argv++) { if (argv[0][0] == '-') { switch (argv[0][1]) { case 'q': /* quiet */ verbose = 0; break; case 'w': /* page width */ width = singledimen(*argv+2, argerror, usage); break; case 'h': /* page height */ height = singledimen(*argv+2, argerror, usage); break; case 'p': /* paper type */ if ( (paper = findpaper(*argv+2)) != (Paper *)0 ) { width = (double)PaperWidth(paper); height = (double)PaperHeight(paper); } else message(FATAL, "paper size '%s' not recognised\n", *argv+2); break; case 'W': /* input page width */ inwidth = singledimen(*argv+2, argerror, usage); break; case 'H': /* input page height */ inheight = singledimen(*argv+2, argerror, usage); break; case 'P': /* input paper type */ if ( (paper = findpaper(*argv+2)) != (Paper *)0 ) { inwidth = (double)PaperWidth(paper); inheight = (double)PaperHeight(paper); } else message(FATAL, "paper size '%s' not recognised\n", *argv+2); break; case 'v': /* version */ default: usage(); } } else if (infile == stdin) { if ((infile = fopen(*argv, OPEN_READ)) == NULL) message(FATAL, "can't open input file %s\n", *argv); } else if (outfile == stdout) { if ((outfile = fopen(*argv, OPEN_WRITE)) == NULL) message(FATAL, "can't open output file %s\n", *argv); } else usage(); } #if defined(MSDOS) || defined(WINNT) || defined(WIN32) if ( infile == stdin ) { int fd = fileno(stdin) ; if ( setmode(fd, O_BINARY) < 0 ) message(FATAL, "can't open input file %s\n", argv[4]); } if ( outfile == stdout ) { int fd = fileno(stdout) ; if ( setmode(fd, O_BINARY) < 0 ) message(FATAL, "can't reset stdout to binary mode\n"); } #endif if ((infile=seekable(infile))==NULL) message(FATAL, "can't seek input\n"); if (width <= 0 || height <= 0) message(FATAL, "output page width and height must be set\n"); if (inwidth <= 0 || inheight <= 0) message(FATAL, "input page width and height must be set\n"); /* try normal orientation first */ scale = MIN(width/inwidth, height/inheight); waste = (width-scale*inwidth)*(width-scale*inwidth) + (height-scale*inheight)*(height-scale*inheight); hshift = (width - inwidth*scale)/2; vshift = (height - inheight*scale)/2; /* try rotated orientation */ rscale = MIN(height/inwidth, width/inheight); rwaste = (height-scale*inwidth)*(height-scale*inwidth) + (width-scale*inheight)*(width-scale*inheight); if (rwaste < waste) { double tmp = width; scale = rscale; hshift = (width + inheight*scale)/2; vshift = (height - inwidth*scale)/2; rotate = 1; width = height; height = tmp; } width /= scale; height /= scale; /* now construct specification list and run page rearrangement procedure */ specs = newspec(); if (rotate) { specs->rotate = 90; specs->flags |= ROTATE; } specs->pageno = 0; specs->scale = scale; specs->flags |= SCALE; specs->xoff = hshift; specs->yoff = vshift; specs->flags |= OFFSET; pstops(1, 1, 0, specs, 0.0); /* do page rearrangement */ exit(0); }
void main(int argc, char *argv[]) { int horiz, vert, rotate, column, flip, leftright, topbottom; int nup = 1; double draw = 0; /* draw page borders */ double scale; /* page scale */ double uscale = 0; /* user supplied scale */ double ppwid, pphgt; /* paper dimensions */ double margin, border; /* paper & page margins */ double vshift, hshift; /* page centring shifts */ double iwidth, iheight ; /* input paper size */ double tolerance = 100000; /* layout tolerance */ Paper *paper; #ifdef PAPER if ( (paper = findpaper(PAPER)) != (Paper *)0 ) { width = (double)PaperWidth(paper); height = (double)PaperHeight(paper); } #endif margin = border = vshift = hshift = column = flip = 0; leftright = topbottom = 1; iwidth = iheight = -1 ; infile = stdin; outfile = stdout; verbose = 1; for (program = *argv++; --argc; argv++) { if (argv[0][0] == '-') { switch (argv[0][1]) { case 'q': /* quiet */ verbose = 0; break; case 'd': /* draw borders */ if (argv[0][2]) draw = singledimen(*argv+2, argerror, usage); else draw = 1; break; case 'l': /* landscape (rotated left) */ column = !column; topbottom = !topbottom; break; case 'r': /* seascape (rotated right) */ column = !column; leftright = !leftright; break; case 'f': /* flipped */ flip = 1; break; case 'c': /* column major layout */ column = !column; break; case 'w': /* page width */ width = singledimen(*argv+2, argerror, usage); break; case 'W': /* input page width */ iwidth = singledimen(*argv+2, argerror, usage); break; case 'h': /* page height */ height = singledimen(*argv+2, argerror, usage); break; case 'H': /* input page height */ iheight = singledimen(*argv+2, argerror, usage); break; case 'm': /* margins around whole page */ margin = singledimen(*argv+2, argerror, usage); break; case 'b': /* border around individual pages */ border = singledimen(*argv+2, argerror, usage); break; case 't': /* layout tolerance */ tolerance = atof(*argv+2); break; case 's': /* override scale */ uscale = atof(*argv+2); break; case 'p': /* output (and by default input) paper type */ if ( (paper = findpaper(*argv+2)) != (Paper *)0 ) { width = (double)PaperWidth(paper); height = (double)PaperHeight(paper); } else message(FATAL, "paper size '%s' not recognised\n", *argv+2); break; case 'P': /* paper type */ if ( (paper = findpaper(*argv+2)) != (Paper *)0 ) { iwidth = (double)PaperWidth(paper); iheight = (double)PaperHeight(paper); } else message(FATAL, "paper size '%s' not recognised\n", *argv+2); break; case 'n': /* n-up, for compatibility with other psnups */ if (argc >= 2) { argv++; argc--; if ((nup = atoi(*argv)) < 1) message(FATAL, "-n %d too small\n", nup); } else message(FATAL, "argument expected for -n\n"); break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': nup = atoi(*argv+1); break; case 'v': /* version */ default: usage(); } } else if (infile == stdin) { if ((infile = fopen(*argv, OPEN_READ)) == NULL) message(FATAL, "can't open input file %s\n", *argv); } else if (outfile == stdout) { if ((outfile = fopen(*argv, OPEN_WRITE)) == NULL) message(FATAL, "can't open output file %s\n", *argv); } else usage(); } #if defined(MSDOS) || defined(WINNT) if ( infile == stdin ) { int fd = fileno(stdin) ; if ( setmode(fd, O_BINARY) < 0 ) message(FATAL, "can't open input file %s\n", argv[4]); } if ( outfile == stdout ) { int fd = fileno(stdout) ; if ( setmode(fd, O_BINARY) < 0 ) message(FATAL, "can't reset stdout to binary mode\n"); } #endif if ((infile=seekable(infile))==NULL) message(FATAL, "can't seek input\n"); if (width <= 0 || height <= 0) message(FATAL, "page width and height must be set\n"); /* subtract paper margins from height & width */ ppwid = width - margin*2; pphgt = height - margin*2; if (ppwid <= 0 || pphgt <= 0) message(FATAL, "paper margins are too large\n"); /* set default values of input height & width */ if ( iwidth > 0 ) width = iwidth ; if ( iheight > 0 ) height = iheight ; /* Finding the best layout is an optimisation problem. We try all of the * combinations of width*height in both normal and rotated form, and * minimise the wasted space. */ { double best = tolerance; int hor; for (hor = 1; hor; hor = nextdiv(hor, nup)) { int ver = nup/hor; /* try normal orientation first */ double scl = MIN(pphgt/(height*ver), ppwid/(width*hor)); double optim = (ppwid-scl*width*hor)*(ppwid-scl*width*hor) + (pphgt-scl*height*ver)*(pphgt-scl*height*ver); if (optim < best) { best = optim; /* recalculate scale to allow for internal borders */ scale = MIN((pphgt-2*border*ver)/(height*ver), (ppwid-2*border*hor)/(width*hor)); hshift = (ppwid/hor - width*scale)/2; vshift = (pphgt/ver - height*scale)/2; horiz = hor; vert = ver; rotate = flip; } /* try rotated orientation */ scl = MIN(pphgt/(width*hor), ppwid/(height*ver)); optim = (pphgt-scl*width*hor)*(pphgt-scl*width*hor) + (ppwid-scl*height*ver)*(ppwid-scl*height*ver); if (optim < best) { best = optim; /* recalculate scale to allow for internal borders */ scale = MIN((pphgt-2*border*hor)/(width*hor), (ppwid-2*border*ver)/(height*ver)); hshift = (ppwid/ver - height*scale)/2; vshift = (pphgt/hor - width*scale)/2; horiz = ver; vert = hor; rotate = !flip; } } /* fail if nothing better than worst tolerance was found */ if (best == tolerance) message(FATAL, "can't find acceptable layout for %d-up\n", nup); } if (flip) { /* swap width & height for clipping */ double tmp = width; width = height; height = tmp; } if (rotate) { /* rotate leftright and topbottom orders */ int tmp = topbottom; topbottom = !leftright; leftright = tmp; column = !column; } /* now construct specification list and run page rearrangement procedure */ { int page = 0; PageSpec *specs, *tail; tail = specs = newspec(); while (page < nup) { int up, across; /* page index */ if (column) { if (leftright) /* left to right */ across = page/vert; else /* right to left */ across = horiz-1-page/vert; if (topbottom) /* top to bottom */ up = vert-1-page%vert; else /* bottom to top */ up = page%vert; } else { if (leftright) /* left to right */ across = page%horiz; else /* right to left */ across = horiz-1-page%horiz; if (topbottom) /* top to bottom */ up = vert-1-page/horiz; else /* bottom to top */ up = page/horiz; } if (rotate) { tail->xoff = margin + (across+1)*ppwid/horiz - hshift; tail->rotate = 90; tail->flags |= ROTATE; } else { tail->xoff = margin + across*ppwid/horiz + hshift; } tail->pageno = page; if (uscale > 0) tail->scale = uscale; else tail->scale = scale; tail->flags |= SCALE; tail->yoff = margin + up*pphgt/vert + vshift; tail->flags |= OFFSET; if (++page < nup) { tail->flags |= ADD_NEXT; tail->next = newspec(); tail = tail->next; } } pstops(nup, 1, 0, specs, draw); /* do page rearrangement */ } exit(0); }
void DownBeat::findDownBeats(const float *audio, size_t audioLength, const d_vec_t &beats, i_vec_t &downbeats) { // FIND DOWNBEATS BY PARTITIONING THE INPUT AUDIO FILE INTO BEAT SEGMENTS // WHERE THE AUDIO FRAMES ARE DOWNSAMPLED BY A FACTOR OF 16 (fs ~= 2700Hz) // THEN TAKING THE JENSEN-SHANNON DIVERGENCE BETWEEN BEAT SYNCHRONOUS SPECTRAL FRAMES // IMPLEMENTATION (MOSTLY) FOLLOWS: // DAVIES AND PLUMBLEY "A SPECTRAL DIFFERENCE APPROACH TO EXTRACTING DOWNBEATS IN MUSICAL AUDIO" // EUSIPCO 2006, FLORENCE, ITALY d_vec_t newspec(m_beatframesize / 2); // magnitude spectrum of current beat d_vec_t oldspec(m_beatframesize / 2); // magnitude spectrum of previous beat m_beatsd.clear(); if (audioLength == 0) return; for (size_t i = 0; i + 1 < beats.size(); ++i) { // Copy the extents of the current beat from downsampled array // into beat frame buffer size_t beatstart = (beats[i] * m_increment) / m_factor; size_t beatend = (beats[i+1] * m_increment) / m_factor; if (beatend >= audioLength) beatend = audioLength - 1; if (beatend < beatstart) beatend = beatstart; size_t beatlen = beatend - beatstart; // Also apply a Hanning window to the beat frame buffer, sized // to the beat extents rather than the frame size. (Because // the size varies, it's easier to do this by hand than use // our Window abstraction.) // std::cerr << "beatlen = " << beatlen << std::endl; // float rms = 0; for (size_t j = 0; j < beatlen && j < m_beatframesize; ++j) { double mul = 0.5 * (1.0 - cos(TWO_PI * (double(j) / double(beatlen)))); m_beatframe[j] = audio[beatstart + j] * mul; // rms += m_beatframe[j] * m_beatframe[j]; } // rms = sqrt(rms); // std::cerr << "beat " << i << ": audio rms " << rms << std::endl; for (size_t j = beatlen; j < m_beatframesize; ++j) { m_beatframe[j] = 0.0; } // Now FFT beat frame m_fft->process(false, m_beatframe, m_fftRealOut, m_fftImagOut); // Calculate magnitudes for (size_t j = 0; j < m_beatframesize/2; ++j) { newspec[j] = sqrt(m_fftRealOut[j] * m_fftRealOut[j] + m_fftImagOut[j] * m_fftImagOut[j]); } // Preserve peaks by applying adaptive threshold MathUtilities::adaptiveThreshold(newspec); // Calculate JS divergence between new and old spectral frames if (i > 0) { // otherwise we have no previous frame m_beatsd.push_back(measureSpecDiff(oldspec, newspec)); // std::cerr << "specdiff: " << m_beatsd[m_beatsd.size()-1] << std::endl; } // Copy newspec across to old for (size_t j = 0; j < m_beatframesize/2; ++j) { oldspec[j] = newspec[j]; } } // We now have all spectral difference measures in specdiff int timesig = m_bpb; if (timesig == 0) timesig = 4; d_vec_t dbcand(timesig); // downbeat candidates for (int beat = 0; beat < timesig; ++beat) { dbcand[beat] = 0; } // look for beat transition which leads to greatest spectral change for (int beat = 0; beat < timesig; ++beat) { int count = 0; for (int example = beat-1; example < (int)m_beatsd.size(); example += timesig) { if (example < 0) continue; dbcand[beat] += (m_beatsd[example]) / timesig; ++count; } if (count > 0) dbcand[beat] /= count; // std::cerr << "dbcand[" << beat << "] = " << dbcand[beat] << std::endl; } // first downbeat is beat at index of maximum value of dbcand int dbind = MathUtilities::getMax(dbcand); // remaining downbeats are at timesig intervals from the first for (int i = dbind; i < (int)beats.size(); i += timesig) { downbeats.push_back(i); } }
int main(int argc, char *argv[]) { double scale, rscale; /* page scale */ double waste, rwaste; /* amount wasted */ double vshift, hshift; /* page centring shifts */ int rotate; double inwidth = -1; double inheight = -1; off_t sizeheaders[20]; /* headers to remove */ PageSpec *specs; int opt; const struct paper *paper = NULL; set_paper_size(NULL); vshift = hshift = 0; rotate = 0; verbose = 1; program = *argv; while((opt = getopt(argc, argv, "qw:h:p:W:H:P:")) != EOF) { switch(opt) { case 'q': /* quiet */ verbose = 0; break; case 'w': /* page width */ width = singledimen(optarg); break; case 'h': /* page height */ height = singledimen(optarg); break; case 'p': /* paper type */ if ( (paper = paperinfo(optarg)) != NULL ) { width = paperpswidth(paper); height = paperpsheight(paper); } else message(FATAL, "paper size '%s' not recognised\n", optarg); break; case 'W': /* input page width */ inwidth = singledimen(optarg); break; case 'H': /* input page height */ inheight = singledimen(optarg); break; case 'P': /* input paper type */ if ( (paper = paperinfo(optarg)) != NULL ) { inwidth = paperpswidth(paper); inheight = paperpsheight(paper); } else message(FATAL, "paper size '%s' not recognised\n", optarg); break; case 'v': /* version */ default: usage(); } } infile = stdin; outfile = stdout; /* Be defensive */ if((argc - optind) < 0 || (argc - optind) > 2) usage(); if (optind != argc) { /* User specified an input file */ if ((infile = fopen(argv[optind], "rb")) == NULL) message(FATAL, "can't open input file %s\n", argv[optind]); optind++; } if (optind != argc) { /* User specified an output file */ if ((outfile = fopen(argv[optind], "wb")) == NULL) message(FATAL, "can't open output file %s\n", argv[optind]); optind++; } if (optind != argc) usage(); if ((infile=seekable(infile))==NULL) message(FATAL, "can't seek input\n"); if (width <= 0 || height <= 0) message(FATAL, "output page width and height must be set\n"); scanpages(sizeheaders); if (inwidth <= 0 || inheight <= 0) message(FATAL, "input page width and height must be set\n"); /* try normal orientation first */ scale = MIN(width/inwidth, height/inheight); waste = (width-scale*inwidth)*(width-scale*inwidth) + (height-scale*inheight)*(height-scale*inheight); hshift = (width - inwidth*scale)/2; vshift = (height - inheight*scale)/2; /* try rotated orientation */ rscale = MIN(height/inwidth, width/inheight); rwaste = (height-scale*inwidth)*(height-scale*inwidth) + (width-scale*inheight)*(width-scale*inheight); if (rwaste < waste) { double tmp = width; scale = rscale; hshift = (width + inheight*scale)/2; vshift = (height - inwidth*scale)/2; rotate = 1; width = height; height = tmp; } width /= scale; height /= scale; /* now construct specification list and run page rearrangement procedure */ specs = newspec(); if (rotate) { specs->rotate = 90; specs->flags |= ROTATE; } specs->pageno = 0; specs->scale = scale; specs->flags |= SCALE; specs->xoff = hshift; specs->yoff = vshift; specs->flags |= OFFSET; pstops_write(1, 1, 0, specs, 0.0, sizeheaders); /* do page rearrangement */ return 0; }