summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <robin@xiph.org>2010-05-30 15:27:19 +0000
committerRobin Watts <robin@xiph.org>2010-05-30 15:27:19 +0000
commitd024c7dcbd50115ba7871850a18ef51caf8837f1 (patch)
tree199c0f33c9d4094d4ba43eded1f2fa7eb060d803
parentd4a99079c96f680aae57af6a49a4c0c82eea0308 (diff)
downloadtremor-d024c7dcbd50115ba7871850a18ef51caf8837f1.tar.gz
Add final ARM code sections for Tremolo decode.
Add missing couple of vorbis dsp entrypoints. git-svn-id: https://svn.xiph.org/branches/lowmem-branch/Tremolo@17258 0101bb08-14d6-0310-b084-bc0e0c8e3800
-rw-r--r--Makefile.rjw4
-rw-r--r--codebook.c14
-rw-r--r--dpenARM.s459
-rw-r--r--dsp.c16
-rw-r--r--framing.c140
5 files changed, 575 insertions, 58 deletions
diff --git a/Makefile.rjw b/Makefile.rjw
index c8acd47..63d349c 100644
--- a/Makefile.rjw
+++ b/Makefile.rjw
@@ -30,7 +30,7 @@ AS = arm-none-linux-gnueabi-as
DEFINES :=
-CFLAGS := -g -mcpu=cortex-a8 -mfpu=neon -I$(srcdir) -D__ARM__ -D_ARM_
+CFLAGS := -O3 -mcpu=cortex-a8 -mfpu=neon -I$(srcdir) -D__ARM__ -D_ARM_
CXXFLAGS := $(CFLAGS)
@@ -44,6 +44,7 @@ LIBOBJS := \
build/bitwise.o \
build/bitwiseARM.o \
build/codebook.o \
+ build/dpenARM.o \
build/dsp.o \
build/floor0.o \
build/floor1.o \
@@ -79,6 +80,7 @@ LIBOBJS_L := \
build/bitwise.ol \
build/bitwiseARM.o \
build/codebook.ol \
+ build/dpenARM.o \
build/dsp.ol \
build/floor0.ol \
build/floor1.ol \
diff --git a/codebook.c b/codebook.c
index 75ee255..6fe99e0 100644
--- a/codebook.c
+++ b/codebook.c
@@ -602,6 +602,9 @@ int vorbis_book_unpack(oggpack_buffer *opb,codebook *s){
return -1;
}
+#ifdef _ARM_ASSEM_
+ogg_uint32_t decode_packed_entry_number(codebook *book, oggpack_buffer *b);
+#else
static inline ogg_uint32_t decode_packed_entry_number(codebook *book,
oggpack_buffer *b){
ogg_uint32_t chase=0;
@@ -695,6 +698,7 @@ static inline ogg_uint32_t decode_packed_entry_number(codebook *book,
oggpack_adv(b,read+1);
return(-1);
}
+#endif
/* returns the [original, not compacted] entry number or -1 on eof *********/
long vorbis_book_decode(codebook *book, oggpack_buffer *b){
@@ -702,6 +706,9 @@ long vorbis_book_decode(codebook *book, oggpack_buffer *b){
return decode_packed_entry_number(book,b);
}
+#ifdef _ARM_ASSEM_
+int decode_map(codebook *s, oggpack_buffer *b, ogg_int32_t *v, int point);
+#else
int decode_map(codebook *s, oggpack_buffer *b, ogg_int32_t *v, int point){
ogg_uint32_t entry = decode_packed_entry_number(s,b);
int i;
@@ -773,6 +780,7 @@ int decode_map(codebook *s, oggpack_buffer *b, ogg_int32_t *v, int point){
return 0;
}
+#endif
/* returns 0 on OK or -1 on eof *************************************/
long vorbis_book_decodevs_add(codebook *book,ogg_int32_t *a,
@@ -832,6 +840,11 @@ long vorbis_book_decodev_set(codebook *book,ogg_int32_t *a,
return 0;
}
+#ifdef _ARM_ASSEM_
+long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a,
+ long offset,int ch,
+ oggpack_buffer *b,int n,int point);
+#else
long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a,
long offset,int ch,
oggpack_buffer *b,int n,int point){
@@ -856,3 +869,4 @@ long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a,
return 0;
}
+#endif
diff --git a/dpenARM.s b/dpenARM.s
new file mode 100644
index 0000000..8a3cbef
--- /dev/null
+++ b/dpenARM.s
@@ -0,0 +1,459 @@
+; Tremolo library
+; Copyright (C) 2009 Robin Watts for Pinknoise Productions Ltd
+
+ AREA |.text|, CODE, READONLY
+
+ EXPORT decode_packed_entry_number
+ EXPORT decode_packed_entry_number_REALSTART
+ EXPORT decode_map
+ EXPORT vorbis_book_decodevv_add
+ EXPORT _checksum
+
+ IMPORT oggpack_adv
+ IMPORT oggpack_look
+ IMPORT oggpack_eop
+ IMPORT crc_lookup
+
+decode_packed_entry_number_REALSTART
+dpen_nobits
+ MOV r0,r5 ; r0 = b
+ MOV r1,#1 ; r1 = 1
+ BL oggpack_adv ; oggpack_adv(b,1) /* Force eop */
+duff
+ MVN r0,#0 ; return -1
+ LDMFD r13!,{r4-r8,r10,PC}
+
+dpen_readfailed
+ SUBS r4,r4,#1 ; r4 = --read
+ BEQ dpen_nobits
+ MOV r0,r5 ; r0 = b
+ MOV r1,r4 ; r1 = read
+ ADR r14,dpen_read_return
+ B oggpack_look
+
+decode_packed_entry_number
+ ; r0 = codebook *book
+ ; r1 = oggpack_buffer *b
+ STMFD r13!,{r4-r8,r10,r14}
+
+ LDMIA r0,{r4,r6,r7} ; r4 = read = book->max_length
+ ; r6 = book->dec_table
+ ; r7 = book->dec_method
+ MOV r5,r1 ; r5 = b
+
+ MOV r0,r5 ; r0 = b
+ MOV r1,r4 ; r1 = read
+ BL oggpack_look
+dpen_read_return
+ CMP r0,#0
+ BLT dpen_readfailed
+
+ ; r0 = lok
+ ; r4 = read
+ ; r5 = b
+ ; r6 = dec_table
+ ; r7 = dec_method
+
+ CMP r7, #3
+ BGT meth4
+ BEQ meth3
+ CMP r7, #1
+ BGT meth2
+ BEQ meth1
+meth0
+ RSB r1, r4, #0 ; r1 = i-read = 0-read
+ MOV r7, #0 ; r7 = chase
+m0_loop
+ MOVS r0, r0, LSR #1 ; r0 = lok>>1 C = bottom bit
+ ADC r2, r6, r7, LSL #1 ; r8 = &t[chase*2+C]
+ LDRB r7, [r2]
+ ADDS r1, r1, #1 ; r1 = i-read++ (i-read<0 => i<read)
+ ; stall Xscale
+ CMPLT r7, #0x80
+ BLT m0_loop
+ AND r7, r7, #0x7F ; r7 = chase
+ CMP r1, #0 ; if (i-read >= 0) === (i >= read)
+ MVNGT r7, #0 ; if (i >= read) value to return = -1
+ ADD r1, r1, r4 ; r1 = i-read+read+1 = i +1
+ MOV r0, r5 ; r0 = b
+ BL oggpack_adv ; oggpack_adv(b, i+1);
+ MOV r0, r7 ; return chase
+ LDMFD r13!,{r4-r8,r10,PC}
+
+meth1
+ ; r0 = lok
+ ; r4 = read
+ ; r5 = b
+ ; r6 = dec_table
+ RSB r1, r4, #0 ; r1 = i = -read
+ MOV r10,#0 ; r10= next = 0
+m1_loop
+ MOV r7, r10 ; r7 = chase=next
+ MOVS r0, r0, LSR #1 ; r0 = lok>>1 C = bottom bit
+ ADC r8, r6, r7 ; r8 = t+chase+bit
+ LDRB r10,[r8], -r6 ; r10= next=t[chase+bit] r8=chase+bit
+ ADDS r1, r1, #1 ; r1 = i++
+ ; stall Xscale
+ CMPLT r10,#0x80 ; if (next & 0x80) == 0
+ BLT m1_loop
+
+ ADD r1, r1, r4 ; r1 = i+read
+ MOV r0, r5 ; r0 = b
+ BL oggpack_adv ; oggpack_adv(b, i)
+
+ CMP r10,#0x80
+ BLT duff
+
+ CMP r8, r7 ; if bit==0 (chase+bit==chase) (sets C)
+ LDRNEB r14,[r6, r7] ; r14= t[chase]
+ MOVEQ r14,#128
+ ADC r12,r8, r6 ; r12= chase+bit+1+t
+ LDRB r14,[r12,r14,LSR #7] ; r14= t[chase+bit+1+(!bit || t[chase]&0x80)]
+ BIC r10,r10,#0x80 ; r3 = next &= ~0x80
+ ; stall Xscale
+ ORR r0, r14,r10,LSL #8 ; r7 = chase = (next<<8) | r14
+
+ LDMFD r13!,{r4-r8,r10,PC}
+
+
+meth2
+ RSB r1, r4, #0 ; r1 = i-read = 0-read
+ MOV r7, #0 ; r7 = chase
+ MOV r6, r6, LSR #1
+m2_loop
+ MOVS r0, r0, LSR #1 ; r0 = lok>>1 C = bottom bit
+ ADC r2, r6, r7, LSL #1 ; r8 = &t[chase*2+C]
+ LDRH r7, [r2, r2]
+ ADDS r1, r1, #1 ; r1 = i-read++ (i-read<0 => i<read)
+ ; stall Xscale
+ CMPLT r7, #0x8000
+ BLT m2_loop
+ BIC r7, r7, #0x8000 ; r7 = chase
+ CMP r1, #0 ; if (i-read >= 0) === (i >= read)
+ MVNGT r7, #0 ; if (i >= read) value to return = -1
+ ADD r1, r1, r4 ; r1 = i-read+read+1 = i +1
+ MOV r0, r5 ; r0 = b
+ BL oggpack_adv ; oggpack_adv(b, i+1);
+ MOV r0, r7 ; return chase
+ LDMFD r13!,{r4-r8,r10,PC}
+
+meth3
+ ; r0 = lok
+ ; r4 = read
+ ; r5 = b
+ ; r6 = dec_table
+ RSB r1, r4, #0 ; r1 = i = -read
+ MOV r10,#0 ; r10= next = 0
+m3_loop
+ MOV r7, r10 ; r7 = chase=next
+ MOVS r0, r0, LSR #1 ; r0 = lok>>1 C = bottom bit
+ ADC r8, r7, #0 ; r8 = chase+bit
+ MOV r8, r8, LSL #1 ; r8 = (chase+bit)<<1
+ LDRH r10,[r6, r8] ; r10= next=t[chase+bit]
+ ADDS r1, r1, #1 ; r1 = i++
+ ; stall Xscale
+ CMPLT r10,#0x8000 ; if (next & 0x8000) == 0
+ BLT m3_loop
+
+ ADD r1, r1, r4 ; r1 = i+read
+ MOV r0, r5 ; r0 = b
+ BL oggpack_adv ; oggpack_adv(b, i)
+
+ CMP r10,#0x8000
+ BLT duff
+
+ MOV r7, r7, LSL #1
+ CMP r8, r7 ; if bit==0 (chase+bit==chase) sets C
+ LDRNEH r14,[r6, r7] ; r14= t[chase]
+ MOVEQ r14,#0x8000
+ ADC r12,r8, r14,LSR #15 ; r12= 1+((chase+bit)<<1)+(!bit || t[chase]&0x8000)
+ ADC r12,r12,r14,LSR #15 ; r12= t + (1+chase+bit+(!bit || t[chase]&0x8000))<<1
+ LDRH r14,[r6, r12] ; r14= t[chase+bit+1
+ BIC r10,r10,#0x8000 ; r3 = next &= ~0x8000
+ ; stall Xscale
+ ORR r0, r14,r10,LSL #16 ; r7 = chase = (next<<16) | r14
+
+ LDMFD r13!,{r4-r8,r10,PC}
+
+meth4
+ RSB r1, r4, #0 ; r1 = i-read = 0-read
+ MOV r7, #0 ; r7 = chase
+m4_loop
+ MOVS r0, r0, LSR #1 ; r0 = lok>>1 C = bottom bit
+ ADC r2, r7, r7 ; r8 = chase*2+C
+ LDR r7, [r6, r2, LSL #2]
+ ADDS r1, r1, #1 ; r1 = i-read++ (i-read<0 => i<read)
+ ; stall Xscale
+ CMPLT r7, #0x80000000
+ BLT m4_loop
+ BIC r7, r7, #0x80000000 ; r7 = chase
+ CMP r1, #0 ; if (i-read >= 0) === (i >= read)
+ MVNGT r7, #0 ; if (i >= read) value to return = -1
+ ADD r1, r1, r4 ; r1 = i-read+read+1 = i +1
+ MOV r0, r5 ; r0 = b
+ BL oggpack_adv ; oggpack_adv(b, i+1);
+ MOV r0, r7 ; return chase
+ LDMFD r13!,{r4-r8,r10,PC}
+
+decode_map
+ ; r0 = codebook *s
+ ; r1 = oggpack_buffer *b
+ ; r2 = int v
+ ; r3 = int point
+ STMFD r13!,{r4-r11,r14}
+
+ MOV r4, r0 ; r4 = s
+ MOV r5, r1 ; r5 = b
+ MOV r6, r2 ; r6 = v
+ MOV r7, r3 ; r7 = point
+ BL decode_packed_entry_number
+ MOV r8, r0
+
+ MOV r0, r5
+ BL oggpack_eop
+ CMP r0, #0
+ BNE dm_duff
+
+ ; r4 = s
+ ; r5 = b
+ ; r6 = v
+ ; r7 = point
+ ; r8 = entry
+
+ LDR r1, [r4,#12] ; r1 = s->dec_type
+ LDR r2, [r4,#16] ; r2 = s->q_bits
+ LDR r3, [r4,#20] ; r3 = s->dim
+ LDR r5, [r4,#24] ; r5 = s->q_delp
+ LDR r11,[r4,#28] ; r11= s->q_minp
+ LDR r12,[r4,#32] ; r12= s->q_del = mul
+ LDR r14,[r4,#36] ; r14= s->q_min
+ SUBS r11,r7, r11 ; r11= add = point - s->q_minp
+
+ MOVGT r14,r14,ASR r11 ; r14= add = s->q_min >> add (if add >0)
+ RSBLT r11,r11,#0
+ MOVLT r14,r14,LSL r11 ; r14= add = s->q_min << -add (if add < 0)
+
+ SUBS r5, r7, r5 ; r5 = shiftM = point - s->q_delp
+ LDR r7, [r4,#40] ; r7 = s->q_seq
+ RSBLT r5, r5, #0 ; if (shiftM<0) r5 =-shiftM
+ MOVLT r12,r12,LSL r5 ; r12=mul<<-shiftM
+ MOVLT r5, #0 ; r5 =shiftM = 0
+ MOVGT r14,r14,LSL r5 ; add <<= shiftM
+
+ CMP r7,#0 ; seqMask = (s->q_seq?-1:0)
+ MVNNE r7,#0
+
+ CMP r1, #2
+ BEQ dm2
+ BGT dm3
+ CMP r1,#0 ; probably never happens
+ BLE dm_duff
+dm1
+ ; r1 = s->dec_type
+ ; r2 = s->q_bits
+ ; r3 = s->dim
+ ; r5 = shiftM
+ ; r6 = v
+ ; r7 = seqMask
+ ; r8 = entry
+ ; r12= mul
+ ; r14= add
+ MOV r0, #1
+ RSB r0, r0, r0, LSL r2 ; r0 = mask = (1<<s->q_bits)-1
+ MOV r11,#0 ; r11= prev = 0
+dm1_loop
+ AND r1, r8, r0 ; r1 = v = entry & mask
+ MLA r1, r12, r1, r14 ; r1 = (add + mul*v)
+ MOV r8, r8, LSR r2 ; r8 = entry>>s->q_bits
+ SUBS r3, r3, #1
+ ADD r1, r11,r1, ASR r5 ; r1 = v = prev+((add+mul*v)>>shiftM)
+ AND r11,r1, r7 ; r11= prev = seqMask & v
+ STR r1, [r6], #4 ; *v++ = v
+ BGT dm1_loop
+
+ MOV r0, #0
+ LDMFD r13!,{r4-r11,PC}
+dm2
+ ; r1 = s->dec_type
+ ; r2 = s->q_bits
+ ; r3 = s->dim
+ ; r4 = s
+ ; r5 = shiftM
+ ; r6 = v
+ ; r7 = seqMask
+ ; r8 = entry
+ ; r12= mul
+ ; r14= add
+ LDR r1, [r4,#44] ; r1 = s->q_pack
+ LDR r4, [r4,#48] ; r4 = s->q_val
+ MOV r11,#0 ; r11= prev
+ MOV r0, #1
+ RSB r0, r0, r0, LSL r1 ; r8 = mask = (1<<s->q_pack)-1
+ CMP r2,#8
+ BGT dm2_hword
+dm2_loop
+ AND r2, r8, r0 ; r2 = entry & mask
+ LDRB r2, [r4, r2] ; r2 = v = q->val[entry & mask]
+ MOV r8, r8, LSR r1 ; r8 = entry>>q_pack
+ MLA r2, r12,r2, r14 ; r2 = (add+mul*v)
+ SUBS r3, r3, #1
+ ADD r2, r11,r2, ASR r5 ; r2 = v = prev+(add+mul*v)>>shiftM
+ AND r11,r2, r7 ; r11= prev = seqMask & v
+ STR r2, [r6], #4 ; *v++ = v
+ BGT dm2_loop
+ MOV r0, #0
+ LDMFD r13!,{r4-r11,PC}
+
+dm2_hword
+ AND r2, r8, r0 ; r2 = entry & mask
+ MOV r2, r2, LSL #1 ; r2 = 2*r2
+ LDRH r2, [r4, r2] ; r2 = v = q->val[entry & mask]
+ MOV r8, r8, LSR r1 ; r8 = entry>>q_pack
+ MLA r2, r12,r2, r14 ; r2 = (add+mul*v)
+ SUBS r3, r3, #1
+ ADD r2, r11,r2, ASR r5 ; r2 = v = prev+(add+mul*v)>>shiftM
+ AND r11,r2, r7 ; r11= prev = seqMask & v
+ STR r2, [r6], #4 ; *v++ = v
+ BGT dm2_hword
+ MOV r0, #0
+ LDMFD r13!,{r4-r11,PC}
+
+dm3
+ ; r1 = s->dec_type
+ ; r2 = s->q_bits
+ ; r3 = s->dim
+ ; r4 = s
+ ; r5 = shiftM
+ ; r6 = v
+ ; r7 = seqMask
+ ; r8 = entry
+ ; r12= mul
+ ; r14= add
+ LDR r1, [r4,#44] ; r1 = s->q_pack
+ LDR r4, [r4,#52] ; r4 = s->q_val
+ CMP r2,#8
+ MOV r11,#0 ; r11= prev
+ MLA r4,r1,r8,r4 ; r4 = ptr = s->q_val+entry*s->q_pack
+
+ BGT dm3_hword
+dm3_loop
+ LDRB r2, [r4], #1 ; r2 = v = *ptr++
+ SUBS r3, r3, #1
+ MLA r2, r12,r2, r14 ; r2 = (add+mul*v)
+ ADD r2, r11,r2, ASR r5 ; r2 = v = prev+(add+mul*v)>>shiftM
+ AND r11,r2, r7 ; r11= prev = seqMask & v
+ STR r2, [r6], #4 ; *v++ = v
+ BGT dm3_loop
+ MOV r0, #0
+ LDMFD r13!,{r4-r11,PC}
+
+dm3_hword
+ LDRH r2, [r4], #2 ; r2 = *ptr++
+ SUBS r3, r3, #1
+ MLA r2, r12,r2, r14 ; r2 = (add+mul*v)
+ ADD r2, r11,r2, ASR r5 ; r2 = v = prev+(add+mul*v)>>shiftM
+ AND r11,r2, r7 ; r11= prev = seqMask & v
+ STR r2, [r6], #4 ; *v++ = v
+ BGT dm3_hword
+ MOV r0, #0
+ LDMFD r13!,{r4-r11,PC}
+
+dm_duff
+ MVN r0,#0
+ LDMFD r13!,{r4-r11,PC}
+
+vorbis_book_decodevv_add
+ ; r0 = codebook *book
+ ; r1 = ogg_int32_t **a
+ ; r2 = long offset
+ ; r3 = int ch
+ ; <> = b
+ ; <> = n
+ ; <> = point
+ STMFD r13!,{r4-r11,R14}
+ LDR r7, [r0, #13*4] ; r7 = used_entries
+ MOV r9, r0 ; r9 = book
+ MOV r10,r1 ; r10= &a[chptr] chptr=0
+ MOV r6, r3 ; r6 = ch
+ ADD r8, r10,r3, LSL #2 ; r8 = &a[ch]
+ MOV r11,r2 ; r11= offset
+ CMP r7, #0 ; if (used_entries <= 0)
+ BLE vbdvva_exit ; exit
+ LDR r5, [r13,#10*4] ; r5 = n
+vbdvva_loop1
+ ; r5 = n
+ ; r6 = ch
+ ; r8 = &a[ch]
+ ; r9 = book
+ ; r10= &a[chptr]
+ ; r11= offset
+ MOV r0, r9 ; r0 = book
+ LDR r1, [r13,# 9*4] ; r1 = b
+ LDR r2, [r9, #14*4] ; r2 = v = dec_buf
+ LDR r3, [r13,#11*4] ; r3 = point
+ BL decode_map
+ CMP r0, #0
+ BNE vbdvva_fail
+
+ LDR r0, [r9, # 5*4] ; r0 = book->dim
+ LDR r1, [r9, #14*4] ; r1 = v = dec_buf
+vbdvva_loop2
+ LDR r2, [r10],#4 ; r2 = a[chptr++]
+ LDR r12,[r1], #4 ; r1 = v[j++]
+ CMP r10,r8 ; if (chptr == ch)
+ SUBEQ r10,r10,r6, LSL #2 ; chptr = 0
+ LDR r14,[r2, r11,LSL #2]! ; r2 = &a[chptr++][i] r14=[r12]
+ ADDEQ r11,r11,#1 ; i++
+ SUBEQ r5, r5, #1 ; n--
+ SUBS r0, r0, #1 ; r0--
+ ADD r12,r12,r14 ; r12= a[chptr++][i]+ v[j]
+ STR r12,[r2] ; r12= a[chptr++][i]+=v[j]
+ BGT vbdvva_loop2
+ CMP r5,#0
+ BGT vbdvva_loop1
+vbdvva_exit
+ MOV r0, #0 ; return 0
+ LDMFD r13!,{r4-r11,PC}
+vbdvva_fail
+ MVN r0, #0 ; return -1
+ LDMFD r13!,{r4-r11,PC}
+
+_checksum
+ ; r0 = ogg_reference *or
+ ; r1 = bytes
+ STMFD r13!,{r5-r6,r14}
+
+ LDR r5,=crc_lookup
+ MOV r14,#0 ; r14= crc_reg = 0
+ MOVS r12,r0
+ BEQ _cs_end
+_cs_loop1
+ LDMIA r12,{r0,r2,r3,r12} ; r0 = or->buffer
+ ; r2 = or->begin
+ ; r3 = or->length
+ ; r12= or->next
+ LDR r0,[r0] ; r0 = or->buffer->data
+ CMP r1,r3 ; r3 = post = (bytes < or->length ?
+ MOVLT r3,r1 ; bytes : or->length)
+ MOVS r6,r3 ; r6 = j = post
+ BEQ _cs_no_bytes
+ ADD r0,r0,r2 ; r0 = or->buffer->data + or->begin
+_cs_loop2
+ LDRB r2, [r0],#1 ; r2 = data[j]
+ ; stall
+ ; stall Xscale
+ EOR r2, r2, r14,LSR #24 ; r2 = (crc_reg>>24)^data[j]
+ LDR r2, [r5, r2, LSL #2] ; r2 = crc_lkp[(crc_reg>>24)^data[j]]
+ SUBS r6, r6, #1 ; j--
+ ; stall Xscale
+ EOR r14,r2, r14,LSL #8 ; r14= crc_reg = (crc_reg<<8)^r2
+ BGT _cs_loop2
+_cs_no_bytes
+ SUBS r1, r1, r3
+ CMPNE r12,#0
+ BNE _cs_loop1
+_cs_end
+ MOV r0,r14
+ LDMFD r13!,{r5-r6,PC}
+
+ END
diff --git a/dsp.c b/dsp.c
index eaa3649..03a8fee 100644
--- a/dsp.c
+++ b/dsp.c
@@ -43,10 +43,9 @@ int vorbis_dsp_restart(vorbis_dsp_state *v){
return 0;
}
-vorbis_dsp_state *vorbis_dsp_create(vorbis_info *vi){
+int vorbis_dsp_init(vorbis_dsp_state *v,vorbis_info *vi){
int i;
- vorbis_dsp_state *v=_ogg_calloc(1,sizeof(*v));
codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
v->vi=vi;
@@ -64,10 +63,16 @@ vorbis_dsp_state *vorbis_dsp_create(vorbis_info *vi){
v->W=0; /* current window size */
vorbis_dsp_restart(v);
+ return 0;
+}
+
+vorbis_dsp_state *vorbis_dsp_create(vorbis_info *vi){
+ vorbis_dsp_state *v=_ogg_calloc(1,sizeof(*v));
+ vorbis_dsp_init(v,vi);
return v;
}
-void vorbis_dsp_destroy(vorbis_dsp_state *v){
+void vorbis_dsp_clear(vorbis_dsp_state *v){
int i;
if(v){
vorbis_info *vi=v->vi;
@@ -87,6 +92,11 @@ void vorbis_dsp_destroy(vorbis_dsp_state *v){
}
}
+void vorbis_dsp_destroy(vorbis_dsp_state *v){
+ vorbis_dsp_clear(v);
+ _ogg_free(v);
+}
+
static LOOKUP_T *_vorbis_window(int left){
switch(left){
case 32:
diff --git a/framing.c b/framing.c
index 4842143..e8ebed7 100644
--- a/framing.c
+++ b/framing.c
@@ -135,7 +135,7 @@ static ogg_reference *ogg_buffer_alloc(ogg_buffer_state *bs,long bytes){
/* enlarge the data buffer in the current link */
static void ogg_buffer_realloc(ogg_reference *or,long bytes){
ogg_buffer *ob=or->buffer;
-
+
/* if the unused buffer is too small, grow it */
if(ob->size<bytes){
ob->data=_ogg_realloc(ob->data,bytes);
@@ -160,7 +160,7 @@ static void ogg_buffer_mark(ogg_reference *or){
length, a zero length ref is returned. */
static ogg_reference *ogg_buffer_sub(ogg_reference *or,long length){
ogg_reference *ret=0,*head=0;
-
+
/* duplicate the reference chain; increment refcounts */
while(or && length){
ogg_reference *temp=_fetch_ref(or->buffer->ptr.owner);
@@ -169,12 +169,12 @@ static ogg_reference *ogg_buffer_sub(ogg_reference *or,long length){
else
ret=temp;
head=temp;
- head->buffer=or->buffer;
+ head->buffer=or->buffer;
head->begin=or->begin;
head->length=length;
if(head->length>or->length)
head->length=or->length;
-
+
length-=head->length;
or=or->next;
}
@@ -193,7 +193,7 @@ ogg_reference *ogg_buffer_dup(ogg_reference *or){
else
ret=temp;
head=temp;
- head->buffer=or->buffer;
+ head->buffer=or->buffer;
head->begin=or->begin;
head->length=or->length;
or=or->next;
@@ -224,44 +224,44 @@ static ogg_reference *ogg_buffer_split(ogg_reference **tail,
if(!or || pos==0){
return 0;
-
+
}else{
-
+
if(pos>=or->length){
/* exact split, or off the end? */
if(or->next){
-
+
/* a split */
*tail=or->next;
or->next=0;
-
+
}else{
-
+
/* off or at the end */
*tail=*head=0;
-
+
}
}else{
-
+
/* split within a fragment */
long lengthA=pos;
long beginB=or->begin+pos;
long lengthB=or->length-pos;
-
+
/* make a new reference to tail the second piece */
*tail=_fetch_ref(or->buffer->ptr.owner);
-
+
(*tail)->buffer=or->buffer;
(*tail)->begin=beginB;
(*tail)->length=lengthB;
(*tail)->next=or->next;
_ogg_buffer_mark_one(*tail);
- if(head && or==*head)*head=*tail;
-
+ if(head && or==*head)*head=*tail;
+
/* update the first piece */
or->next=0;
or->length=lengthA;
-
+
}
}
return ret;
@@ -277,7 +277,7 @@ static void ogg_buffer_release_one(ogg_reference *or){
ob->ptr.next=bs->unused_buffers;
bs->unused_buffers=ob;
}
-
+
bs->outstanding--; /* for the returned reference */
or->next=bs->unused_references;
bs->unused_references=or;
@@ -358,7 +358,7 @@ static int oggbyte_init(oggbyte_buffer *b,ogg_reference *or){
b->ref=b->baseref=or;
b->pos=0;
b->end=b->ref->length;
- b->ptr=b->ref->buffer->data+b->ref->begin;
+ b->ptr=b->ref->buffer->data+b->ref->begin;
return 0;
}else
return -1;
@@ -374,7 +374,7 @@ static void oggbyte_set4(oggbyte_buffer *b,ogg_uint32_t val,int pos){
++pos;
}
}
-
+
static unsigned char oggbyte_read1(oggbyte_buffer *b,int pos){
_positionB(b,pos);
_positionF(b,pos);
@@ -451,7 +451,7 @@ ogg_uint32_t ogg_page_serialno(ogg_page *og){
if(oggbyte_init(&ob,og->header)) return 0xffffffffUL;
return oggbyte_read4(&ob,14);
}
-
+
ogg_uint32_t ogg_page_pageno(ogg_page *og){
oggbyte_buffer ob;
if(oggbyte_init(&ob,og->header))return 0xffffffffUL;
@@ -465,13 +465,13 @@ ogg_uint32_t ogg_page_pageno(ogg_page *og){
/* NOTE:
If a page consists of a packet begun on a previous page, and a new
packet begun (but not completed) on this page, the return will be:
- ogg_page_packets(page) ==1,
+ ogg_page_packets(page) ==1,
ogg_page_continued(page) !=0
If a page happens to be a single packet that was begun on a
previous page, and spans to the next page (in the case of a three or
-more page packet), the return will be:
- ogg_page_packets(page) ==0,
+more page packet), the return will be:
+ ogg_page_packets(page) ==0,
ogg_page_continued(page) !=0
*/
@@ -491,7 +491,7 @@ int ogg_page_packets(ogg_page *og){
/* Static CRC calculation table. See older code in CVS for dead
run-time initialization code. */
-static ogg_uint32_t crc_lookup[256]={
+ogg_uint32_t crc_lookup[256]={
0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,
0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005,
0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61,
@@ -557,6 +557,11 @@ static ogg_uint32_t crc_lookup[256]={
0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668,
0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4};
+void ogg_sync_init(ogg_sync_state *oy){
+ memset(oy,0,sizeof(*oy));
+ oy->bufferpool=ogg_buffer_create();
+}
+
ogg_sync_state *ogg_sync_create(void){
ogg_sync_state *oy=_ogg_calloc(1,sizeof(*oy));
memset(oy,0,sizeof(*oy));
@@ -564,6 +569,15 @@ ogg_sync_state *ogg_sync_create(void){
return oy;
}
+int ogg_sync_clear(ogg_sync_state *oy){
+ if(oy){
+ ogg_sync_reset(oy);
+ ogg_buffer_destroy(oy->bufferpool);
+ memset(oy,0,sizeof(*oy));
+ }
+ return OGG_SUCCESS;
+}
+
int ogg_sync_destroy(ogg_sync_state *oy){
if(oy){
ogg_sync_reset(oy);
@@ -595,7 +609,7 @@ unsigned char *ogg_sync_bufferin(ogg_sync_state *oy, long bytes){
oy->fifo_head=oy->fifo_tail=ogg_buffer_alloc(oy->bufferpool,bytes);
return oy->fifo_head->buffer->data;
}
-
+
/* space left in current fragment case */
if(oy->fifo_head->buffer->size-
oy->fifo_head->length-
@@ -608,7 +622,7 @@ unsigned char *ogg_sync_bufferin(ogg_sync_state *oy, long bytes){
ogg_buffer_realloc(oy->fifo_head,bytes);
return oy->fifo_head->buffer->data+oy->fifo_head->begin;
}
-
+
/* current fragment used/full; get new fragment */
{
ogg_reference *new=ogg_buffer_alloc(oy->bufferpool,bytes);
@@ -618,15 +632,18 @@ unsigned char *ogg_sync_bufferin(ogg_sync_state *oy, long bytes){
return oy->fifo_head->buffer->data;
}
-int ogg_sync_wrote(ogg_sync_state *oy, long bytes){
+int ogg_sync_wrote(ogg_sync_state *oy, long bytes){
if(!oy->fifo_head)return OGG_EINVAL;
- if(oy->fifo_head->buffer->size-oy->fifo_head->length-oy->fifo_head->begin <
+ if(oy->fifo_head->buffer->size-oy->fifo_head->length-oy->fifo_head->begin <
bytes)return OGG_EINVAL;
oy->fifo_head->length+=bytes;
oy->fifo_fill+=bytes;
return OGG_SUCCESS;
}
+#ifdef _ARM_ASSEM_
+ogg_uint32_t _checksum(ogg_reference *or, int bytes);
+#else
static ogg_uint32_t _checksum(ogg_reference *or, int bytes){
ogg_uint32_t crc_reg=0;
int j,post;
@@ -642,7 +659,7 @@ static ogg_uint32_t _checksum(ogg_reference *or, int bytes){
return crc_reg;
}
-
+#endif
/* sync the stream. This is meant to be useful for finding page
boundaries.
@@ -651,7 +668,7 @@ static ogg_uint32_t _checksum(ogg_reference *or, int bytes){
-n) skipped n bytes
0) page not ready; more data (no bytes skipped)
n) page synced at current location; page length n bytes
-
+
*/
long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
@@ -665,7 +682,7 @@ long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
if(oy->headerbytes==0){
if(bytes<27)goto sync_out; /* not enough for even a minimal header */
-
+
/* verify capture pattern */
if(oggbyte_read1(&page,0)!=(int)'O' ||
oggbyte_read1(&page,1)!=(int)'g' ||
@@ -682,7 +699,7 @@ long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
for(i=0;i<oy->headerbytes-27;i++)
oy->bodybytes+=oggbyte_read1(&page,27+i);
}
-
+
if(oy->bodybytes+oy->headerbytes>bytes)goto sync_out;
/* we have what appears to be a complete page; last test: verify
@@ -693,11 +710,11 @@ long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
/* Compare checksums; memory continues to be common access */
if(chksum!=_checksum(oy->fifo_tail,oy->bodybytes+oy->headerbytes)){
-
+
/* D'oh. Mismatch! Corrupt page (or miscapture and not a page
at all). replace the computed checksum with the one actually
read in; remember all the memory is common access */
-
+
oggbyte_set4(&page,chksum,22);
goto sync_fail;
}
@@ -717,7 +734,7 @@ long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
ogg_buffer_pretruncate(oy->fifo_tail,oy->headerbytes+oy->bodybytes);
if(!oy->fifo_tail)oy->fifo_head=0;
}
-
+
ret=oy->headerbytes+oy->bodybytes;
oy->unsynced=0;
oy->headerbytes=0;
@@ -725,20 +742,20 @@ long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
oy->fifo_fill-=ret;
return ret;
-
+
sync_fail:
oy->headerbytes=0;
oy->bodybytes=0;
oy->fifo_tail=ogg_buffer_pretruncate(oy->fifo_tail,1);
ret--;
-
+
/* search forward through fragments for possible capture */
while(oy->fifo_tail){
/* invariant: fifo_cursor points to a position in fifo_tail */
unsigned char *now=oy->fifo_tail->buffer->data+oy->fifo_tail->begin;
unsigned char *next=memchr(now, 'O', oy->fifo_tail->length);
-
+
if(next){
/* possible capture in this segment */
long bytes=next-now;
@@ -786,7 +803,7 @@ int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og){
/* need more data */
return 0;
}
-
+
/* head did not start a synced page... skipped some bytes */
if(!oy->unsynced){
oy->unsynced=1;
@@ -812,22 +829,37 @@ int ogg_sync_reset(ogg_sync_state *oy){
return OGG_SUCCESS;
}
+void ogg_stream_init(ogg_stream_state *os, int serialno){
+ memset(os, 0, sizeof(*os));
+ os->serialno=serialno;
+ os->pageno=-1;
+}
+
ogg_stream_state *ogg_stream_create(int serialno){
ogg_stream_state *os=_ogg_calloc(1,sizeof(*os));
os->serialno=serialno;
os->pageno=-1;
return os;
-}
+}
+
+int ogg_stream_clear(ogg_stream_state *os){
+ if(os){
+ ogg_buffer_release(os->header_tail);
+ ogg_buffer_release(os->body_tail);
+ memset(os,0,sizeof(*os));
+ }
+ return OGG_SUCCESS;
+}
int ogg_stream_destroy(ogg_stream_state *os){
if(os){
ogg_buffer_release(os->header_tail);
ogg_buffer_release(os->body_tail);
- memset(os,0,sizeof(*os));
+ memset(os,0,sizeof(*os));
_ogg_free(os);
}
return OGG_SUCCESS;
-}
+}
#define FINFLAG 0x80000000UL
@@ -847,9 +879,9 @@ static void _next_lace(oggbyte_buffer *ob,ogg_stream_state *os){
}
}
-static void _span_queued_page(ogg_stream_state *os){
+static void _span_queued_page(ogg_stream_state *os){
while( !(os->body_fill&FINFLAG) ){
-
+
if(!os->header_tail)break;
/* first flush out preceeding page header (if any). Body is
@@ -866,7 +898,7 @@ static void _span_queued_page(ogg_stream_state *os){
os->header_head=0;
break;
}else{
-
+
/* process/prepare next page, if any */
long pageno;
@@ -877,7 +909,7 @@ static void _span_queued_page(ogg_stream_state *os){
oggbyte_init(&ob,os->header_tail);
os->lacing_fill=oggbyte_read1(&ob,26);
-
+
/* are we in sequence? */
if(pageno!=os->pageno){
if(os->pageno==-1) /* indicates seek or reset */
@@ -891,12 +923,12 @@ static void _span_queued_page(ogg_stream_state *os){
os->body_fill=0;
}
-
+
if(ogg_page_continued(&og)){
if(os->body_fill==0){
/* continued packet, but no preceeding data to continue */
/* dump the first partial packet on the page */
- _next_lace(&ob,os);
+ _next_lace(&ob,os);
os->body_tail=
ogg_buffer_pretruncate(os->body_tail,os->body_fill_next&FINMASK);
if(os->body_tail==0)os->body_head=0;
@@ -928,11 +960,11 @@ static void _span_queued_page(ogg_stream_state *os){
_next_lace(&ob,os);
}
-
+
os->pageno=pageno+1;
os->e_o_s=ogg_page_eos(&og);
os->b_o_s=ogg_page_bos(&og);
-
+
}
}
}
@@ -947,11 +979,11 @@ int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){
/* check the serial number */
if(serialno!=os->serialno){
- ogg_page_release(og);
+ //ogg_page_release(og);
return OGG_ESERIAL;
}
if(version>0){
- ogg_page_release(og);
+ //ogg_page_release(og);
return OGG_EVERSION;
}
@@ -1074,7 +1106,7 @@ static int _packetout(ogg_stream_state *os,ogg_packet *op,int adv){
op->bytes=os->body_fill&FINMASK;
}
}
-
+
if(adv){
os->packetno++;
os->b_o_s=0;