4 #include "edlsession.h"
7 #include "indexthread.h"
10 #include "mwindowgui.h"
11 #include "preferences.h"
12 #include "mainsession.h"
13 #include "trackcanvas.h"
16 // Read data from buffers and calculate peaks
18 IndexThread::IndexThread(MWindow *mwindow,
19 IndexFile *index_file,
23 int64_t length_source)
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
35 if(asset->index_buffer) delete [] asset->index_buffer;
36 if(asset->index_offsets) delete [] asset->index_offsets;
37 // buffer used for drawing during the build. This is not deleted in the asset
38 asset->index_buffer = new float[index_size];
39 // This is deleted in the asset's destructor
40 asset->index_offsets = new int64_t[asset->channels];
41 bzero(asset->index_buffer, index_size * sizeof(float));
42 //printf("IndexThread::IndexThread %d\n", index_size);
44 // initialization is completed in run
45 for(int i = 0; i < TOTAL_BUFFERS; i++)
47 buffer_in[i] = new double*[asset->channels];
48 output_lock[i] = new Condition(0, "IndexThread::output_lock");
49 input_lock[i] = new Condition(1, "IndexThread::input_lock");
50 for(int j = 0; j < asset->channels; j++)
52 buffer_in[i][j] = new double[buffer_size];
59 IndexThread::~IndexThread()
61 for(int i = 0; i < TOTAL_BUFFERS; i++)
63 for(int j = 0; j < asset->channels; j++)
65 delete [] buffer_in[i][j];
67 delete [] buffer_in[i];
68 delete output_lock[i];
72 delete [] asset->index_buffer;
73 asset->index_buffer = 0;
76 int IndexThread::start_build()
81 for(int i = 0; i < TOTAL_BUFFERS; i++) last_buffer[i] = 0;
85 int IndexThread::stop_build()
90 void IndexThread::run()
94 // current high samples in index
96 // current low samples in the index
98 // position in current indexframe
99 int64_t *frame_position;
102 highpoint = new int64_t[asset->channels];
103 lowpoint = new int64_t[asset->channels];
104 frame_position = new int64_t[asset->channels];
106 // predict first highpoint for each channel plus padding and initialize it
107 for(int64_t channel = 0; channel < asset->channels; channel++)
110 asset->index_offsets[channel] =
111 (length_source / asset->index_zoom * 2 + 1) * channel;
112 lowpoint[channel] = highpoint[channel] + 1;
114 // Not effective when index_zoom == 1
115 // zero the first point
116 // asset->index_buffer[highpoint[channel]] = 0;
117 // asset->index_buffer[lowpoint[channel]] = 0;
118 frame_position[channel] = 0;
121 int64_t index_start = 0; // end of index during last edit update
122 asset->index_end = 0; // samples in source completed
123 asset->old_index_end = 0;
124 asset->index_status = 2;
125 int64_t zoomx = asset->index_zoom;
126 float *index_buffer = asset->index_buffer; // output of index build
128 // index_file->redraw_edits();
130 while(!interrupt_flag && !done)
132 output_lock[current_buffer]->lock("IndexThread::run");
134 if(last_buffer[current_buffer]) done = 1;
135 if(!interrupt_flag && !done)
138 int64_t fragment_size = input_len[current_buffer];
140 //printf("IndexThread::run 1\n");
141 for(int channel = 0; channel < asset->channels; channel++)
143 int64_t *highpoint_channel = &highpoint[channel];
144 int64_t *lowpoint_channel = &lowpoint[channel];
145 int64_t *frame_position_channel = &frame_position[channel];
146 double *buffer_source = buffer_in[current_buffer][channel];
148 for(int64_t i = 0; i < fragment_size; i++)
150 if(*frame_position_channel == zoomx)
152 *highpoint_channel += 2;
153 *lowpoint_channel += 2;
154 *frame_position_channel = 0;
155 // store and reset output values
156 index_buffer[*highpoint_channel] = index_buffer[*lowpoint_channel] = buffer_source[i];
160 // get high and low points
163 index_buffer[*highpoint_channel] =
164 index_buffer[*lowpoint_channel] = buffer_source[i];
169 if(buffer_source[i] > index_buffer[*highpoint_channel])
170 index_buffer[*highpoint_channel] = buffer_source[i];
172 if(buffer_source[i] < index_buffer[*lowpoint_channel])
173 index_buffer[*lowpoint_channel] = buffer_source[i];
176 (*frame_position_channel)++;
177 } // end index one buffer
179 //printf("IndexThread::run 2\n");
181 asset->index_end += fragment_size;
183 // draw simultaneously with build
184 //printf("IndexThread::run 2.1\n");
185 index_file->redraw_edits(0);
186 //printf("IndexThread::run 2.2\n");
187 index_start = asset->index_end;
188 //printf("IndexThread::run 2.3\n");
189 //printf("IndexThread::run 3\n");
192 //printf("IndexThread::run %ld\n", lowpoint[asset->channels - 1] + 1);
193 input_lock[current_buffer]->unlock();
195 if(current_buffer >= TOTAL_BUFFERS) current_buffer = 0;
198 index_file->redraw_edits(1);
200 // ================================== write the index file to disk
202 if(!(file = fopen(index_filename, "wb")))
204 // failed to create it
205 printf(_("IndexThread::run() Couldn't write index file %s to disk.\n"), index_filename);
210 fwrite((char*)&(asset->index_start), sizeof(int64_t), 1, file);
212 asset->index_status = INDEX_READY;
213 asset->write(mwindow->plugindb,
217 xml.write_to_file(file);
218 asset->index_start = ftell(file);
219 fseek(file, 0, SEEK_SET);
220 fwrite((char*)&(asset->index_start), sizeof(int64_t), 1, file);
221 fseek(file, asset->index_start, SEEK_SET);
223 fwrite(asset->index_buffer, (lowpoint[asset->channels - 1] + 1) * sizeof(float), 1, file);
228 // Force reread of header
229 asset->index_status = INDEX_NOTTESTED;
230 // asset->index_status = INDEX_READY;
231 asset->index_end = length_source;
232 asset->old_index_end = 0;
233 asset->index_start = 0;
237 delete [] frame_position;