3 #include "edlsession.h"
6 #include "indexthread.h"
8 #include "mwindowgui.h"
9 #include "preferences.h"
10 #include "mainsession.h"
11 #include "trackcanvas.h"
15 #define _(String) gettext(String)
16 #define gettext_noop(String) String
17 #define N_(String) gettext_noop (String)
19 // Read data from buffers and calculate peaks
21 IndexThread::IndexThread(MWindow *mwindow,
22 IndexFile *index_file,
26 int64_t length_source)
29 this->buffer_size = buffer_size;
30 this->length_source = length_source;
31 this->mwindow = mwindow;
32 this->index_filename = index_filename;
33 this->index_file = index_file;
35 // initialize output data
36 int64_t index_size = mwindow->preferences->index_size /
37 sizeof(float) + 1; // size of output file in floats
38 if(asset->index_buffer) delete [] asset->index_buffer;
39 if(asset->index_offsets) delete [] asset->index_offsets;
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 bzero(asset->index_buffer, index_size * sizeof(float));
45 //printf("IndexThread::IndexThread %d\n", index_size);
47 // initialization is completed in run
48 for(int i = 0; i < TOTAL_BUFFERS; i++)
50 buffer_in[i] = new double*[asset->channels];
51 for(int j = 0; j < asset->channels; j++)
53 buffer_in[i][j] = new double[buffer_size];
55 output_lock[i].lock();
61 IndexThread::~IndexThread()
63 for(int i = 0; i < TOTAL_BUFFERS; i++)
65 for(int j = 0; j < asset->channels; j++)
67 delete [] buffer_in[i][j];
69 delete [] buffer_in[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();
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;