summaryrefslogtreecommitdiff
path: root/indra/llaudio/llvorbisencode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llaudio/llvorbisencode.cpp')
-rw-r--r--indra/llaudio/llvorbisencode.cpp898
1 files changed, 449 insertions, 449 deletions
diff --git a/indra/llaudio/llvorbisencode.cpp b/indra/llaudio/llvorbisencode.cpp
index 2e1ed9b505..573c947764 100644
--- a/indra/llaudio/llvorbisencode.cpp
+++ b/indra/llaudio/llvorbisencode.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file vorbisencode.cpp
* @brief Vorbis encoding routine routine for Indra.
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library 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
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -39,161 +39,161 @@
#if 0
#include "VorbisFramework.h"
-#define vorbis_analysis mac_vorbis_analysis
-#define vorbis_analysis_headerout mac_vorbis_analysis_headerout
-#define vorbis_analysis_init mac_vorbis_analysis_init
-#define vorbis_encode_ctl mac_vorbis_encode_ctl
-#define vorbis_encode_setup_init mac_vorbis_encode_setup_init
-#define vorbis_encode_setup_managed mac_vorbis_encode_setup_managed
-
-#define vorbis_info_init mac_vorbis_info_init
-#define vorbis_info_clear mac_vorbis_info_clear
-#define vorbis_comment_init mac_vorbis_comment_init
-#define vorbis_comment_clear mac_vorbis_comment_clear
-#define vorbis_block_init mac_vorbis_block_init
-#define vorbis_block_clear mac_vorbis_block_clear
-#define vorbis_dsp_clear mac_vorbis_dsp_clear
-#define vorbis_analysis_buffer mac_vorbis_analysis_buffer
-#define vorbis_analysis_wrote mac_vorbis_analysis_wrote
-#define vorbis_analysis_blockout mac_vorbis_analysis_blockout
-
-#define ogg_stream_packetin mac_ogg_stream_packetin
-#define ogg_stream_init mac_ogg_stream_init
-#define ogg_stream_flush mac_ogg_stream_flush
-#define ogg_stream_pageout mac_ogg_stream_pageout
-#define ogg_page_eos mac_ogg_page_eos
-#define ogg_stream_clear mac_ogg_stream_clear
+#define vorbis_analysis mac_vorbis_analysis
+#define vorbis_analysis_headerout mac_vorbis_analysis_headerout
+#define vorbis_analysis_init mac_vorbis_analysis_init
+#define vorbis_encode_ctl mac_vorbis_encode_ctl
+#define vorbis_encode_setup_init mac_vorbis_encode_setup_init
+#define vorbis_encode_setup_managed mac_vorbis_encode_setup_managed
+
+#define vorbis_info_init mac_vorbis_info_init
+#define vorbis_info_clear mac_vorbis_info_clear
+#define vorbis_comment_init mac_vorbis_comment_init
+#define vorbis_comment_clear mac_vorbis_comment_clear
+#define vorbis_block_init mac_vorbis_block_init
+#define vorbis_block_clear mac_vorbis_block_clear
+#define vorbis_dsp_clear mac_vorbis_dsp_clear
+#define vorbis_analysis_buffer mac_vorbis_analysis_buffer
+#define vorbis_analysis_wrote mac_vorbis_analysis_wrote
+#define vorbis_analysis_blockout mac_vorbis_analysis_blockout
+
+#define ogg_stream_packetin mac_ogg_stream_packetin
+#define ogg_stream_init mac_ogg_stream_init
+#define ogg_stream_flush mac_ogg_stream_flush
+#define ogg_stream_pageout mac_ogg_stream_pageout
+#define ogg_page_eos mac_ogg_page_eos
+#define ogg_stream_clear mac_ogg_stream_clear
#endif
S32 check_for_invalid_wav_formats(const std::string& in_fname, std::string& error_msg)
{
- U16 num_channels = 0;
- U32 sample_rate = 0;
- U32 bits_per_sample = 0;
- U32 physical_file_size = 0;
- U32 chunk_length = 0;
- U32 raw_data_length = 0;
- U32 bytes_per_sec = 0;
- BOOL uncompressed_pcm = FALSE;
+ U16 num_channels = 0;
+ U32 sample_rate = 0;
+ U32 bits_per_sample = 0;
+ U32 physical_file_size = 0;
+ U32 chunk_length = 0;
+ U32 raw_data_length = 0;
+ U32 bytes_per_sec = 0;
+ BOOL uncompressed_pcm = FALSE;
- unsigned char wav_header[44]; /*Flawfinder: ignore*/
+ unsigned char wav_header[44]; /*Flawfinder: ignore*/
- error_msg.clear();
+ error_msg.clear();
- //********************************
- LLAPRFile infile ;
+ //********************************
+ LLAPRFile infile ;
infile.open(in_fname,LL_APR_RB);
- //********************************
- if (!infile.getFileHandle())
- {
- error_msg = "CannotUploadSoundFile";
- return(LLVORBISENC_SOURCE_OPEN_ERR);
- }
-
- infile.read(wav_header, 44);
- physical_file_size = infile.seek(APR_END,0);
-
- if (strncmp((char *)&(wav_header[0]),"RIFF",4))
- {
- error_msg = "SoundFileNotRIFF";
- return(LLVORBISENC_WAV_FORMAT_ERR);
- }
-
- if (strncmp((char *)&(wav_header[8]),"WAVE",4))
- {
- error_msg = "SoundFileNotRIFF";
- return(LLVORBISENC_WAV_FORMAT_ERR);
- }
-
- // parse the chunks
-
- U32 file_pos = 12; // start at the first chunk (usually fmt but not always)
-
- while ((file_pos + 8)< physical_file_size)
- {
- infile.seek(APR_SET,file_pos);
- infile.read(wav_header, 44);
-
- chunk_length = ((U32) wav_header[7] << 24)
- + ((U32) wav_header[6] << 16)
- + ((U32) wav_header[5] << 8)
- + wav_header[4];
-
- if (chunk_length > physical_file_size - file_pos - 4)
- {
- infile.close();
- error_msg = "SoundFileInvalidChunkSize";
- return(LLVORBISENC_CHUNK_SIZE_ERR);
- }
-
-// LL_INFOS() << "chunk found: '" << wav_header[0] << wav_header[1] << wav_header[2] << wav_header[3] << "'" << LL_ENDL;
-
- if (!(strncmp((char *)&(wav_header[0]),"fmt ",4)))
- {
- if ((wav_header[8] == 0x01) && (wav_header[9] == 0x00))
- {
- uncompressed_pcm = TRUE;
- }
- num_channels = ((U16) wav_header[11] << 8) + wav_header[10];
- sample_rate = ((U32) wav_header[15] << 24)
- + ((U32) wav_header[14] << 16)
- + ((U32) wav_header[13] << 8)
- + wav_header[12];
- bits_per_sample = ((U16) wav_header[23] << 8) + wav_header[22];
- bytes_per_sec = ((U32) wav_header[19] << 24)
- + ((U32) wav_header[18] << 16)
- + ((U32) wav_header[17] << 8)
- + wav_header[16];
- }
- else if (!(strncmp((char *)&(wav_header[0]),"data",4)))
- {
- raw_data_length = chunk_length;
- }
- file_pos += (chunk_length + 8);
- chunk_length = 0;
- }
- //****************
- infile.close();
- //****************
-
- if (!uncompressed_pcm)
- {
- error_msg = "SoundFileNotPCM";
- return(LLVORBISENC_PCM_FORMAT_ERR);
- }
-
- if ((num_channels < 1) || (num_channels > LLVORBIS_CLIP_MAX_CHANNELS))
- {
- error_msg = "SoundFileInvalidChannelCount";
- return(LLVORBISENC_MULTICHANNEL_ERR);
- }
-
- if (sample_rate != LLVORBIS_CLIP_SAMPLE_RATE)
- {
- error_msg = "SoundFileInvalidSampleRate";
- return(LLVORBISENC_UNSUPPORTED_SAMPLE_RATE);
- }
-
- if ((bits_per_sample != 16) && (bits_per_sample != 8))
- {
- error_msg = "SoundFileInvalidWordSize";
- return(LLVORBISENC_UNSUPPORTED_WORD_SIZE);
- }
-
- if (!raw_data_length)
- {
- error_msg = "SoundFileInvalidHeader";
- return(LLVORBISENC_CLIP_TOO_LONG);
- }
-
- F32 clip_length = (F32)raw_data_length/(F32)bytes_per_sec;
-
- if (clip_length > LLVORBIS_CLIP_MAX_TIME)
- {
- error_msg = "SoundFileInvalidTooLong";
- return(LLVORBISENC_CLIP_TOO_LONG);
- }
+ //********************************
+ if (!infile.getFileHandle())
+ {
+ error_msg = "CannotUploadSoundFile";
+ return(LLVORBISENC_SOURCE_OPEN_ERR);
+ }
+
+ infile.read(wav_header, 44);
+ physical_file_size = infile.seek(APR_END,0);
+
+ if (strncmp((char *)&(wav_header[0]),"RIFF",4))
+ {
+ error_msg = "SoundFileNotRIFF";
+ return(LLVORBISENC_WAV_FORMAT_ERR);
+ }
+
+ if (strncmp((char *)&(wav_header[8]),"WAVE",4))
+ {
+ error_msg = "SoundFileNotRIFF";
+ return(LLVORBISENC_WAV_FORMAT_ERR);
+ }
+
+ // parse the chunks
+
+ U32 file_pos = 12; // start at the first chunk (usually fmt but not always)
+
+ while ((file_pos + 8)< physical_file_size)
+ {
+ infile.seek(APR_SET,file_pos);
+ infile.read(wav_header, 44);
+
+ chunk_length = ((U32) wav_header[7] << 24)
+ + ((U32) wav_header[6] << 16)
+ + ((U32) wav_header[5] << 8)
+ + wav_header[4];
+
+ if (chunk_length > physical_file_size - file_pos - 4)
+ {
+ infile.close();
+ error_msg = "SoundFileInvalidChunkSize";
+ return(LLVORBISENC_CHUNK_SIZE_ERR);
+ }
+
+// LL_INFOS() << "chunk found: '" << wav_header[0] << wav_header[1] << wav_header[2] << wav_header[3] << "'" << LL_ENDL;
+
+ if (!(strncmp((char *)&(wav_header[0]),"fmt ",4)))
+ {
+ if ((wav_header[8] == 0x01) && (wav_header[9] == 0x00))
+ {
+ uncompressed_pcm = TRUE;
+ }
+ num_channels = ((U16) wav_header[11] << 8) + wav_header[10];
+ sample_rate = ((U32) wav_header[15] << 24)
+ + ((U32) wav_header[14] << 16)
+ + ((U32) wav_header[13] << 8)
+ + wav_header[12];
+ bits_per_sample = ((U16) wav_header[23] << 8) + wav_header[22];
+ bytes_per_sec = ((U32) wav_header[19] << 24)
+ + ((U32) wav_header[18] << 16)
+ + ((U32) wav_header[17] << 8)
+ + wav_header[16];
+ }
+ else if (!(strncmp((char *)&(wav_header[0]),"data",4)))
+ {
+ raw_data_length = chunk_length;
+ }
+ file_pos += (chunk_length + 8);
+ chunk_length = 0;
+ }
+ //****************
+ infile.close();
+ //****************
+
+ if (!uncompressed_pcm)
+ {
+ error_msg = "SoundFileNotPCM";
+ return(LLVORBISENC_PCM_FORMAT_ERR);
+ }
+
+ if ((num_channels < 1) || (num_channels > LLVORBIS_CLIP_MAX_CHANNELS))
+ {
+ error_msg = "SoundFileInvalidChannelCount";
+ return(LLVORBISENC_MULTICHANNEL_ERR);
+ }
+
+ if (sample_rate != LLVORBIS_CLIP_SAMPLE_RATE)
+ {
+ error_msg = "SoundFileInvalidSampleRate";
+ return(LLVORBISENC_UNSUPPORTED_SAMPLE_RATE);
+ }
+
+ if ((bits_per_sample != 16) && (bits_per_sample != 8))
+ {
+ error_msg = "SoundFileInvalidWordSize";
+ return(LLVORBISENC_UNSUPPORTED_WORD_SIZE);
+ }
+
+ if (!raw_data_length)
+ {
+ error_msg = "SoundFileInvalidHeader";
+ return(LLVORBISENC_CLIP_TOO_LONG);
+ }
+
+ F32 clip_length = (F32)raw_data_length/(F32)bytes_per_sec;
+
+ if (clip_length > LLVORBIS_CLIP_MAX_TIME)
+ {
+ error_msg = "SoundFileInvalidTooLong";
+ return(LLVORBISENC_CLIP_TOO_LONG);
+ }
return(LLVORBISENC_NOERR);
}
@@ -201,306 +201,306 @@ S32 check_for_invalid_wav_formats(const std::string& in_fname, std::string& erro
S32 encode_vorbis_file(const std::string& in_fname, const std::string& out_fname)
{
#define READ_BUFFER 1024
- unsigned char readbuffer[READ_BUFFER*4+44]; /* out of the data segment, not the stack */ /*Flawfinder: ignore*/
-
- ogg_stream_state os; /* take physical pages, weld into a logical stream of packets */
- ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */
- ogg_packet op; /* one raw packet of data for decode */
-
- vorbis_info vi; /* struct that stores all the static vorbis bitstream settings */
- vorbis_comment vc; /* struct that stores all the user comments */
-
- vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
- vorbis_block vb; /* local working space for packet->PCM decode */
-
- int eos=0;
- int result;
-
- U16 num_channels = 0;
- U32 sample_rate = 0;
- U32 bits_per_sample = 0;
-
- S32 format_error = 0;
- std::string error_msg;
- if ((format_error = check_for_invalid_wav_formats(in_fname, error_msg)))
- {
- LL_WARNS() << error_msg << ": " << in_fname << LL_ENDL;
- return(format_error);
- }
+ unsigned char readbuffer[READ_BUFFER*4+44]; /* out of the data segment, not the stack */ /*Flawfinder: ignore*/
+
+ ogg_stream_state os; /* take physical pages, weld into a logical stream of packets */
+ ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */
+ ogg_packet op; /* one raw packet of data for decode */
+
+ vorbis_info vi; /* struct that stores all the static vorbis bitstream settings */
+ vorbis_comment vc; /* struct that stores all the user comments */
+
+ vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
+ vorbis_block vb; /* local working space for packet->PCM decode */
+
+ int eos=0;
+ int result;
+
+ U16 num_channels = 0;
+ U32 sample_rate = 0;
+ U32 bits_per_sample = 0;
+
+ S32 format_error = 0;
+ std::string error_msg;
+ if ((format_error = check_for_invalid_wav_formats(in_fname, error_msg)))
+ {
+ LL_WARNS() << error_msg << ": " << in_fname << LL_ENDL;
+ return(format_error);
+ }
#if 1
- unsigned char wav_header[44]; /*Flawfinder: ignore*/
-
- S32 data_left = 0;
-
- LLAPRFile infile ;
- infile.open(in_fname,LL_APR_RB);
- if (!infile.getFileHandle())
- {
- LL_WARNS() << "Couldn't open temporary ogg file for writing: " << in_fname
- << LL_ENDL;
- return(LLVORBISENC_SOURCE_OPEN_ERR);
- }
-
- LLAPRFile outfile ;
- outfile.open(out_fname,LL_APR_WPB);
- if (!outfile.getFileHandle())
- {
- LL_WARNS() << "Couldn't open upload sound file for reading: " << in_fname
- << LL_ENDL;
- return(LLVORBISENC_DEST_OPEN_ERR);
- }
-
- // parse the chunks
- U32 chunk_length = 0;
- U32 file_pos = 12; // start at the first chunk (usually fmt but not always)
-
- while (infile.eof() != APR_EOF)
- {
- infile.seek(APR_SET,file_pos);
- infile.read(wav_header, 44);
-
- chunk_length = ((U32) wav_header[7] << 24)
- + ((U32) wav_header[6] << 16)
- + ((U32) wav_header[5] << 8)
- + wav_header[4];
-
-// LL_INFOS() << "chunk found: '" << wav_header[0] << wav_header[1] << wav_header[2] << wav_header[3] << "'" << LL_ENDL;
-
- if (!(strncmp((char *)&(wav_header[0]),"fmt ",4)))
- {
- num_channels = ((U16) wav_header[11] << 8) + wav_header[10];
- sample_rate = ((U32) wav_header[15] << 24)
- + ((U32) wav_header[14] << 16)
- + ((U32) wav_header[13] << 8)
- + wav_header[12];
- bits_per_sample = ((U16) wav_header[23] << 8) + wav_header[22];
- }
- else if (!(strncmp((char *)&(wav_header[0]),"data",4)))
- {
- infile.seek(APR_SET,file_pos+8);
- // leave the file pointer at the beginning of the data chunk data
- data_left = chunk_length;
- break;
- }
- file_pos += (chunk_length + 8);
- chunk_length = 0;
- }
-
-
- /********** Encode setup ************/
-
- /* choose an encoding mode */
- /* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */
- vorbis_info_init(&vi);
-
- // always encode to mono
-
- // SL-52913 & SL-53779 determined this quality level to be our 'good
- // enough' general-purpose quality level with a nice low bitrate.
- // Equivalent to oggenc -q0.5
- F32 quality = 0.05f;
-// quality = (bitrate==128000 ? 0.4f : 0.1);
-
-// if (vorbis_encode_init(&vi, /* num_channels */ 1 ,sample_rate, -1, bitrate, -1))
- if (vorbis_encode_init_vbr(&vi, /* num_channels */ 1 ,sample_rate, quality))
-// if (vorbis_encode_setup_managed(&vi,1,sample_rate,-1,bitrate,-1) ||
-// vorbis_encode_ctl(&vi,OV_ECTL_RATEMANAGE_AVG,NULL) ||
-// vorbis_encode_setup_init(&vi))
- {
- LL_WARNS() << "unable to initialize vorbis codec at quality " << quality << LL_ENDL;
- // LL_WARNS() << "unable to initialize vorbis codec at bitrate " << bitrate << LL_ENDL;
- return(LLVORBISENC_DEST_OPEN_ERR);
- }
-
- /* add a comment */
- vorbis_comment_init(&vc);
-// vorbis_comment_add(&vc,"Linden");
-
- /* set up the analysis state and auxiliary encoding storage */
- vorbis_analysis_init(&vd,&vi);
- vorbis_block_init(&vd,&vb);
-
- /* set up our packet->stream encoder */
- /* pick a random serial number; that way we can more likely build
- chained streams just by concatenation */
- ogg_stream_init(&os, ll_rand());
-
- /* Vorbis streams begin with three headers; the initial header (with
- most of the codec setup parameters) which is mandated by the Ogg
- bitstream spec. The second header holds any comment fields. The
- third header holds the bitstream codebook. We merely need to
- make the headers, then pass them to libvorbis one at a time;
- libvorbis handles the additional Ogg bitstream constraints */
-
- {
- ogg_packet header;
- ogg_packet header_comm;
- ogg_packet header_code;
-
- vorbis_analysis_headerout(&vd,&vc,&header,&header_comm,&header_code);
- ogg_stream_packetin(&os,&header); /* automatically placed in its own
- page */
- ogg_stream_packetin(&os,&header_comm);
- ogg_stream_packetin(&os,&header_code);
-
- /* We don't have to write out here, but doing so makes streaming
- * much easier, so we do, flushing ALL pages. This ensures the actual
- * audio data will start on a new page
- */
- while(!eos){
- int result=ogg_stream_flush(&os,&og);
- if(result==0)break;
- outfile.write(og.header, og.header_len);
- outfile.write(og.body, og.body_len);
- }
-
- }
-
-
- while(!eos)
- {
- long bytes_per_sample = bits_per_sample/8;
-
- long bytes=(long)infile.read(readbuffer,llclamp((S32)(READ_BUFFER*num_channels*bytes_per_sample),0,data_left)); /* stereo hardwired here */
-
- if (bytes==0)
- {
- /* end of file. this can be done implicitly in the mainline,
- but it's easier to see here in non-clever fashion.
- Tell the library we're at end of stream so that it can handle
- the last frame and mark end of stream in the output properly */
-
- vorbis_analysis_wrote(&vd,0);
-// eos = 1;
-
- }
- else
- {
- long i;
- long samples;
- int temp;
-
- data_left -= bytes;
+ unsigned char wav_header[44]; /*Flawfinder: ignore*/
+
+ S32 data_left = 0;
+
+ LLAPRFile infile ;
+ infile.open(in_fname,LL_APR_RB);
+ if (!infile.getFileHandle())
+ {
+ LL_WARNS() << "Couldn't open temporary ogg file for writing: " << in_fname
+ << LL_ENDL;
+ return(LLVORBISENC_SOURCE_OPEN_ERR);
+ }
+
+ LLAPRFile outfile ;
+ outfile.open(out_fname,LL_APR_WPB);
+ if (!outfile.getFileHandle())
+ {
+ LL_WARNS() << "Couldn't open upload sound file for reading: " << in_fname
+ << LL_ENDL;
+ return(LLVORBISENC_DEST_OPEN_ERR);
+ }
+
+ // parse the chunks
+ U32 chunk_length = 0;
+ U32 file_pos = 12; // start at the first chunk (usually fmt but not always)
+
+ while (infile.eof() != APR_EOF)
+ {
+ infile.seek(APR_SET,file_pos);
+ infile.read(wav_header, 44);
+
+ chunk_length = ((U32) wav_header[7] << 24)
+ + ((U32) wav_header[6] << 16)
+ + ((U32) wav_header[5] << 8)
+ + wav_header[4];
+
+// LL_INFOS() << "chunk found: '" << wav_header[0] << wav_header[1] << wav_header[2] << wav_header[3] << "'" << LL_ENDL;
+
+ if (!(strncmp((char *)&(wav_header[0]),"fmt ",4)))
+ {
+ num_channels = ((U16) wav_header[11] << 8) + wav_header[10];
+ sample_rate = ((U32) wav_header[15] << 24)
+ + ((U32) wav_header[14] << 16)
+ + ((U32) wav_header[13] << 8)
+ + wav_header[12];
+ bits_per_sample = ((U16) wav_header[23] << 8) + wav_header[22];
+ }
+ else if (!(strncmp((char *)&(wav_header[0]),"data",4)))
+ {
+ infile.seek(APR_SET,file_pos+8);
+ // leave the file pointer at the beginning of the data chunk data
+ data_left = chunk_length;
+ break;
+ }
+ file_pos += (chunk_length + 8);
+ chunk_length = 0;
+ }
+
+
+ /********** Encode setup ************/
+
+ /* choose an encoding mode */
+ /* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */
+ vorbis_info_init(&vi);
+
+ // always encode to mono
+
+ // SL-52913 & SL-53779 determined this quality level to be our 'good
+ // enough' general-purpose quality level with a nice low bitrate.
+ // Equivalent to oggenc -q0.5
+ F32 quality = 0.05f;
+// quality = (bitrate==128000 ? 0.4f : 0.1);
+
+// if (vorbis_encode_init(&vi, /* num_channels */ 1 ,sample_rate, -1, bitrate, -1))
+ if (vorbis_encode_init_vbr(&vi, /* num_channels */ 1 ,sample_rate, quality))
+// if (vorbis_encode_setup_managed(&vi,1,sample_rate,-1,bitrate,-1) ||
+// vorbis_encode_ctl(&vi,OV_ECTL_RATEMANAGE_AVG,NULL) ||
+// vorbis_encode_setup_init(&vi))
+ {
+ LL_WARNS() << "unable to initialize vorbis codec at quality " << quality << LL_ENDL;
+ // LL_WARNS() << "unable to initialize vorbis codec at bitrate " << bitrate << LL_ENDL;
+ return(LLVORBISENC_DEST_OPEN_ERR);
+ }
+
+ /* add a comment */
+ vorbis_comment_init(&vc);
+// vorbis_comment_add(&vc,"Linden");
+
+ /* set up the analysis state and auxiliary encoding storage */
+ vorbis_analysis_init(&vd,&vi);
+ vorbis_block_init(&vd,&vb);
+
+ /* set up our packet->stream encoder */
+ /* pick a random serial number; that way we can more likely build
+ chained streams just by concatenation */
+ ogg_stream_init(&os, ll_rand());
+
+ /* Vorbis streams begin with three headers; the initial header (with
+ most of the codec setup parameters) which is mandated by the Ogg
+ bitstream spec. The second header holds any comment fields. The
+ third header holds the bitstream codebook. We merely need to
+ make the headers, then pass them to libvorbis one at a time;
+ libvorbis handles the additional Ogg bitstream constraints */
+
+ {
+ ogg_packet header;
+ ogg_packet header_comm;
+ ogg_packet header_code;
+
+ vorbis_analysis_headerout(&vd,&vc,&header,&header_comm,&header_code);
+ ogg_stream_packetin(&os,&header); /* automatically placed in its own
+ page */
+ ogg_stream_packetin(&os,&header_comm);
+ ogg_stream_packetin(&os,&header_code);
+
+ /* We don't have to write out here, but doing so makes streaming
+ * much easier, so we do, flushing ALL pages. This ensures the actual
+ * audio data will start on a new page
+ */
+ while(!eos){
+ int result=ogg_stream_flush(&os,&og);
+ if(result==0)break;
+ outfile.write(og.header, og.header_len);
+ outfile.write(og.body, og.body_len);
+ }
+
+ }
+
+
+ while(!eos)
+ {
+ long bytes_per_sample = bits_per_sample/8;
+
+ long bytes=(long)infile.read(readbuffer,llclamp((S32)(READ_BUFFER*num_channels*bytes_per_sample),0,data_left)); /* stereo hardwired here */
+
+ if (bytes==0)
+ {
+ /* end of file. this can be done implicitly in the mainline,
+ but it's easier to see here in non-clever fashion.
+ Tell the library we're at end of stream so that it can handle
+ the last frame and mark end of stream in the output properly */
+
+ vorbis_analysis_wrote(&vd,0);
+// eos = 1;
+
+ }
+ else
+ {
+ long i;
+ long samples;
+ int temp;
+
+ data_left -= bytes;
/* data to encode */
-
- /* expose the buffer to submit data */
- float **buffer=vorbis_analysis_buffer(&vd,READ_BUFFER);
-
- i = 0;
- samples = bytes / (num_channels * bytes_per_sample);
-
- if (num_channels == 2)
- {
- if (bytes_per_sample == 2)
- {
- /* uninterleave samples */
- for(i=0; i<samples ;i++)
- {
- temp = ((signed char *)readbuffer)[i*4+1]; /*Flawfinder: ignore*/
- temp += ((signed char *)readbuffer)[i*4+3]; /*Flawfinder: ignore*/
- temp <<= 8;
- temp += readbuffer[i*4];
- temp += readbuffer[i*4+2];
-
- buffer[0][i] = ((float)temp) / 65536.f;
- }
- }
- else // presume it's 1 byte per which is unsigned (F#@%ing wav "standard")
- {
- /* uninterleave samples */
- for(i=0; i<samples ;i++)
- {
- temp = readbuffer[i*2+0];
- temp += readbuffer[i*2+1];
- temp -= 256;
- buffer[0][i] = ((float)temp) / 256.f;
- }
- }
- }
- else if (num_channels == 1)
- {
- if (bytes_per_sample == 2)
- {
- for(i=0; i < samples ;i++)
- {
- temp = ((signed char*)readbuffer)[i*2+1];
- temp <<= 8;
- temp += readbuffer[i*2];
- buffer[0][i] = ((float)temp) / 32768.f;
- }
- }
- else // presume it's 1 byte per which is unsigned (F#@%ing wav "standard")
- {
- for(i=0; i < samples ;i++)
- {
- temp = readbuffer[i];
- temp -= 128;
- buffer[0][i] = ((float)temp) / 128.f;
- }
- }
- }
-
- /* tell the library how much we actually submitted */
- vorbis_analysis_wrote(&vd,i);
- }
-
- /* vorbis does some data preanalysis, then divvies up blocks for
- more involved (potentially parallel) processing. Get a single
- block for encoding now */
- while(vorbis_analysis_blockout(&vd,&vb)==1)
- {
-
- /* analysis */
- /* Do the main analysis, creating a packet */
- vorbis_analysis(&vb, NULL);
- vorbis_bitrate_addblock(&vb);
-
- while(vorbis_bitrate_flushpacket(&vd, &op))
- {
-
- /* weld the packet into the bitstream */
- ogg_stream_packetin(&os,&op);
-
- /* write out pages (if any) */
- while(!eos)
- {
- result = ogg_stream_pageout(&os,&og);
-
- if(result==0)
- break;
-
- outfile.write(og.header, og.header_len);
- outfile.write(og.body, og.body_len);
-
- /* this could be set above, but for illustrative purposes, I do
- it here (to show that vorbis does know where the stream ends) */
-
- if(ogg_page_eos(&og))
- eos=1;
-
- }
- }
- }
- }
-
-
-
- /* clean up and exit. vorbis_info_clear() must be called last */
-
- ogg_stream_clear(&os);
- vorbis_block_clear(&vb);
- vorbis_dsp_clear(&vd);
- vorbis_comment_clear(&vc);
- vorbis_info_clear(&vi);
-
- /* ogg_page and ogg_packet structs always point to storage in
- libvorbis. They're never freed or manipulated directly */
-
-// fprintf(stderr,"Vorbis encoding: Done.\n");
- LL_INFOS() << "Vorbis encoding: Done." << LL_ENDL;
-
+
+ /* expose the buffer to submit data */
+ float **buffer=vorbis_analysis_buffer(&vd,READ_BUFFER);
+
+ i = 0;
+ samples = bytes / (num_channels * bytes_per_sample);
+
+ if (num_channels == 2)
+ {
+ if (bytes_per_sample == 2)
+ {
+ /* uninterleave samples */
+ for(i=0; i<samples ;i++)
+ {
+ temp = ((signed char *)readbuffer)[i*4+1]; /*Flawfinder: ignore*/
+ temp += ((signed char *)readbuffer)[i*4+3]; /*Flawfinder: ignore*/
+ temp <<= 8;
+ temp += readbuffer[i*4];
+ temp += readbuffer[i*4+2];
+
+ buffer[0][i] = ((float)temp) / 65536.f;
+ }
+ }
+ else // presume it's 1 byte per which is unsigned (F#@%ing wav "standard")
+ {
+ /* uninterleave samples */
+ for(i=0; i<samples ;i++)
+ {
+ temp = readbuffer[i*2+0];
+ temp += readbuffer[i*2+1];
+ temp -= 256;
+ buffer[0][i] = ((float)temp) / 256.f;
+ }
+ }
+ }
+ else if (num_channels == 1)
+ {
+ if (bytes_per_sample == 2)
+ {
+ for(i=0; i < samples ;i++)
+ {
+ temp = ((signed char*)readbuffer)[i*2+1];
+ temp <<= 8;
+ temp += readbuffer[i*2];
+ buffer[0][i] = ((float)temp) / 32768.f;
+ }
+ }
+ else // presume it's 1 byte per which is unsigned (F#@%ing wav "standard")
+ {
+ for(i=0; i < samples ;i++)
+ {
+ temp = readbuffer[i];
+ temp -= 128;
+ buffer[0][i] = ((float)temp) / 128.f;
+ }
+ }
+ }
+
+ /* tell the library how much we actually submitted */
+ vorbis_analysis_wrote(&vd,i);
+ }
+
+ /* vorbis does some data preanalysis, then divvies up blocks for
+ more involved (potentially parallel) processing. Get a single
+ block for encoding now */
+ while(vorbis_analysis_blockout(&vd,&vb)==1)
+ {
+
+ /* analysis */
+ /* Do the main analysis, creating a packet */
+ vorbis_analysis(&vb, NULL);
+ vorbis_bitrate_addblock(&vb);
+
+ while(vorbis_bitrate_flushpacket(&vd, &op))
+ {
+
+ /* weld the packet into the bitstream */
+ ogg_stream_packetin(&os,&op);
+
+ /* write out pages (if any) */
+ while(!eos)
+ {
+ result = ogg_stream_pageout(&os,&og);
+
+ if(result==0)
+ break;
+
+ outfile.write(og.header, og.header_len);
+ outfile.write(og.body, og.body_len);
+
+ /* this could be set above, but for illustrative purposes, I do
+ it here (to show that vorbis does know where the stream ends) */
+
+ if(ogg_page_eos(&og))
+ eos=1;
+
+ }
+ }
+ }
+ }
+
+
+
+ /* clean up and exit. vorbis_info_clear() must be called last */
+
+ ogg_stream_clear(&os);
+ vorbis_block_clear(&vb);
+ vorbis_dsp_clear(&vd);
+ vorbis_comment_clear(&vc);
+ vorbis_info_clear(&vi);
+
+ /* ogg_page and ogg_packet structs always point to storage in
+ libvorbis. They're never freed or manipulated directly */
+
+// fprintf(stderr,"Vorbis encoding: Done.\n");
+ LL_INFOS() << "Vorbis encoding: Done." << LL_ENDL;
+
#endif
- return(LLVORBISENC_NOERR);
-
+ return(LLVORBISENC_NOERR);
+
}