/* * (Re)fill the stream buffer that is to be decoded. If any data * still exists in the buffer then they are first shifted to be * front of the stream buffer. */ static int sox_mp3_input(sox_format_t * ft) { priv_t *p = (priv_t *) ft->priv; size_t bytes_read; size_t remaining; remaining = p->Stream.bufend - p->Stream.next_frame; /* libmad does not consume all the buffer it's given. Some * data, part of a truncated frame, is left unused at the * end of the buffer. That data must be put back at the * beginning of the buffer and taken in account for * refilling the buffer. This means that the input buffer * must be large enough to hold a complete frame at the * highest observable bit-rate (currently 448 kb/s). * TODO: Is 2016 bytes the size of the largest frame? * (448000*(1152/32000))/8 */ memmove(p->mp3_buffer, p->Stream.next_frame, remaining); bytes_read = lsx_readbuf(ft, p->mp3_buffer+remaining, p->mp3_buffer_size-remaining); if (bytes_read == 0) { return SOX_EOF; } p->mad_stream_buffer(&p->Stream, p->mp3_buffer, bytes_read+remaining); p->Stream.error = 0; return SOX_SUCCESS; }
static int dvms_read_header(sox_format_t * ft, struct dvms_header *hdr) { unsigned char hdrbuf[DVMS_HEADER_LEN]; unsigned char *pch = hdrbuf; int i; unsigned sum; if (lsx_readbuf(ft, hdrbuf, sizeof(hdrbuf)) != sizeof(hdrbuf)) { return (SOX_EOF); } for(i = sizeof(hdrbuf), sum = 0; i > /*2*/3; i--) /* Deti bug */ sum += *pch++; pch = hdrbuf; memcpy(hdr->Filename, pch, sizeof(hdr->Filename)); pch += sizeof(hdr->Filename); hdr->Id = get16_le(&pch); hdr->State = get16_le(&pch); hdr->Unixtime = get32_le(&pch); hdr->Usender = get16_le(&pch); hdr->Ureceiver = get16_le(&pch); hdr->Length = get32_le(&pch); hdr->Srate = get16_le(&pch); hdr->Days = get16_le(&pch); hdr->Custom1 = get16_le(&pch); hdr->Custom2 = get16_le(&pch); memcpy(hdr->Info, pch, sizeof(hdr->Info)); pch += sizeof(hdr->Info); memcpy(hdr->extend, pch, sizeof(hdr->extend)); pch += sizeof(hdr->extend); hdr->Crc = get16_le(&pch); if (sum != hdr->Crc) { lsx_report("DVMS header checksum error, read %u, calculated %u", hdr->Crc, sum); return (SOX_EOF); } return (SOX_SUCCESS); }
static int callback_read(void* ft_data, unsigned char* ptr, int nbytes) { sox_format_t* ft = (sox_format_t*)ft_data; return lsx_readbuf(ft, ptr, (size_t)nbytes); }
static int startread(sox_format_t * ft) { priv_t *p = (priv_t *) ft->priv; size_t ReadSize; sox_bool ignore_length = ft->signal.length == SOX_IGNORE_LENGTH; int open_library_result; LSX_DLLIBRARY_OPEN( p, mad_dl, MAD_FUNC_ENTRIES, "MAD decoder library", mad_library_names, open_library_result); if (open_library_result) return SOX_EOF; p->mp3_buffer_size = sox_globals.bufsiz; p->mp3_buffer = lsx_malloc(p->mp3_buffer_size); ft->signal.length = SOX_UNSPEC; if (ft->seekable) { #ifdef USING_ID3TAG read_comments(ft); rewind((FILE*)ft->fp); if (!ft->signal.length) #endif if (!ignore_length) ft->signal.length = mp3_duration_ms(ft); } p->mad_stream_init(&p->Stream); p->mad_frame_init(&p->Frame); p->mad_synth_init(&p->Synth); mad_timer_reset(&p->Timer); ft->encoding.encoding = SOX_ENCODING_MP3; /* Decode at least one valid frame to find out the input * format. The decoded frame will be saved off so that it * can be processed later. */ ReadSize = lsx_readbuf(ft, p->mp3_buffer, p->mp3_buffer_size); if (ReadSize != p->mp3_buffer_size && ferror((FILE*)ft->fp)) return SOX_EOF; p->mad_stream_buffer(&p->Stream, p->mp3_buffer, ReadSize); /* Find a valid frame before starting up. This makes sure * that we have a valid MP3 and also skips past ID3v2 tags * at the beginning of the audio file. */ p->Stream.error = 0; while (p->mad_frame_decode(&p->Frame,&p->Stream)) { /* check whether input buffer needs a refill */ if (p->Stream.error == MAD_ERROR_BUFLEN) { if (sox_mp3_input(ft) == SOX_EOF) return SOX_EOF; continue; } /* Consume any ID3 tags */ sox_mp3_inputtag(ft); /* FIXME: We should probably detect when we've read * a bunch of non-ID3 data and still haven't found a * frame. In that case we can abort early without * scanning the whole file. */ p->Stream.error = 0; } if (p->Stream.error) { lsx_fail_errno(ft,SOX_EOF,"No valid MP3 frame found"); return SOX_EOF; } switch(p->Frame.header.mode) { case MAD_MODE_SINGLE_CHANNEL: case MAD_MODE_DUAL_CHANNEL: case MAD_MODE_JOINT_STEREO: case MAD_MODE_STEREO: ft->signal.channels = MAD_NCHANNELS(&p->Frame.header); break; default: lsx_fail_errno(ft, SOX_EFMT, "Cannot determine number of channels"); return SOX_EOF; } p->FrameCount=1; p->mad_timer_add(&p->Timer,p->Frame.header.duration); p->mad_synth_frame(&p->Synth,&p->Frame); ft->signal.precision = MP3_MAD_PRECISION; ft->signal.rate=p->Synth.pcm.samplerate; if (ignore_length) ft->signal.length = SOX_UNSPEC; else { ft->signal.length = (uint64_t)(ft->signal.length * .001 * ft->signal.rate + .5); ft->signal.length *= ft->signal.channels; /* Keep separate from line above! */ } p->cursamp = 0; return SOX_SUCCESS; }
static char const * auto_detect_format(sox_format_t * ft, char const * ext) { char data[AUTO_DETECT_SIZE]; size_t len = lsx_readbuf(ft, data, ft->seekable? sizeof(data) : PIPE_AUTO_DETECT_SIZE); #define CHECK(type, p2, l2, d2, p1, l1, d1) if (len >= p1 + l1 && \ !memcmp(data + p1, d1, (size_t)l1) && !memcmp(data + p2, d2, (size_t)l2)) return #type; CHECK(voc , 0, 0, "" , 0, 20, "Creative Voice File\x1a") CHECK(smp , 0, 0, "" , 0, 17, "SOUND SAMPLE DATA") CHECK(wve , 0, 0, "" , 0, 15, "ALawSoundFile**") CHECK(gsrt , 0, 0, "" , 16, 9, "ring.bin") CHECK(amr-wb, 0, 0, "" , 0, 9, "#!AMR-WB\n") CHECK(prc , 0, 0, "" , 0, 8, "\x37\x00\x00\x10\x6d\x00\x00\x10") CHECK(sph , 0, 0, "" , 0, 7, "NIST_1A") CHECK(amr-nb, 0, 0, "" , 0, 6, "#!AMR\n") CHECK(txw , 0, 0, "" , 0, 6, "LM8953") CHECK(sndt , 0, 0, "" , 0, 6, "SOUND\x1a") CHECK(vorbis, 0, 4, "OggS" , 29, 6, "vorbis") CHECK(opus , 0, 4, "OggS" , 28, 8, "OpusHead") CHECK(speex , 0, 4, "OggS" , 28, 6, "Speex") CHECK(hcom ,65, 4, "FSSD" , 128,4, "HCOM") CHECK(wav , 0, 4, "RIFF" , 8, 4, "WAVE") CHECK(wav , 0, 4, "RIFX" , 8, 4, "WAVE") CHECK(wav , 0, 4, "RF64" , 8, 4, "WAVE") CHECK(aiff , 0, 4, "FORM" , 8, 4, "AIFF") CHECK(aifc , 0, 4, "FORM" , 8, 4, "AIFC") CHECK(8svx , 0, 4, "FORM" , 8, 4, "8SVX") CHECK(maud , 0, 4, "FORM" , 8, 4, "MAUD") CHECK(xa , 0, 0, "" , 0, 4, "XA\0\0") CHECK(xa , 0, 0, "" , 0, 4, "XAI\0") CHECK(xa , 0, 0, "" , 0, 4, "XAJ\0") CHECK(au , 0, 0, "" , 0, 4, ".snd") CHECK(au , 0, 0, "" , 0, 4, "dns.") CHECK(au , 0, 0, "" , 0, 4, "\0ds.") CHECK(au , 0, 0, "" , 0, 4, ".sd\0") CHECK(flac , 0, 0, "" , 0, 4, "fLaC") CHECK(avr , 0, 0, "" , 0, 4, "2BIT") CHECK(caf , 0, 0, "" , 0, 4, "caff") CHECK(wv , 0, 0, "" , 0, 4, "wvpk") CHECK(paf , 0, 0, "" , 0, 4, " paf") CHECK(sf , 0, 0, "" , 0, 4, "\144\243\001\0") CHECK(sf , 0, 0, "" , 0, 4, "\0\001\243\144") CHECK(sf , 0, 0, "" , 0, 4, "\144\243\002\0") CHECK(sf , 0, 0, "" , 0, 4, "\0\002\243\144") CHECK(sf , 0, 0, "" , 0, 4, "\144\243\003\0") CHECK(sf , 0, 0, "" , 0, 4, "\0\003\243\144") CHECK(sf , 0, 0, "" , 0, 4, "\144\243\004\0") CHECK(sox , 0, 0, "" , 0, 4, ".SoX") CHECK(sox , 0, 0, "" , 0, 4, "XoS.") if (ext && !strcasecmp(ext, "snd")) CHECK(sndr , 7, 1, "" , 0, 2, "\0") #undef CHECK #if HAVE_MAGIC if (sox_globals.use_magic) { static magic_t magic; char const * filetype = NULL; if (!magic) { magic = magic_open(MAGIC_MIME | MAGIC_SYMLINK); if (magic) magic_load(magic, NULL); } if (magic) filetype = magic_buffer(magic, data, len); if (filetype && strncmp(filetype, "application/octet-stream", (size_t)24) && !lsx_strends(filetype, "/unknown") && strncmp(filetype, "text/plain", (size_t)10) ) return filetype; else if (filetype) lsx_debug("libmagic detected %s", filetype); } #endif return NULL; }
static int startread(sox_format_t * ft) { priv_t * avr = (priv_t *)ft->priv; int rc; lsx_reads(ft, avr->magic, (size_t)4); if (strncmp (avr->magic, AVR_MAGIC, (size_t)4)) { lsx_fail_errno(ft,SOX_EHDR,"AVR: unknown header"); return(SOX_EOF); } lsx_readbuf(ft, avr->name, sizeof(avr->name)); lsx_readw (ft, &(avr->mono)); if (avr->mono) { ft->signal.channels = 2; } else { ft->signal.channels = 1; } lsx_readw (ft, &(avr->rez)); if (avr->rez == 8) { ft->encoding.bits_per_sample = 8; } else if (avr->rez == 16) { ft->encoding.bits_per_sample = 16; } else { lsx_fail_errno(ft,SOX_EFMT,"AVR: unsupported sample resolution"); return(SOX_EOF); } lsx_readw (ft, &(avr->sign)); if (avr->sign) { ft->encoding.encoding = SOX_ENCODING_SIGN2; } else { ft->encoding.encoding = SOX_ENCODING_UNSIGNED; } lsx_readw (ft, &(avr->loop)); lsx_readw (ft, &(avr->midi)); lsx_readdw (ft, &(avr->rate)); /* * No support for AVRs created by ST-Replay, * Replay Proffesional and PRO-Series 12. * * Just masking the upper byte out. */ ft->signal.rate = (avr->rate & 0x00ffffff); lsx_readdw (ft, &(avr->size)); lsx_readdw (ft, &(avr->lbeg)); lsx_readdw (ft, &(avr->lend)); lsx_readw (ft, &(avr->res1)); lsx_readw (ft, &(avr->res2)); lsx_readw (ft, &(avr->res3)); lsx_readbuf(ft, avr->ext, sizeof(avr->ext)); lsx_readbuf(ft, avr->user, sizeof(avr->user)); rc = lsx_rawstartread (ft); if (rc) return rc; return(SOX_SUCCESS); }
/*----------------------------------------------------------------- * startread() -- start reading a VOC file *-----------------------------------------------------------------*/ static int startread(sox_format_t * ft) { int rtn = SOX_SUCCESS; char header[20]; priv_t * v = (priv_t *) ft->priv; unsigned short sbseek; int rc; int ii; /* for getting rid of lseek */ unsigned char uc; if (lsx_readbuf(ft, header, (size_t)20) != 20) { lsx_fail_errno(ft, SOX_EHDR, "unexpected EOF in VOC header"); return (SOX_EOF); } if (strncmp(header, "Creative Voice File\032", (size_t)19)) { lsx_fail_errno(ft, SOX_EHDR, "VOC file header incorrect"); return (SOX_EOF); } /* read the offset to data, from start of file */ /* after this read we have read 20 bytes of header + 2 */ lsx_readw(ft, &sbseek); /* ANN: read to skip the header, instead of lseek */ /* this should allow use with pipes.... */ for (ii = 22; ii < sbseek; ii++) lsx_readb(ft, &uc); v->rate = -1; v->block_remaining = 0; v->total_size = 0; /* ANN added */ v->extended = 0; /* read until we get the format information.... */ rc = getblock(ft); if (rc) return rc; /* get rate of data */ if (v->rate == -1) { lsx_fail_errno(ft, SOX_EOF, "Input .voc file had no sound!"); return (SOX_EOF); } /* setup word length of data */ /* ANN: Check VOC format and map to the proper libSoX format value */ switch (v->format) { case VOC_FMT_LIN8U: /* 0 8 bit unsigned linear PCM */ ft->encoding.encoding = SOX_ENCODING_UNSIGNED; v->size = 8; break; case VOC_FMT_CRLADPCM4: /* 1 Creative 8-bit to 4-bit ADPCM */ ft->encoding.encoding = SOX_ENCODING_CL_ADPCM; v->size = 4; break; case VOC_FMT_CRLADPCM3: /* 2 Creative 8-bit to 3-bit ADPCM */ ft->encoding.encoding = SOX_ENCODING_CL_ADPCM; v->size = 3; break; case VOC_FMT_CRLADPCM2: /* 3 Creative 8-bit to 2-bit ADPCM */ ft->encoding.encoding = SOX_ENCODING_CL_ADPCM; v->size = 2; break; case VOC_FMT_LIN16: /* 4 16-bit signed PCM */ ft->encoding.encoding = SOX_ENCODING_SIGN2; v->size = 16; break; case VOC_FMT_ALAW: /* 6 CCITT a-Law 8-bit PCM */ ft->encoding.encoding = SOX_ENCODING_ALAW; v->size = 8; break; case VOC_FMT_MU255: /* 7 CCITT u-Law 8-bit PCM */ ft->encoding.encoding = SOX_ENCODING_ULAW; v->size = 8; break; case VOC_FMT_CRLADPCM4A: /*0x200 Creative 16-bit to 4-bit ADPCM */ ft->encoding.encoding = SOX_ENCODING_CL_ADPCM16; v->size = 4; break; default: lsx_fail("Unknown VOC format %d", v->format); rtn = SOX_EOF; break; } ft->encoding.bits_per_sample = v->size; /* setup number of channels */ if (ft->signal.channels == 0) ft->signal.channels = v->channels; return (SOX_SUCCESS); }
static int sox_mp3seek(sox_format_t * ft, uint64_t offset) { priv_t * p = (priv_t *) ft->priv; size_t initial_bitrate = p->Frame.header.bitrate; size_t tagsize = 0, consumed = 0; sox_bool vbr = sox_false; /* Variable Bit Rate */ sox_bool depadded = sox_false; uint64_t to_skip_samples = 0; /* Reset all */ lsx_rewind(ft); mad_timer_reset(&p->Timer); p->FrameCount = 0; /* They where opened in startread */ mad_synth_finish(&p->Synth); p->mad_frame_finish(&p->Frame); p->mad_stream_finish(&p->Stream); p->mad_stream_init(&p->Stream); p->mad_frame_init(&p->Frame); p->mad_synth_init(&p->Synth); offset /= ft->signal.channels; to_skip_samples = offset; while(sox_true) { /* Read data from the MP3 file */ size_t padding = 0; size_t read; size_t leftover = p->Stream.bufend - p->Stream.next_frame; memcpy(p->mp3_buffer, p->Stream.this_frame, leftover); read = lsx_readbuf(ft, p->mp3_buffer + leftover, p->mp3_buffer_size - leftover); if (read == 0) { lsx_debug("seek failure. unexpected EOF (frames=%" PRIuPTR " leftover=%" PRIuPTR ")", p->FrameCount, leftover); break; } for (; !depadded && padding < read && !p->mp3_buffer[padding]; ++padding); depadded = sox_true; p->mad_stream_buffer(&p->Stream, p->mp3_buffer + padding, leftover + read - padding); while (sox_true) { /* Decode frame headers */ static unsigned short samples; p->Stream.error = MAD_ERROR_NONE; /* Not an audio frame */ if (p->mad_header_decode(&p->Frame.header, &p->Stream) == -1) { if (p->Stream.error == MAD_ERROR_BUFLEN) break; /* Normal behaviour; get some more data from the file */ if (!MAD_RECOVERABLE(p->Stream.error)) { lsx_warn("unrecoverable MAD error"); break; } if (p->Stream.error == MAD_ERROR_LOSTSYNC) { unsigned available = (p->Stream.bufend - p->Stream.this_frame); tagsize = tagtype(p->Stream.this_frame, (size_t) available); if (tagsize) { /* It's some ID3 tags, so just skip */ if (tagsize >= available) { lsx_seeki(ft, (off_t)(tagsize - available), SEEK_CUR); depadded = sox_false; } p->mad_stream_skip(&p->Stream, min(tagsize, available)); } else lsx_warn("MAD lost sync"); } else lsx_warn("recoverable MAD error"); continue; } consumed += p->Stream.next_frame - p->Stream.this_frame; vbr |= (p->Frame.header.bitrate != initial_bitrate); samples = 32 * MAD_NSBSAMPLES(&p->Frame.header); p->FrameCount++; p->mad_timer_add(&p->Timer, p->Frame.header.duration); if(to_skip_samples <= samples) { p->mad_frame_decode(&p->Frame,&p->Stream); p->mad_synth_frame(&p->Synth, &p->Frame); p->cursamp = to_skip_samples; return SOX_SUCCESS; } else to_skip_samples -= samples; /* If not VBR, we can extrapolate frame size */ if (p->FrameCount == 64 && !vbr) { p->FrameCount = offset / samples; to_skip_samples = offset % samples; if (SOX_SUCCESS != lsx_seeki(ft, (off_t)(p->FrameCount * consumed / 64 + tagsize), SEEK_SET)) return SOX_EOF; /* Reset Stream for refilling buffer */ p->mad_stream_finish(&p->Stream); p->mad_stream_init(&p->Stream); break; } } }; return SOX_EOF; }
static int start_read(sox_format_t * ft) { unsigned long header_size_ul = 0, num_samples_ul = 0; sox_encoding_t encoding = SOX_ENCODING_SIGN2; size_t header_size, bytes_read; size_t num_samples = 0; unsigned bytes_per_sample = 0; unsigned channels = 1; unsigned rate = 16000; char fldname[64], fldtype[16], fldsval[128]; char * buf; /* Magic header */ if (lsx_reads(ft, fldname, (size_t)8) || strncmp(fldname, "NIST_1A", (size_t)7) != 0) { lsx_fail_errno(ft, SOX_EHDR, "Sphere header does not begin with magic word `NIST_1A'"); return (SOX_EOF); } if (lsx_reads(ft, fldsval, (size_t)8)) { lsx_fail_errno(ft, SOX_EHDR, "Error reading Sphere header"); return (SOX_EOF); } /* Determine header size, and allocate a buffer large enough to hold it. */ sscanf(fldsval, "%lu", &header_size_ul); buf = lsx_malloc(header_size = header_size_ul); /* Skip what we have read so far */ header_size -= 16; if (lsx_reads(ft, buf, header_size) == SOX_EOF) { lsx_fail_errno(ft, SOX_EHDR, "Error reading Sphere header"); free(buf); return (SOX_EOF); } header_size -= (strlen(buf) + 1); while (strncmp(buf, "end_head", (size_t)8) != 0) { if (strncmp(buf, "sample_n_bytes", (size_t)14) == 0) sscanf(buf, "%63s %15s %u", fldname, fldtype, &bytes_per_sample); else if (strncmp(buf, "channel_count", (size_t)13) == 0) sscanf(buf, "%63s %15s %u", fldname, fldtype, &channels); else if (strncmp(buf, "sample_count ", (size_t)13) == 0) sscanf(buf, "%53s %15s %lu", fldname, fldtype, &num_samples_ul); else if (strncmp(buf, "sample_rate ", (size_t)12) == 0) sscanf(buf, "%53s %15s %u", fldname, fldtype, &rate); else if (strncmp(buf, "sample_coding", (size_t)13) == 0) { sscanf(buf, "%63s %15s %127s", fldname, fldtype, fldsval); if (!strcasecmp(fldsval, "ulaw") || !strcasecmp(fldsval, "mu-law")) encoding = SOX_ENCODING_ULAW; else if (!strcasecmp(fldsval, "pcm")) encoding = SOX_ENCODING_SIGN2; else { lsx_fail_errno(ft, SOX_EFMT, "sph: unsupported coding `%s'", fldsval); free(buf); return SOX_EOF; } } else if (strncmp(buf, "sample_byte_format", (size_t)18) == 0) { sscanf(buf, "%53s %15s %127s", fldname, fldtype, fldsval); if (strcmp(fldsval, "01") == 0) /* Data is little endian. */ ft->encoding.reverse_bytes = MACHINE_IS_BIGENDIAN; else if (strcmp(fldsval, "10") == 0) /* Data is big endian. */ ft->encoding.reverse_bytes = MACHINE_IS_LITTLEENDIAN; else if (strcmp(fldsval, "1")) { lsx_fail_errno(ft, SOX_EFMT, "sph: unsupported coding `%s'", fldsval); free(buf); return SOX_EOF; } } if (lsx_reads(ft, buf, header_size) == SOX_EOF) { lsx_fail_errno(ft, SOX_EHDR, "Error reading Sphere header"); free(buf); return (SOX_EOF); } header_size -= (strlen(buf) + 1); } if (!bytes_per_sample) bytes_per_sample = encoding == SOX_ENCODING_ULAW? 1 : 2; while (header_size) { bytes_read = lsx_readbuf(ft, buf, header_size); if (bytes_read == 0) { free(buf); return (SOX_EOF); } header_size -= bytes_read; } free(buf); if (ft->seekable) { /* Check first four bytes of data to see if it's shorten compressed. */ char shorten_check[4]; if (lsx_readchars(ft, shorten_check, sizeof(shorten_check))) return SOX_EOF; lsx_seeki(ft, -(off_t)sizeof(shorten_check), SEEK_CUR); if (!memcmp(shorten_check, "ajkg", sizeof(shorten_check))) { lsx_fail_errno(ft, SOX_EFMT, "File uses shorten compression, cannot handle this."); return (SOX_EOF); } } num_samples = num_samples_ul; return lsx_check_read_params(ft, channels, (sox_rate_t)rate, encoding, bytes_per_sample << 3, (uint64_t)num_samples * channels, sox_true); }