int ffvorbis_encode(ffvorbis_enc *v) { ogg_packet pkt; int r; enum { W_HDR, W_COMM, W_BOOK, W_DATA }; switch (v->state) { case W_HDR: ffstr_set2(&v->data, &v->pkt_hdr); v->state = W_COMM; return FFVORBIS_RDATA; case W_COMM: ffvorbtag_fin(&v->vtag); if (0 != (r = _ffvorbis_tags(v, &v->data))) return ERR(v, r); v->state = W_BOOK; return FFVORBIS_RDATA; case W_BOOK: ffstr_set2(&v->data, &v->pkt_book); v->state = W_DATA; return FFVORBIS_RDATA; } int n = (uint)(v->pcmlen / (sizeof(float) * v->channels)); v->pcmlen = 0; for (;;) { r = vorbis_encode(v->vctx, v->pcm, n, &pkt); if (r < 0) { v->err = r; return FFVORBIS_RERR; } else if (r == 0) { if (v->fin) { n = -1; continue; } return FFVORBIS_RMORE; } break; } v->granulepos = pkt.granulepos; ffstr_set(&v->data, pkt.packet, pkt.bytes); return (pkt.e_o_s) ? FFVORBIS_RDONE : FFVORBIS_RDATA; }
/** * \brief Decode music chunks * \param[in] start Start of music chunks. * \param[in] end End of music chunks. * \param[in] songNames Song titles. * \return On success true, otherwise false. */ PUBLIC wtBoolean AudioFile_ReduxDecodeMusic( const W32 start, const W32 end, const char *path, char *songNames[] ) { SW8 *buffChunk; void *buffWav; W32 i; W32 length; char filename[ 1024 ]; W32 uncompr_length; printf( "Decoding Music (This could take a while)..." ); if( ! ADLIB_Init( 44100 ) ) { return false; } for( i = start ; i < end ; ++i ) { buffChunk = (PSW8) AudioFile_CacheAudioChunk( i ); if( buffChunk == NULL ) { continue; } uncompr_length = ADLIB_getLength( buffChunk ); if( uncompr_length <= 1 ) { MM_FREE( buffChunk ); continue; } ADLIB_LoadMusic( buffChunk ); buffWav = MM_MALLOC( uncompr_length * 64 * 2 ); if( buffWav == NULL ) { MM_FREE( buffChunk ); continue; } length = ADLIB_UpdateMusic( uncompr_length, buffWav ); #ifdef BIG_ENDIAN_SYSTEM AudioFile_dataByteSwap( buffWav, length ); #endif // Save audio buffer if( _saveMusicAsWav ) { if( songNames ) { wt_snprintf( filename, sizeof( filename ), "%s%c%s.wav", path, PATH_SEP, songNames[ i - start ] ); } else { wt_snprintf( filename, sizeof( filename ), "%s%c%d.wav", path, PATH_SEP, i - start ); } wav_write( filename, buffWav, length, 1, 44100, 2 ); } else { if( songNames ) { wt_snprintf( filename, sizeof( filename ), "%s%c%s.ogg", path, PATH_SEP, songNames[ i - start ] ); } else { wt_snprintf( filename, sizeof( filename ), "%s%c%d.ogg", path, PATH_SEP, i - start ); } vorbis_encode( filename, buffWav, length, 1, 16, 44100, 0, 0, 0 ); } MM_FREE( buffWav ); MM_FREE( buffChunk ); } ADLIB_Shutdown(); printf( "Done\n" ); return true; }
PRIVATE void CA_SaveMusicChunk( W32 chunk, const char *filename ) { W8 *data, *BuffWav; W32 pos, length, uncompr_length; W32 len; pos = audiostarts[ chunk ]; length = audiostarts[ chunk+1 ] - pos; data = MM_MALLOC( length ); if( data == NULL ) { return; } if( fseek( audiohandle, pos, SEEK_SET ) != 0 ) { printf( "[CA_SaveMusicChunk]: Could not seek!\n" ); MM_FREE( data ); return; } if( fread( data, 1, length, audiohandle ) != length ) { printf( "[CA_SaveMusicChunk]: Read error!\n" ); MM_FREE( data ); return; } uncompr_length = ADLIB_getLength( data ); if( uncompr_length == 1 ) { MM_FREE( data ); return; } ADLIB_LoadMusic( data ); BuffWav = MM_MALLOC( uncompr_length * 64 * 2 ); if( BuffWav == NULL ) { MM_FREE( data ); return; } len = ADLIB_UpdateMusic( uncompr_length, BuffWav ); #if 1 vorbis_encode( filename, BuffWav, len, 1, 16, 44100, 0, 0, 0 ); #else write_wav( filename, BuffWav, len, 1, 44100, 2 ); #endif MM_FREE( BuffWav ); MM_FREE( data ); }
/** * \brief Decode sound fx. * \param[in] start Start of sound fx chunks. * \param[in] end End of sound fx chunks. * \param[in] path Directory path to save file to. * \return On success true, otherwise false. */ PUBLIC wtBoolean AudioFile_ReduxDecodeSound( const W32 start, const W32 end, const char *path ) { SW8 *buffChunk; void *buffWav; W32 i; W32 length; char filename[ 1024 ]; printf( "Decoding Sound FX..." ); if( ! ADLIB_Init( 22050 ) ) { return false; } for( i = start ; i < end ; ++i ) { buffChunk = (PSW8) AudioFile_CacheAudioChunk( i ); if( buffChunk == NULL ) { continue; } buffWav = ADLIB_DecodeSound( (AdLibSound *)buffChunk, &length ); if( buffWav == NULL ) { MM_FREE( buffChunk ); continue; } #ifdef BIG_ENDIAN_SYSTEM AudioFile_dataByteSwap( buffWav, length ); #endif if( _saveAudioAsWav ) { wt_snprintf( filename, sizeof( filename ), "%s%c%.3d.wav", path, PATH_SEP, GetSoundMappedIndex( i - start ) ); wav_write( filename, buffWav, length, 1, 22050, 2 ); } else { wt_snprintf( filename, sizeof( filename ), "%s%c%.3d.ogg", path, PATH_SEP, GetSoundMappedIndex( i - start ) ); vorbis_encode( filename, buffWav, length, 1, 16, 22050, 0, 0, 0 ); } MM_FREE( buffWav ); MM_FREE( buffChunk ); } ADLIB_Shutdown(); printf( "Done\n" ); return true; }