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