r807: Minor fix...
[cinelerra_cv/mob.git] / cinelerra / indexthread.C
blob68b23f2ac58da0e44b43d0b3e5ea586c59f54305
1 #include "asset.h"
2 #include "condition.h"
3 #include "edl.h"
4 #include "edlsession.h"
5 #include "filexml.h"
6 #include "indexfile.h"
7 #include "indexthread.h"
8 #include "language.h"
9 #include "mwindow.h"
10 #include "mwindowgui.h"
11 #include "preferences.h"
12 #include "mainsession.h"
13 #include "trackcanvas.h"
14 #include "tracks.h"
16 // Read data from buffers and calculate peaks
18 IndexThread::IndexThread(MWindow *mwindow, 
19                                                 IndexFile *index_file,
20                                                 Asset *asset,
21                                                 char *index_filename,
22                                                 int64_t buffer_size, 
23                                                 int64_t length_source)
25         this->asset = asset;
26         this->buffer_size = buffer_size;
27         this->length_source = length_source;
28         this->mwindow = mwindow;
29         this->index_filename = index_filename;
30         this->index_file = index_file;
32 // initialize output data
33         int64_t index_size = mwindow->preferences->index_size / 
34                 sizeof(float) + 1;      // size of output file in floats
36         delete [] asset->index_buffer;
37         delete [] asset->index_offsets;
38         delete [] asset->index_sizes;
40 // buffer used for drawing during the build.  This is not deleted in the asset
41         asset->index_buffer = new float[index_size];  
42 // This is deleted in the asset's destructor
43         asset->index_offsets = new int64_t[asset->channels];
44         asset->index_sizes = new int64_t[asset->channels];
45         bzero(asset->index_buffer, index_size * sizeof(float));
47 // initialization is completed in run
48         for(int i = 0; i < TOTAL_BUFFERS; i++)
49         {
50                 buffer_in[i] = new double*[asset->channels];
51                 output_lock[i] = new Condition(0, "IndexThread::output_lock");
52                 input_lock[i] = new Condition(1, "IndexThread::input_lock");
53                 for(int j = 0; j < asset->channels; j++)
54                 {
55                         buffer_in[i][j] = new double[buffer_size];
56                 }
57         }
59         interrupt_flag = 0;
62 IndexThread::~IndexThread()
64         for(int i = 0; i < TOTAL_BUFFERS; i++)
65         {
66                 for(int j = 0; j < asset->channels; j++)
67                 {
68                         delete [] buffer_in[i][j];
69                 }
70                 delete [] buffer_in[i];
71                 delete output_lock[i];
72                 delete input_lock[i];
73         }
74         
75         delete [] asset->index_buffer;
76         asset->index_buffer = 0;
79 int IndexThread::start_build()
81         set_synchronous(1);
82         interrupt_flag = 0;
83         current_buffer = 0;
84         for(int i = 0; i <  TOTAL_BUFFERS; i++) last_buffer[i] = 0;
85         start();
88 int IndexThread::stop_build()
90         join();
93 void IndexThread::run()
95         int done = 0;
97 // current high samples in index
98         int64_t *highpoint;            
99 // current low samples in the index
100         int64_t *lowpoint;             
101 // position in current indexframe
102         int64_t *frame_position;
103         int first_point = 1;
105         highpoint = new int64_t[asset->channels];
106         lowpoint = new int64_t[asset->channels];
107         frame_position = new int64_t[asset->channels];
109 // predict first highpoint for each channel plus padding and initialize it
110         for(int64_t channel = 0; channel < asset->channels; channel++)
111         {
112                 highpoint[channel] = 
113                         asset->index_offsets[channel] = 
114                         (length_source / asset->index_zoom * 2 + 1) * channel;
115                 lowpoint[channel] = highpoint[channel] + 1;
117                 frame_position[channel] = 0;
118         }
120         int64_t index_start = 0;    // end of index during last edit update
121         asset->index_end = 0;      // samples in source completed
122         asset->old_index_end = 0;
123         asset->index_status = INDEX_BUILDING;
124         int64_t zoomx = asset->index_zoom;
125         float *index_buffer = asset->index_buffer;    // output of index build
127         while(!interrupt_flag && !done)
128         {
129                 output_lock[current_buffer]->lock("IndexThread::run");
131                 if(last_buffer[current_buffer]) done = 1;
132                 if(!interrupt_flag && !done)
133                 {
134 // process buffer
135                         int64_t fragment_size = input_len[current_buffer];
137                         for(int channel = 0; channel < asset->channels; channel++)
138                         {
139                                 int64_t *highpoint_channel = &highpoint[channel];
140                                 int64_t *lowpoint_channel = &lowpoint[channel];
141                                 int64_t *frame_position_channel = &frame_position[channel];
142                                 double *buffer_source = buffer_in[current_buffer][channel];
144                                 for(int64_t i = 0; i < fragment_size; i++)
145                                 {
146                                         if(*frame_position_channel == zoomx)
147                                         {
148                                                 *highpoint_channel += 2;
149                                                 *lowpoint_channel += 2;
150                                                 *frame_position_channel = 0;
151 // store and reset output values
152                                                 index_buffer[*highpoint_channel] = 
153                                                         index_buffer[*lowpoint_channel] = 
154                                                         buffer_source[i];
155                                                 asset->index_sizes[channel] = *lowpoint_channel - 
156                                                         asset->index_offsets[channel] + 
157                                                         1;
158                                         }
159                                         else
160                                         {
161 // get high and low points
162                                                 if(first_point)
163                                                 {
164                                                         index_buffer[*highpoint_channel] = 
165                                                                 index_buffer[*lowpoint_channel] = buffer_source[i];
166                                                         first_point = 0;
167                                                 }
168                                                 else
169                                                 {
170                                                         if(buffer_source[i] > index_buffer[*highpoint_channel]) 
171                                                                 index_buffer[*highpoint_channel] = buffer_source[i];
172                                                         else 
173                                                         if(buffer_source[i] < index_buffer[*lowpoint_channel]) 
174                                                                 index_buffer[*lowpoint_channel] = buffer_source[i];
175                                                 }
176                                         }
177                                         (*frame_position_channel)++;
178                                 } // end index one buffer
179                         }
181                         asset->index_end += fragment_size;
183 // draw simultaneously with build
184                         index_file->redraw_edits(0);
185                         index_start = asset->index_end;
186                 }
188                 input_lock[current_buffer]->unlock();
189                 current_buffer++;
190                 if(current_buffer >= TOTAL_BUFFERS) current_buffer = 0;
191         }
193         index_file->redraw_edits(1);
196 // write the index file to disk
197         asset->write_index(index_filename, 
198                 (lowpoint[asset->channels - 1] + 1) * sizeof(float));
201         delete [] highpoint;
202         delete [] lowpoint;
203         delete [] frame_position;