forked from sahaRatul/sela
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathselaplay.c
More file actions
151 lines (127 loc) · 4.36 KB
/
selaplay.c
File metadata and controls
151 lines (127 loc) · 4.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include <stdio.h>
#include <malloc.h>
#include <pthread.h>
#include <assert.h>
#include "rice.h"
#include "lpc.h"
#include "format.h"
#include "pulse_output.h"
#include "packetqueue.h"
#define BLOCK_SIZE 2048
void *playback_func(void *arg);
int main(int argc,char **argv)
{
if(argc < 2)
{
fprintf(stderr,"Usage : %s <input.sela>\n",argv[0]);
return -1;
}
FILE *infile = fopen(argv[1],"rb");
if(infile == NULL)
{
fprintf(stderr,"Error while opening input.\n");
return -1;
}
int sample_rate,temp,i,j = 0;
unsigned char opt_lpc_order;
const int frame_sync = 0xAA55FF00;
const int corr = 1 << 20;
unsigned int frame_count = 0;
const short Q = 20;
short bps;
unsigned short num_ref_elements,num_residue_elements,samples_per_channel;
unsigned char channels,curr_channel,rice_param_ref,rice_param_residue;
PacketList list;
audio_format fmt;
pthread_t play_thread;
signed short signed_decomp_ref[MAX_LPC_ORDER];
unsigned short compressed_ref[MAX_LPC_ORDER];
unsigned short compressed_residues[BLOCK_SIZE];
unsigned short decomp_ref[MAX_LPC_ORDER];
short s_ref[MAX_LPC_ORDER];
short s_rcv_samples[BLOCK_SIZE];
unsigned short decomp_residues[BLOCK_SIZE];
short s_residues[BLOCK_SIZE];
int rcv_samples[BLOCK_SIZE];
int lpc[MAX_LPC_ORDER + 1];
double ref[MAX_LPC_ORDER];
double lpc_mat[MAX_LPC_ORDER][MAX_LPC_ORDER];
fread(&sample_rate,sizeof(int),1,infile);
fread(&bps,sizeof(short),1,infile);
fread(&channels,sizeof(unsigned char),1,infile);
fprintf(stderr,"Sample rate : %d Hz\n",sample_rate);
fprintf(stderr,"Bits per sample : %d\n",bps);
fprintf(stderr,"Channels : %d\n",channels);
fmt.sample_rate = sample_rate;
fmt.num_channels = channels;
fmt.bits_per_sample = bps;
initialize_pulse(&fmt);
PacketQueueInit(&list);
//Start playback thread
pthread_create(&play_thread,NULL,&playback_func,(void *)(&list));
//Main loop
while(feof(infile) == 0)
{
short *buffer = (short *)malloc(sizeof(short) * BLOCK_SIZE * channels);
fread(&temp,sizeof(int),1,infile);//Read from input
if(temp == frame_sync)
{
for(i = 0; i < channels; i++)
{
fread(&curr_channel,sizeof(unsigned char),1,infile);
//Read rice_params,bytes,encoded lpc_coeffs from input
fread(&rice_param_ref,sizeof(unsigned char),1,infile);
fread(&num_ref_elements,sizeof(unsigned short),1,infile);
fread(&opt_lpc_order,sizeof(unsigned char),1,infile);
fread(compressed_ref,sizeof(unsigned short),num_ref_elements,infile);
//Read rice_params,bytes,encoded residues from input
fread(&rice_param_residue,sizeof(unsigned char),1,infile);
fread(&num_residue_elements,sizeof(unsigned short),1,infile);
fread(&samples_per_channel,sizeof(unsigned short),1,infile);
fread(compressed_residues,sizeof(unsigned short),num_residue_elements,infile);
//Decode compressed reflection coefficients and residues
char decoded_lpc_num = rice_decode_block(rice_param_ref,compressed_ref,opt_lpc_order,decomp_ref);
assert(decoded_lpc_num == opt_lpc_order);
short decomp_residues_num = rice_decode_block(rice_param_residue,compressed_residues,samples_per_channel,decomp_residues);
assert(decomp_residues_num == samples_per_channel);
//unsigned to signed
unsigned_to_signed(opt_lpc_order,decomp_ref,s_ref);
unsigned_to_signed(samples_per_channel,decomp_residues,s_residues);
//Dequantize reflection coefficients
dqtz_ref_cof(s_ref,opt_lpc_order,Q,ref);
//Generate lpc coefficients
levinson(NULL,opt_lpc_order,ref,lpc_mat);
lpc[0] = 0;
for(int k = 0; k < opt_lpc_order; k++)
lpc[k+1] = corr * lpc_mat[opt_lpc_order - 1][k];
//Generate original
calc_signal(s_residues,samples_per_channel,opt_lpc_order,Q,lpc,rcv_samples);
//Copy_to_short
for(int k = 0; k < samples_per_channel; k++)
s_rcv_samples[k] = rcv_samples[k];
//Combine samples from all channels
for(int k = 0; k < samples_per_channel; k++)
buffer[channels * k + i] = s_rcv_samples[k];
}
PacketNode *node=(PacketNode *)malloc(sizeof(PacketNode));
node->packet = (char *)buffer;
node->packet_size = samples_per_channel * channels * sizeof(short);
PacketQueuePut(&list,node);//Insert in list
}
else
{
fprintf(stderr,"Sync lost\n");
break;
}
}
pthread_join(play_thread,NULL);
destroy_pulse();
fclose(infile);
return 0;
}
void *playback_func(void *arg)
{
PacketList *list=(PacketList *)arg;
pulse_play(list);
return NULL;
}