📄 ogg.c
字号:
bytes = sizeof (float) * psf->sf.channels * frames ; if (bytes > pogg->cache_size) { new_block = realloc (pogg->cache_pcm, bytes) ; if (new_block == NULL) /* XXX : SFE_MALLOC_FAILED */ return -1 ; pogg->cache_pcm = new_block ; pogg->cache_size = bytes ; } ; memcpy (pogg->cache_pcm, pcm, bytes) ; pogg->cache_frames = frames ; pogg->cache_remaining = frames ; if (pogg->cache_granulepos != -1) pogg->cache_granulepos += frames ; pogg_copyout (psf) ; return 0 ;} /* pogg_decode */static intpogg_read_packet (OGGZ * oggz, ogg_packet * op, long serialno, void * data){ SF_PRIVATE * psf = (SF_PRIVATE *) data ; OGG_PRIVATE * pogg = (OGG_PRIVATE *) psf->fdata ; FishSound * fsound = pogg->fsound ; /* Avoid warning message. */ oggz = NULL ; serialno = 0 ; fish_sound_decode (fsound, op->packet, op->bytes) ; if (op->granulepos != -1) pogg->cache_granulepos = op->granulepos ; if (pogg->remaining == 0) return OGGZ_STOP_OK ; return OGGZ_CONTINUE ;} /* pogg_read_packet */static sf_count_tpogg_read_loop (SF_PRIVATE *psf, sf_count_t len){ OGG_PRIVATE * pogg = (OGG_PRIVATE *) psf->fdata ; long nread = 1024 ; sf_count_t ret = len ; /** Calculate nr. frames remaining */ pogg->remaining = len / psf->sf.channels ; /** Serve out any remaining cached data first */ pogg_copyout (psf) ; while (nread > 0 && pogg->remaining > 0) nread = oggz_read (pogg->oggz, 1024) ; if (nread == 0) ret -= pogg->remaining * psf->sf.channels ; return ret ;} /* pogg_read_loop */static sf_count_tpogg_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len){ OGG_PRIVATE * pogg = (OGG_PRIVATE *) psf->fdata ; pogg->ptr = ptr ; pogg->pcmtype = POGG_PCM_SHORT ; return pogg_read_loop (psf, len) ;} /* pogg_read_s */static sf_count_tpogg_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len){ OGG_PRIVATE * pogg = (OGG_PRIVATE *) psf->fdata ; pogg->ptr = ptr ; pogg->pcmtype = POGG_PCM_INT ; return pogg_read_loop (psf, len) ;} /* pogg_read_i */static sf_count_tpogg_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len){ OGG_PRIVATE * pogg = (OGG_PRIVATE *) psf->fdata ; pogg->ptr = ptr ; pogg->pcmtype = POGG_PCM_FLOAT ; return pogg_read_loop (psf, len) ;} /* pogg_read_f */static sf_count_tpogg_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len){ OGG_PRIVATE * pogg = (OGG_PRIVATE *) psf->fdata ; pogg->ptr = ptr ; pogg->pcmtype = POGG_PCM_DOUBLE ; return pogg_read_loop (psf, len) ;} /* pogg_read_d *//*------------------------------------------------------------------------------** Seek functions*/static sf_count_tpogg_seek (SF_PRIVATE *psf, int mode, sf_count_t seek_from_start){ OGG_PRIVATE * pogg = (OGG_PRIVATE *) psf->fdata ; ogg_int64_t units = seek_from_start * 1000 / psf->sf.samplerate ; if (mode != SFM_READ) { psf->error = SFE_BAD_SEEK ; return SF_SEEK_ERROR ; } ; oggz_seek_units (pogg->oggz, units, SEEK_SET) ; /* Invalidate cache and set the desired seek position */ pogg->cache_remaining = 0 ; pogg->cache_granulepos = -1 ; pogg->seek_from_start = seek_from_start ; return seek_from_start ;} /* pogg_seek *//*------------------------------------------------------------------------------** Write functions*/static intpogg_encoded (FishSound * fsound, unsigned char * buf, long bytes, void * user_data){ SF_PRIVATE * psf = (SF_PRIVATE *) user_data ; OGG_PRIVATE * pogg = (OGG_PRIVATE *) psf->fdata ; ogg_packet op ; int err ; op.packet = buf ; op.bytes = bytes ; op.b_o_s = pogg->b_o_s ; op.e_o_s = 0 ; op.granulepos = fish_sound_get_frameno (fsound) ; op.packetno = -1 ; err = oggz_write_feed (pogg->oggz, &op, pogg->serialno, 0, NULL) ; pogg->b_o_s = 0 ; return OGGZ_CONTINUE ;} /* pogg_encoded */static intpogg_write_anx_headers (SF_PRIVATE *psf, int format){ OGG_PRIVATE * pogg = (OGG_PRIVATE *) psf->fdata ; unsigned char buf [128] ; long anx_serialno ; int headers_len = 0 ; const char * content_type ; ogg_packet op ; int err ; anx_serialno = oggz_serialno_new (pogg->oggz) ; /* Write Annodex header */ memset (buf, 0, 48) ; snprintf (buf, 8, "Annodex") ; /* Version */ *(ogg_int16_t *) &buf [8] = (ogg_int16_t) POGG_ANX_VERSION_MAJOR ; *(ogg_int16_t *) &buf [10] = (ogg_int16_t) POGG_ANX_VERSION_MINOR ; if (CPU_IS_BIG_ENDIAN) endswap_short_array ((short *) &buf [8], 2) ; /* Timebase numerator */ *(ogg_int64_t *) &buf [12] = (ogg_int64_t) 0 ; /* Timebase denominator */ *(ogg_int64_t *) &buf [20] = (ogg_int64_t) 1 ; if (CPU_IS_BIG_ENDIAN) endswap_long_array ((long *) &buf [12], 2) ; op.packet = buf ; op.bytes = 48 ; op.b_o_s = 1 ; op.e_o_s = 0 ; op.granulepos = 0 ; op.packetno = -1 ; err = oggz_write_feed (pogg->oggz, &op, anx_serialno, 0, NULL) ; pogg->b_o_s = 0 ; /* Write AnxData header */ memset (buf, 0, 48) ; snprintf (buf, 8, "AnxData") ; /* Granule rate numerator */ *(ogg_int64_t *) &buf [8] = (ogg_int64_t) psf->sf.samplerate ; /* Granule rate denominator */ *(ogg_int64_t *) &buf [16] = (ogg_int64_t) 1 ; if (CPU_IS_BIG_ENDIAN) endswap_long_array ((long *) &buf [8], 2) ; /* Number of secondary header pages */ *(ogg_int32_t *) &buf [24] = (ogg_int32_t) 3 ; if (CPU_IS_BIG_ENDIAN) endswap_int_array ((int *) &buf [24], 1) ; /* Headers */ if (format == FISH_SOUND_VORBIS) content_type = POGG_VORBIS_CONTENT_TYPE ; else content_type = POGG_SPEEX_CONTENT_TYPE ; headers_len = snprintf ((char *) &buf [28], 100, "Content-Type : %s\r\n", content_type) ; op.packet = buf ; op.bytes = 28 + headers_len + 1 ; op.b_o_s = 1 ; op.e_o_s = 0 ; op.granulepos = 0 ; op.packetno = -1 ; err = oggz_write_feed (pogg->oggz, &op, pogg->serialno, 0, NULL) ; /* Write Annodex eos packet */ op.packet = NULL ; op.bytes = 0 ; op.b_o_s = 0 ; op.e_o_s = 1 ; op.granulepos = 0 ; op.packetno = -1 ; err = oggz_write_feed (pogg->oggz, &op, anx_serialno, 0, NULL) ; return 0 ;} /* pogg_write_anx_headers */static intpogg_write_header (SF_PRIVATE *psf){ OGG_PRIVATE * pogg = (OGG_PRIVATE *) psf->fdata ; OGGZ * oggz ; FishSound * fsound ; FishSoundInfo fsinfo ; oggz = oggz_new (OGGZ_WRITE) ; oggz_io_set_write (oggz, pogg_io_write, psf) ; fsinfo.samplerate = psf->sf.samplerate ; fsinfo.channels = psf->sf.channels ; switch (psf->sf.format & SF_FORMAT_SUBMASK) { case SF_FORMAT_VORBIS : fsinfo.format = FISH_SOUND_VORBIS ; break ; case SF_FORMAT_SPEEX : fsinfo.format = FISH_SOUND_SPEEX ; break ; } ; fsound = fish_sound_new (FISH_SOUND_ENCODE, &fsinfo) ; fish_sound_set_interleave (fsound, 1) ; fish_sound_set_encoded_callback (fsound, pogg_encoded, psf) ; pogg->oggz = oggz ; pogg->fsound = fsound ; pogg->serialno = oggz_serialno_new (oggz) ; pogg->b_o_s = 1 ; pogg->comments_written = 0 ; pogg->granulepos = 0 ; pogg->fptr = (float *) malloc (sizeof (float) * 1024) ; if ((psf->sf.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_ANX) pogg_write_anx_headers (psf, fsinfo.format) ; return 0 ;} /* pogg_write_header */static voidpogg_write_comments (SF_PRIVATE *psf){ OGG_PRIVATE * pogg = (OGG_PRIVATE *) psf->fdata ; int k ; int err ; for (k = 0 ; k < SF_MAX_STRINGS ; k++) { printf ("hrumf comment : %d => %s\n", psf->strings [k].type, psf->strings [k].str) ; /* if (psf->strings [k].type == 0) break ; */ if (psf->strings [k].type != 0) { printf ("adding comment : %d => %s\n", psf->strings [k].type, psf->strings [k].str) ; switch (psf->strings [k].type) { case SF_STR_SOFTWARE : err = fish_sound_comment_add_byname (pogg->fsound, "ENCODER", psf->strings [k].str) ; break ; case SF_STR_TITLE : err = fish_sound_comment_add_byname (pogg->fsound, "TITLE", psf->strings [k].str) ; break ; case SF_STR_COPYRIGHT : err = fish_sound_comment_add_byname (pogg->fsound, "COPYRIGHT", psf->strings [k].str) ; break ; case SF_STR_ARTIST : err = fish_sound_comment_add_byname (pogg->fsound, "ARTIST", psf->strings [k].str) ; break ; /* case SF_STR_COMMENT : fish_sound_comment_add_byname (pogg->fsound, "COMMENT", psf->strings [k].str) ; break ; */ case SF_STR_DATE : err = fish_sound_comment_add_byname (pogg->fsound, "DATE", psf->strings [k].str) ; break ; } ; } ; /* if type !0 */ } ; pogg->comments_written = 1 ; return ;} /* pogg_write_comments*/static sf_count_tpogg_write_s (SF_PRIVATE *psf, short *ptr, sf_count_t len){ OGG_PRIVATE * pogg = (OGG_PRIVATE *) psf->fdata ; long n, i, remaining = len / psf->sf.channels ; if (pogg->comments_written == 0) pogg_write_comments (psf) ; while (remaining > 0) { n = SF_MIN (remaining, 1024) ; for (i = 0 ; i < n * psf->sf.channels ; i++) pogg->fptr [i] = (float) ptr [i] ; fish_sound_encode (pogg->fsound, (float **) ptr, n) ; while (oggz_write (pogg->oggz, 1024) > 0) ; ptr += n * psf->sf.channels ; remaining -= n ; } ; return len ;} /* pogg_write_s */static sf_count_tpogg_write_i (SF_PRIVATE *psf, int *ptr, sf_count_t len){ OGG_PRIVATE * pogg = (OGG_PRIVATE *) psf->fdata ; long n, i, remaining = len / psf->sf.channels ; if (pogg->comments_written == 0) pogg_write_comments (psf) ; while (remaining > 0) { n = SF_MIN (remaining, 1024) ; for (i = 0 ; i < n * psf->sf.channels ; i++) pogg->fptr [i] = (float) ptr [i] ; fish_sound_encode (pogg->fsound, (float **) ptr, n) ; while (oggz_write (pogg->oggz, 1024) > 0) ; ptr += n * psf->sf.channels ; remaining -= n ; } ; return len ;} /* pogg_write_i */static sf_count_tpogg_write_f (SF_PRIVATE *psf, float *ptr, sf_count_t len){ OGG_PRIVATE * pogg = (OGG_PRIVATE *) psf->fdata ; long n, remaining = len / psf->sf.channels ; if (pogg->comments_written == 0) pogg_write_comments (psf) ; while (remaining > 0) { n = SF_MIN (remaining, 1024) ; fish_sound_encode (pogg->fsound, (float **) ptr, n) ; while (oggz_write (pogg->oggz, 1024) > 0) ; ptr += n * psf->sf.channels ; remaining -= n ; } ; return len ;} /* pog_write_f */static sf_count_tpogg_write_d (SF_PRIVATE *psf, double *ptr, sf_count_t len){ OGG_PRIVATE * pogg = (OGG_PRIVATE *) psf->fdata ; long n, i, remaining = len / psf->sf.channels ; if (pogg->comments_written == 0) pogg_write_comments (psf) ; while (remaining > 0) { n = SF_MIN (remaining, 1024) ; for (i = 0 ; i < n * psf->sf.channels ; i++) pogg->fptr [i] = (float) ptr [i] ; fish_sound_encode (pogg->fsound, (float **) ptr, n) ; while (oggz_write (pogg->oggz, 1024) > 0) ; ptr += n * psf->sf.channels ; remaining -= n ; } ; return len ;} /* pogg_write_d */#endif/*** Do not edit or modify anything in this comment block.** The arch-tag line is a file identity tag for the GNU Arch** revision control system.**** arch-tag: 9ff1fe9c-629e-4e9c-9ef5-3d0eb1e427a0*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -