📄 wav_gsm610.c
字号:
pgsm610 = (GSM610_PRIVATE*) psf->fdata ; sptr = (short*) psf->buffer ; bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ; while (len > 0) { readcount = (len >= bufferlen) ? bufferlen : len ; count = wav_gsm610_read (psf, pgsm610, sptr, readcount) ; for (k = 0 ; k < readcount ; k++) ptr [index+k] = normfact * (double) (sptr [k]) ; index += readcount ; total += count ; len -= readcount ; } ; return total ;} /* wav_gsm610_read_d */static off_t wav_gsm610_seek (SF_PRIVATE *psf, off_t offset, int whence){ GSM610_PRIVATE *pgsm610 ; int newblock, newsample ; if (! psf->fdata) return 0 ; pgsm610 = (GSM610_PRIVATE*) psf->fdata ; if (! (psf->blockwidth && psf->datalength && psf->dataoffset)) { psf->error = SFE_BAD_SEEK ; return ((off_t) -1) ; } ; switch (whence) { case SEEK_SET : if (offset < 0 || offset > pgsm610->blocks * GSM610_SAMPLES) { psf->error = SFE_BAD_SEEK ; return ((off_t) -1) ; } ; newblock = offset / GSM610_SAMPLES ; newsample = offset % GSM610_SAMPLES ; break ; case SEEK_CUR : if (psf->current + offset < 0 || psf->current + offset > pgsm610->blocks * GSM610_SAMPLES) { psf->error = SFE_BAD_SEEK ; return ((off_t) -1) ; } ; newblock = (psf->current + offset) / GSM610_SAMPLES ; newsample = (psf->current + offset) % GSM610_SAMPLES ; break ; case SEEK_END : if (offset > 0 || GSM610_SAMPLES * pgsm610->blocks + offset < 0) { psf->error = SFE_BAD_SEEK ; return ((off_t) -1) ; } ; newblock = (GSM610_SAMPLES * pgsm610->blocks + offset) / GSM610_SAMPLES ; newsample = (GSM610_SAMPLES * pgsm610->blocks + offset) % GSM610_SAMPLES ; break ; default : psf->error = SFE_BAD_SEEK ; return ((off_t) -1) ; } ; if (psf->mode == SF_MODE_READ) { fseek (psf->file, (int) (psf->dataoffset + newblock * GSM610_BLOCKSIZE), SEEK_SET) ; pgsm610->blockcount = newblock ; wav_gsm610_read_block (psf, pgsm610) ; pgsm610->samplecount = newsample ; } else { /* What to do about write??? */ psf->error = SFE_BAD_SEEK ; return ((off_t) -1) ; } ; psf->current = newblock * GSM610_SAMPLES + newsample ; return psf->current ;} /* wav_gsm610_seek *//*==========================================================================================** GSM 6.10 Write Functions.*//*==========================================================================================*/static intwav_gsm610_write_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610){ int k ; /* Encode the samples. */ gsm_encode (pgsm610->gsm_data, pgsm610->samples, pgsm610->block) ; gsm_encode (pgsm610->gsm_data, pgsm610->samples+GSM610_SAMPLES/2, pgsm610->block+GSM610_BLOCKSIZE/2) ; /* Write the block to disk. */ if ((k = fwrite (pgsm610->block, 1, GSM610_BLOCKSIZE, psf->file)) != GSM610_BLOCKSIZE) psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, GSM610_BLOCKSIZE) ; pgsm610->samplecount = 0 ; pgsm610->blockcount ++ ; /* Set samples to zero for next block. */ memset (pgsm610->samples, 0, GSM610_SAMPLES * sizeof (short)) ; return 1 ;} /* wav_gsm610_write_block */static int wav_gsm610_write (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610, short *ptr, int len){ int count, total = 0, index = 0 ; while (index < len) { count = GSM610_SAMPLES - pgsm610->samplecount ; if (count > len - index) count = len - index ; memcpy (&(pgsm610->samples [pgsm610->samplecount]), &(ptr [index]), count * sizeof (short)) ; index += count ; pgsm610->samplecount += count ; total = index ; if (pgsm610->samplecount >= GSM610_SAMPLES) wav_gsm610_write_block (psf, pgsm610) ; } ; return total ; } /* wav_gsm610_write */static int wav_gsm610_write_s (SF_PRIVATE *psf, short *ptr, int len){ GSM610_PRIVATE *pgsm610 ; int total ; if (! psf->fdata) return 0 ; pgsm610 = (GSM610_PRIVATE*) psf->fdata ; total = wav_gsm610_write (psf, pgsm610, ptr, len) ; return total ;} /* wav_gsm610_write_s */static int wav_gsm610_write_i (SF_PRIVATE *psf, int *ptr, int len){ GSM610_PRIVATE *pgsm610 ; short *sptr ; int k, bufferlen, writecount = 0, count ; int index = 0, total = 0 ; if (! psf->fdata) return 0 ; pgsm610 = (GSM610_PRIVATE*) psf->fdata ; sptr = (short*) psf->buffer ; bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ; while (len > 0) { writecount = (len >= bufferlen) ? bufferlen : len ; for (k = 0 ; k < writecount ; k++) sptr [k] = (short) ptr [index+k] ; count = wav_gsm610_write (psf, pgsm610, sptr, writecount) ; index += writecount ; total += count ; len -= writecount ; } ; return total ;} /* wav_gsm610_write_i */static int wav_gsm610_write_f (SF_PRIVATE *psf, float *ptr, int len){ GSM610_PRIVATE *pgsm610 ; short *sptr ; int k, bufferlen, writecount = 0, count ; int index = 0, total = 0 ; if (! psf->fdata) return 0 ; pgsm610 = (GSM610_PRIVATE*) psf->fdata ; sptr = (short*) psf->buffer ; bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ; while (len > 0) { writecount = (len >= bufferlen) ? bufferlen : len ; for (k = 0 ; k < writecount ; k++) sptr [k] = (short) (1.0 * ptr [index+k]) ; count = wav_gsm610_write (psf, pgsm610, sptr, writecount) ; index += writecount ; total += count ; len -= writecount ; } ; return total ;} /* wav_gsm610_write_f */static int wav_gsm610_write_d (SF_PRIVATE *psf, double *ptr, int len, int normalize){ GSM610_PRIVATE *pgsm610 ; short *sptr ; int k, bufferlen, writecount = 0, count ; int index = 0, total = 0 ; double normfact ; normfact = (normalize ? (double) 0x8000 : 1.0) ; if (! psf->fdata) return 0 ; pgsm610 = (GSM610_PRIVATE*) psf->fdata ; sptr = (short*) psf->buffer ; bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ; while (len > 0) { writecount = (len >= bufferlen) ? bufferlen : len ; for (k = 0 ; k < writecount ; k++) sptr [k] = (short) (normfact * ptr [index+k]) ; count = wav_gsm610_write (psf, pgsm610, sptr, writecount) ; index += writecount ; total += count ; len -= writecount ; } ; return total ;} /* wav_gsm610_write_d */static intwav_gsm610_write_header (SF_PRIVATE *psf){ int fmt_size, blockalign, samplesperblock, bytespersec ; blockalign = GSM610_BLOCKSIZE ; samplesperblock = GSM610_SAMPLES ; bytespersec = (psf->sf.samplerate * blockalign) / samplesperblock ; /* Reset the current header length to zero. */ psf->header [0] = 0 ; psf->headindex = 0 ; fseek (psf->file, 0, SEEK_SET) ; /* RIFF marker, length, WAVE and 'fmt ' markers. */ psf_binheader_writef (psf, "mlmm", RIFF_MARKER, psf->filelength - 8, WAVE_MARKER, fmt_MARKER) ; /* fmt chunk. */ fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 ; /* fmt : size, WAV format type, channels. */ psf_binheader_writef (psf, "lww", fmt_size, WAVE_FORMAT_GSM610, psf->sf.channels) ; /* fmt : samplerate, bytespersec. */ psf_binheader_writef (psf, "ll", psf->sf.samplerate, bytespersec) ; /* fmt : blockalign, bitwidth, extrabytes, samplesperblock. */ psf_binheader_writef (psf, "wwww", blockalign, 0, 2, samplesperblock) ; /* Fact chunk : marker, chunk size, samples */ psf_binheader_writef (psf, "mll", fact_MARKER, sizeof (int), psf->sf.samples) ; /* DATA chunk : marker, datalength. */ psf_binheader_writef (psf, "ml", data_MARKER, psf->datalength) ; fwrite (psf->header, psf->headindex, 1, psf->file) ; psf->dataoffset = psf->headindex ; psf->datalength = (psf->sf.samples / samplesperblock) * samplesperblock ; if (psf->sf.samples % samplesperblock) psf->datalength += samplesperblock ; return 0 ;} /* wav_gsm610_write_header */int wav_gsm610_close (SF_PRIVATE *psf){ GSM610_PRIVATE *pgsm610 ; if (! psf->fdata) return 0 ; pgsm610 = (GSM610_PRIVATE*) psf->fdata ; if (psf->mode == SF_MODE_WRITE) { /* If a block has been partially assembled, write it out ** as the final block. */ if (pgsm610->samplecount && pgsm610->samplecount < GSM610_SAMPLES) wav_gsm610_write_block (psf, pgsm610) ; /* Now we know for certain the length of the file we can ** re-write correct values for the RIFF and data chunks. */ fseek (psf->file, 0, SEEK_END) ; psf->filelength = ftell (psf->file) ; psf->sf.samples = GSM610_SAMPLES * pgsm610->blockcount ; psf->datalength = psf->filelength - psf->dataoffset ; wav_gsm610_write_header (psf) ; } ; if (pgsm610->gsm_data) gsm_destroy (pgsm610->gsm_data) ; if (psf->fdata) free (psf->fdata) ; psf->fdata = NULL ; return 0 ;} /* wav_gsm610_close */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -