Commit a0aabefa authored by giles's avatar giles
Browse files

Recommit changes lost in server migration.

Original commit (r6809) 2004-06-04 00:54:26 -0400 (Fri, 04 Jun 2004) by jm.

Think I've got gapless working properly now. Also, started implementing
the speex_lib_ctl() interface and simplified speex_bits_advance (patch
by Alfr?\195?\169do Moreira)


git-svn-id: http://svn.xiph.org/trunk/speex@6809 0101bb08-14d6-0310-b084-bc0e0c8e3800
parent 844c3e72
......@@ -324,24 +324,12 @@ int speex_bits_peek(SpeexBits *bits)
void speex_bits_advance(SpeexBits *bits, int n)
{
int nbytes, nbits;
if ((bits->bytePtr<<3)+bits->bitPtr+n>bits->nbBits)
if (((bits->bytePtr<<3)+bits->bitPtr+n>bits->nbBits) || bits->overflow){
bits->overflow=1;
if (bits->overflow)
return;
nbytes = n >> 3;
nbits = n & 7;
bits->bytePtr += nbytes;
bits->bitPtr += nbits;
if (bits->bitPtr>7)
{
bits->bitPtr-=8;
bits->bytePtr++;
}
}
bits->bytePtr += (bits->bitPtr+n) >> 3; /*divide by 8*/
bits->bitPtr = (bits->bitPtr+n) & 7; /* modulo by 8*/
}
int speex_bits_remaining(SpeexBits *bits)
......
......@@ -877,3 +877,29 @@ int speex_mode_query(const SpeexMode *mode, int request, void *ptr)
{
return mode->query(mode->mode, request, ptr);
}
int speex_lib_ctl(int request, void *ptr)
{
switch (request)
{
case SPEEX_LIB_GET_MAJOR_VERSION:
break;
case SPEEX_LIB_GET_MINOR_VERSION:
break;
case SPEEX_LIB_GET_MICRO_VERSION:
break;
case SPEEX_LIB_GET_EXTRA_VERSION:
break;
case SPEEX_LIB_GET_VERSION_STRING:
break;
case SPEEX_LIB_SET_ALLOC_FUNC:
break;
case SPEEX_LIB_GET_ALLOC_FUNC:
break;
case SPEEX_LIB_SET_FREE_FUNC:
break;
case SPEEX_LIB_GET_FREE_FUNC:
break;
}
return -1;
}
......@@ -1795,6 +1795,9 @@ int nb_encoder_ctl(void *state, int request, void *ptr)
case SPEEX_GET_SUBMODE_ENCODING:
(*(int*)ptr) = st->encode_submode;
break;
case SPEEX_GET_LOOKAHEAD:
(*(int*)ptr)=(st->windowSize-st->frameSize);
break;
case SPEEX_GET_PI_GAIN:
{
int i;
......
......@@ -1278,6 +1278,10 @@ int sb_encoder_ctl(void *state, int request, void *ptr)
case SPEEX_GET_SUBMODE_ENCODING:
(*(int*)ptr) = st->encode_submode;
break;
case SPEEX_GET_LOOKAHEAD:
speex_encoder_ctl(st->st_low, SPEEX_GET_LOOKAHEAD, ptr);
(*(int*)ptr) = 2*(*(int*)ptr) + QMF_ORDER - 1;
break;
case SPEEX_GET_PI_GAIN:
{
int i;
......
......@@ -131,6 +131,10 @@ extern "C" {
/** */
#define SPEEX_GET_SUBMODE_ENCODING 37
/*#define SPEEX_SET_SUBMODE_ENCODING 38*/
/** */
#define SPEEX_GET_LOOKAHEAD 39
/* Used internally, not to be used in applications */
/** Used internally*/
......@@ -150,6 +154,8 @@ extern "C" {
#define SPEEX_GET_PF 1
/* Values allowed for mode queries */
/** Query the frame size of a mode */
#define SPEEX_MODE_FRAME_SIZE 0
......@@ -158,6 +164,24 @@ extern "C" {
#define SPEEX_SUBMODE_BITS_PER_FRAME 1
#define SPEEX_LIB_GET_MAJOR_VERSION 1
#define SPEEX_LIB_GET_MINOR_VERSION 3
#define SPEEX_LIB_GET_MICRO_VERSION 5
#define SPEEX_LIB_GET_EXTRA_VERSION 7
#define SPEEX_LIB_GET_VERSION_STRING 9
#define SPEEX_LIB_SET_ALLOC_FUNC 10
#define SPEEX_LIB_GET_ALLOC_FUNC 11
#define SPEEX_LIB_SET_FREE_FUNC 12
#define SPEEX_LIB_GET_FREE_FUNC 13
#define SPEEX_LIB_SET_WARNING_FUNC 14
#define SPEEX_LIB_GET_WARNING_FUNC 15
#define SPEEX_LIB_SET_ERROR_FUNC 16
#define SPEEX_LIB_GET_ERROR_FUNC 17
/** Number of defined modes in Speex */
#define SPEEX_NB_MODES 3
......@@ -333,6 +357,11 @@ int speex_decoder_ctl(void *state, int request, void *ptr);
*/
int speex_mode_query(const SpeexMode *mode, int request, void *ptr);
/** Functions for controlling the behavior of libspeex
* @param request ioctl-type request (one of the SPEEX_LIB_* macros)
* @param ptr Data exchanged to-from function
*/
int speex_lib_ctl(int request, void *ptr);
/** Default narrowband mode */
extern const SpeexMode speex_nb_mode;
......
......@@ -410,6 +410,8 @@ int main(int argc, char **argv)
int packet_count=0;
int stream_init = 0;
int quiet = 0;
ogg_int64_t page_granule=0, last_granule=0;
int skip_samples=0, page_nb_packets;
struct option long_options[] =
{
{"help", no_argument, NULL, 0},
......@@ -581,13 +583,30 @@ int main(int argc, char **argv)
/*Loop for all complete pages we got (most likely only one)*/
while (ogg_sync_pageout(&oy, &og)==1)
{
int packet_no;
if (stream_init == 0) {
ogg_stream_init(&os, ogg_page_serialno(&og));
stream_init = 1;
}
/*Add page to the bitstream*/
ogg_stream_pagein(&os, &og);
page_granule = ogg_page_granulepos(&og);
page_nb_packets = ogg_page_packets(&og);
if (page_granule>0 && frame_size)
{
skip_samples = page_nb_packets*frame_size*nframes - (page_granule-last_granule);
if (ogg_page_eos(&og))
skip_samples = -skip_samples;
/*else if (!ogg_page_bos(&og))
skip_samples = 0;*/
} else
{
skip_samples = 0;
}
/*printf ("page granulepos: %d %d %d\n", skip_samples, page_nb_packets, (int)page_granule);*/
last_granule = page_granule;
/*Extract all available packets*/
packet_no=0;
while (!eos && ogg_stream_packetout(&os, &op)==1)
{
/*If first packet, process as Speex header*/
......@@ -608,7 +627,7 @@ int main(int argc, char **argv)
{
/* Ignore extra headers */
} else {
packet_no++;
int lost=0;
if (loss_percent>0 && 100*((float)rand())/RAND_MAX<loss_percent)
lost=1;
......@@ -662,14 +681,38 @@ int main(int argc, char **argv)
for (i=0;i<frame_size*channels;i++)
out[i]=output[i];
}
{
int frame_offset = 0;
int new_frame_size = frame_size;
/*printf ("packet %d %d\n", packet_no, skip_samples);*/
if (packet_no == 1 && j==0 && skip_samples > 0)
{
/*printf ("chopping first packet\n");*/
new_frame_size -= skip_samples;
frame_offset = skip_samples;
}
if (packet_no == page_nb_packets && skip_samples < 0)
{
int packet_length = nframes*frame_size+skip_samples;
new_frame_size = packet_length - j*frame_size;
if (new_frame_size<0)
new_frame_size = 0;
if (new_frame_size>frame_size)
new_frame_size = frame_size;
/*printf ("chopping end: %d %d %d\n", new_frame_size, packet_length, packet_no);*/
}
if (new_frame_size)
{
#if defined WIN32 || defined _WIN32
if (strlen(outFile)==0)
WIN_Play_Samples (out, sizeof(short) * frame_size*channels);
else
if (strlen(outFile)==0)
WIN_Play_Samples (out+frame_offset*channels, sizeof(short) * new_frame_size*channels);
else
#endif
fwrite(out, sizeof(short), frame_size*channels, fout);
fwrite(out+frame_offset*channels, sizeof(short), new_frame_size*channels, fout);
audio_size+=sizeof(short)*frame_size*channels;
audio_size+=sizeof(short)*new_frame_size*channels;
}
}
}
}
packet_count++;
......
......@@ -103,7 +103,7 @@ static int read_samples(FILE *fin,int frame_size, int bits, int channels, int ls
/*fprintf (stderr, "%d\n", nb_read);*/
if (nb_read==0)
return 1;
return 0;
s=(short*)in;
if(bits==8)
......@@ -138,7 +138,7 @@ static int read_samples(FILE *fin,int frame_size, int bits, int channels, int ls
}
return 0;
return nb_read;
}
void version()
......@@ -206,6 +206,7 @@ void usage()
int main(int argc, char **argv)
{
int nb_samples, total_samples=0, nb_encoded;
int c;
int option_index = 0;
char *inFile, *outFile;
......@@ -279,7 +280,8 @@ int main(int argc, char **argv)
int tmp;
SpeexPreprocessState *preprocess = NULL;
int denoise_enabled=0, agc_enabled=0;
int lookahead = 0;
comment_init(&comments, &comments_length, vendor_string);
/*Process command-line options*/
......@@ -561,42 +563,6 @@ int main(int argc, char **argv)
close_out=1;
}
/*Write header*/
{
op.packet = (unsigned char *)speex_header_to_packet(&header, (int*)&(op.bytes));
op.b_o_s = 1;
op.e_o_s = 0;
op.granulepos = 0;
op.packetno = 0;
ogg_stream_packetin(&os, &op);
free(op.packet);
op.packet = (unsigned char *)comments;
op.bytes = comments_length;
op.b_o_s = 0;
op.e_o_s = 0;
op.granulepos = 0;
op.packetno = 1;
ogg_stream_packetin(&os, &op);
while((result = ogg_stream_flush(&os, &og)))
{
if(!result) break;
ret = oe_write_page(&og, fout);
if(ret != og.header_len + og.body_len)
{
fprintf (stderr,"Error: failed writing header to output stream\n");
exit(1);
}
else
bytes_written += ret;
}
}
free(comments);
speex_encoder_ctl(st, SPEEX_GET_FRAME_SIZE, &frame_size);
speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &complexity);
speex_encoder_ctl(st, SPEEX_SET_SAMPLING_RATE, &rate);
......@@ -638,25 +604,65 @@ int main(int argc, char **argv)
speex_encoder_ctl(st, SPEEX_SET_ABR, &abr_enabled);
}
speex_encoder_ctl(st, SPEEX_GET_LOOKAHEAD, &lookahead);
if (denoise_enabled || agc_enabled)
{
preprocess = speex_preprocess_state_init(frame_size, rate);
speex_preprocess_ctl(preprocess, SPEEX_PREPROCESS_SET_DENOISE, &denoise_enabled);
speex_preprocess_ctl(preprocess, SPEEX_PREPROCESS_SET_AGC, &agc_enabled);
lookahead += frame_size;
}
/*Write header*/
{
op.packet = (unsigned char *)speex_header_to_packet(&header, (int*)&(op.bytes));
op.b_o_s = 1;
op.e_o_s = 0;
op.granulepos = 0;
op.packetno = 0;
ogg_stream_packetin(&os, &op);
free(op.packet);
op.packet = (unsigned char *)comments;
op.bytes = comments_length;
op.b_o_s = 0;
op.e_o_s = 0;
op.granulepos = 0;
op.packetno = 1;
ogg_stream_packetin(&os, &op);
while((result = ogg_stream_flush(&os, &og)))
{
if(!result) break;
ret = oe_write_page(&og, fout);
if(ret != og.header_len + og.body_len)
{
fprintf (stderr,"Error: failed writing header to output stream\n");
exit(1);
}
else
bytes_written += ret;
}
}
free(comments);
speex_bits_init(&bits);
if (!wave_input)
{
if (read_samples(fin,frame_size,fmt,chan,lsb,input, first_bytes, NULL))
eos=1;
nb_samples = read_samples(fin,frame_size,fmt,chan,lsb,input, first_bytes, NULL);
} else {
if (read_samples(fin,frame_size,fmt,chan,lsb,input, NULL, &size))
eos=1;
nb_samples = read_samples(fin,frame_size,fmt,chan,lsb,input, NULL, &size);
}
if (nb_samples==0)
eos=1;
total_samples += nb_samples;
nb_encoded = -lookahead;
/*Main encoding loop (one frame per iteration)*/
while (!eos)
while (!eos || total_samples>nb_encoded)
{
id++;
/*Encode current frame*/
......@@ -668,6 +674,7 @@ int main(int argc, char **argv)
speex_encode_int(st, input, &bits);
nb_encoded += frame_size;
if (print_bitrate) {
int tmp;
char ch=13;
......@@ -687,18 +694,19 @@ int main(int argc, char **argv)
if (wave_input)
{
if (read_samples(fin,frame_size,fmt,chan,lsb,input, NULL, &size))
{
eos=1;
op.e_o_s = 1;
}
nb_samples = read_samples(fin,frame_size,fmt,chan,lsb,input, NULL, &size);
} else {
if (read_samples(fin,frame_size,fmt,chan,lsb,input, NULL, NULL))
{
eos=1;
op.e_o_s = 1;
}
nb_samples = read_samples(fin,frame_size,fmt,chan,lsb,input, NULL, NULL);
}
if (nb_samples==0)
{
eos=1;
}
if (eos && total_samples<=nb_encoded)
op.e_o_s = 1;
else
op.e_o_s = 0;
total_samples += nb_samples;
if ((id+1)%nframes!=0)
continue;
......@@ -708,11 +716,15 @@ int main(int argc, char **argv)
op.packet = (unsigned char *)cbits;
op.bytes = nbBytes;
op.b_o_s = 0;
if (eos)
/*Is this redundent?*/
if (eos && total_samples<=nb_encoded)
op.e_o_s = 1;
else
op.e_o_s = 0;
op.granulepos = (id+nframes)*frame_size;
op.granulepos = (id+1)*frame_size-lookahead;
if (op.granulepos>total_samples)
op.granulepos = total_samples;
/*printf ("granulepos: %d %d %d %d %d %d\n", (int)op.granulepos, id, nframes, lookahead, 5, 6);*/
op.packetno = 2+id/nframes;
ogg_stream_packetin(&os, &op);
......@@ -741,7 +753,10 @@ int main(int argc, char **argv)
op.bytes = nbBytes;
op.b_o_s = 0;
op.e_o_s = 1;
op.granulepos = (id+nframes)*frame_size;
op.granulepos = (id+1)*frame_size-lookahead;
if (op.granulepos>total_samples)
op.granulepos = total_samples;
op.packetno = 2+id/nframes;
ogg_stream_packetin(&os, &op);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment