📄 util.cpp
字号:
/* util.cpp * * $Id: util.cpp,v 1.4 2002/03/16 19:53:19 kyllingstad Exp $ * * Apollo sound player: http://www.apolloplayer.org * Copyright(C) 2000-2002 Apollo Team. See CREDITS file. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * The GNU General Public License is also available online at: * * http://www.gnu.org/copyleft/gpl.html *//** * @file util.cpp * @brief some utility functions. Well. 1 utility function :-) */#include <qstring.h>#include "util.h"voidsecondsToTimeString(long seconds, QString &time) { int s = seconds % 60; seconds -= s; seconds /= 60; int m = seconds % 60; seconds -=m; seconds /= 60; int h = seconds % 24; seconds -= h; seconds /= 24; if (seconds == 1) time.sprintf("%ld day %d:%.2d:%.2d", seconds, h, m, s); else if (seconds > 0) time.sprintf("%ld days %d:%.2d:%.2d", seconds, h, m, s); else if (h > 0) time.sprintf("%d:%.2d:%.2d", h, m, s); else time.sprintf("%.2d:%.2d", m, s);}intgetMp3LengthInSeconds(const QString &path, bool fullScanVbr){ mp3info mp3; FILE *fp; if (!(fp = fopen(path.latin1(), "r"))) return -1; memset(&mp3, 0, sizeof(mp3info)); mp3.filename = const_cast<char *>(path.latin1()); mp3.file = fp; int error = get_mp3_info(&mp3, SCAN_QUICK, fullScanVbr?1:0); fclose(fp); return error ? -1 : mp3.seconds;}////////////////////////////////////////////////////////////////////////////// functions from mp3info - http://www.ibiblio.org/mp3info ///////////////////////////////////////////////////////////////////////////////////////////* Copyright (C) 2000-2001 Cedric Tefft <cedric@earthling.net> */int layer_tab[4]= {0, 3, 2, 1};int frequencies[3][4] = { {22050,24000,16000,50000}, /* MPEG 2.0 */ {44100,48000,32000,50000}, /* MPEG 1.0 */ {11025,12000,8000,50000} /* MPEG 2.5 */};int bitrate[2][3][14] = { { /* MPEG 2.0 */ {32,48,56,64,80,96,112,128,144,160,176,192,224,256}, /* layer 1 */ {8,16,24,32,40,48,56,64,80,96,112,128,144,160}, /* layer 2 */ {8,16,24,32,40,48,56,64,80,96,112,128,144,160} /* layer 3 */ }, { /* MPEG 1.0 */ {32,64,96,128,160,192,224,256,288,320,352,384,416,448}, /* layer 1 */ {32,48,56,64,80,96,112,128,160,192,224,256,320,384}, /* layer 2 */ {32,40,48,56,64,80,96,112,128,160,192,224,256,320} /* layer 3 */ }};int frame_size_index[] = {24000, 72000, 72000};char *mode_text[] = { "stereo", "joint stereo", "dual channel", "mono"};char *emphasis_text[] = { "none", "50/15 microsecs", "reserved", "CCITT J 17"};int get_mp3_info(mp3info *mp3,int scantype, int fullscan_vbr){ int had_error = 0; int frame_type[15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; float seconds=0,total_rate=0; int frames=0,frame_types=0,frames_so_far=0; int l,vbr_median=-1; int bitrate,lastrate; int counter=0; mp3header header; struct stat filestat; off_t sample_pos,data_start=0; stat(mp3->filename,&filestat); mp3->datasize=filestat.st_size; get_id3(mp3); if(scantype == SCAN_QUICK) { if(get_first_header(mp3,0L)) { data_start=ftell(mp3->file); lastrate=15-mp3->header.bitrate; while((counter < NUM_SAMPLES) && lastrate) { sample_pos=(counter*(mp3->datasize/NUM_SAMPLES+1))+data_start; if(get_first_header(mp3,sample_pos)) { bitrate=15-mp3->header.bitrate; } else { bitrate=-1; } if(bitrate != lastrate) { mp3->vbr=1; if(fullscan_vbr) { counter=NUM_SAMPLES; scantype=SCAN_FULL; } } lastrate=bitrate; counter++; } if(!(scantype == SCAN_FULL)) { mp3->frames=(mp3->datasize-data_start)/(l=frame_length(&mp3->header)); mp3->seconds = (int)((float)(frame_length(&mp3->header)*mp3->frames)/ (float)(header_bitrate(&mp3->header)*125)+0.5); mp3->vbr_average = (float)header_bitrate(&mp3->header); } } } if(scantype == SCAN_FULL) { if(get_first_header(mp3,0L)) { data_start=ftell(mp3->file); while((bitrate=get_next_header(mp3))) { frame_type[15-bitrate]++; frames++; } memcpy(&header,&(mp3->header),sizeof(mp3header)); for(counter=0;counter<15;counter++) { if(frame_type[counter]) { frame_types++; header.bitrate=counter; frames_so_far += frame_type[counter]; seconds += (float)(frame_length(&header)*frame_type[counter])/ (float)(header_bitrate(&header)*125); total_rate += (float)((header_bitrate(&header))*frame_type[counter]); if((vbr_median == -1) && (frames_so_far >= frames/2)) vbr_median=counter; } } mp3->seconds=(int)(seconds+0.5); mp3->header.bitrate=vbr_median; mp3->vbr_average=total_rate/(float)frames; mp3->frames=frames; if(frame_types > 1) { mp3->vbr=1; } } } return had_error;}int get_first_header(mp3info *mp3, long startpos) { int k, l=0,c; mp3header h, h2; long valid_start=0; fseek(mp3->file,startpos,SEEK_SET); while (1) { while((c=fgetc(mp3->file)) != 255 && (c != EOF)); if(c == 255) { ungetc(c,mp3->file); valid_start=ftell(mp3->file); if((l=get_header(mp3->file,&h))) { fseek(mp3->file,l-FRAME_HEADER_SIZE,SEEK_CUR); for(k=1; (k < MIN_CONSEC_GOOD_FRAMES) && (mp3->datasize-ftell(mp3->file) >= FRAME_HEADER_SIZE); k++) { if(!(l=get_header(mp3->file,&h2))) break; if(!sameConstant(&h,&h2)) break; fseek(mp3->file,l-FRAME_HEADER_SIZE,SEEK_CUR); } if(k == MIN_CONSEC_GOOD_FRAMES) { fseek(mp3->file,valid_start,SEEK_SET); memcpy(&(mp3->header),&h2,sizeof(mp3header)); mp3->header_isvalid=1; return 1; } } } else { return 0; } } return 0; }/* get_next_header() - read header at current position or look for the next valid header if there isn't one at the current position*/int get_next_header(mp3info *mp3) { int l=0,c,skip_bytes=0; mp3header h; while(1) { while((c=fgetc(mp3->file)) != 255 && (ftell(mp3->file) < mp3->datasize)) skip_bytes++; if(c == 255) { ungetc(c,mp3->file); if((l=get_header(mp3->file,&h))) { if(skip_bytes) mp3->badframes++; fseek(mp3->file,l-FRAME_HEADER_SIZE,SEEK_CUR); return 15-h.bitrate; } else { skip_bytes += FRAME_HEADER_SIZE; } } else { if(skip_bytes) mp3->badframes++; return 0; } }}/* Get next MP3 frame header. Return codes: positive value = Frame Length of this header 0 = No, we did not retrieve a valid frame header*/int get_header(FILE *file,mp3header *header){ unsigned char buffer[FRAME_HEADER_SIZE]; int fl; if(fread(&buffer,FRAME_HEADER_SIZE,1,file)<1) { header->sync=0; return 0; } header->sync=(((int)buffer[0]<<4) | ((int)(buffer[1]&0xE0)>>4)); if(buffer[1] & 0x10) header->version=(buffer[1] >> 3) & 1; else header->version=2; header->layer=(buffer[1] >> 1) & 3; if((header->sync != 0xFFE) || (header->layer != 1)) { header->sync=0; return 0; } header->crc=buffer[1] & 1; header->bitrate=(buffer[2] >> 4) & 0x0F; header->freq=(buffer[2] >> 2) & 0x3; header->padding=(buffer[2] >>1) & 0x1; header->extension=(buffer[2]) & 0x1; header->mode=(buffer[3] >> 6) & 0x3; header->mode_extension=(buffer[3] >> 4) & 0x3; header->copyright=(buffer[3] >> 3) & 0x1; header->original=(buffer[3] >> 2) & 0x1; header->emphasis=(buffer[3]) & 0x3; return ((fl=frame_length(header)) >= MIN_FRAME_SIZE ? fl : 0); }int frame_length(mp3header *header) { return header->sync == 0xFFE ? (frame_size_index[3-header->layer]*((header->version&1)+1)* header_bitrate(header)/header_frequency(header))+ header->padding : 1;}int header_layer(mp3header *h) {return layer_tab[h->layer];}int header_bitrate(mp3header *h) { return bitrate[h->version & 1][3-h->layer][h->bitrate-1];}int header_frequency(mp3header *h) { return frequencies[h->version][h->freq];}char *header_emphasis(mp3header *h) { return emphasis_text[h->emphasis];}char *header_mode(mp3header *h) { return mode_text[h->mode];}int sameConstant(mp3header *h1, mp3header *h2) { if((*(uint*)h1) == (*(uint*)h2)) return 1; if((h1->version == h2->version ) && (h1->layer == h2->layer ) && (h1->crc == h2->crc ) && (h1->freq == h2->freq ) && (h1->mode == h2->mode ) && (h1->copyright == h2->copyright ) && (h1->original == h2->original ) && (h1->emphasis == h2->emphasis )) return 1; else return 0;}int get_id3(mp3info *mp3) { int retcode=0; char fbuf[4]; if(mp3->datasize >= 128) { if(fseek(mp3->file, -128, SEEK_END )) { fprintf(stderr,"ERROR: Couldn't read last 128 bytes of %s!!\n",mp3->filename); retcode |= 4; } else { fread(fbuf,1,3,mp3->file); fbuf[3] = '\0'; mp3->id3.genre[0]=255; if (!strcmp((const char *)"TAG",(const char *)fbuf)) { mp3->id3_isvalid=1; mp3->datasize -= 128; fseek(mp3->file, -125, SEEK_END); fread(mp3->id3.title,1,30,mp3->file); mp3->id3.title[30] = '\0'; fread(mp3->id3.artist,1,30,mp3->file); mp3->id3.artist[30] = '\0'; fread(mp3->id3.album,1,30,mp3->file); mp3->id3.album[30] = '\0'; fread(mp3->id3.year,1,4,mp3->file); mp3->id3.year[4] = '\0'; fread(mp3->id3.comment,1,30,mp3->file); mp3->id3.comment[30] = '\0'; if(mp3->id3.comment[28] == '\0') { mp3->id3.track[0] = mp3->id3.comment[29]; } fread(mp3->id3.genre,1,1,mp3->file); unpad(mp3->id3.title); unpad(mp3->id3.artist); unpad(mp3->id3.album); unpad(mp3->id3.year); unpad(mp3->id3.comment); } } } return retcode;}/* Remove trailing whitespace from the end of a string */char *unpad(char *string) { char *pos=string+strlen(string)-1; while(isspace(pos[0])) (pos--)[0]=0; return string;}////////////////////////////////////////////////////////////////////////////// end of functions from mp3info - http://www.ibiblio.org/mp3info ///////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -