00001 #include "asset.h" 00002 #include "condition.h" 00003 #include "edl.h" 00004 #include "edlsession.h" 00005 #include "filexml.h" 00006 #include "indexfile.h" 00007 #include "indexthread.h" 00008 #include "language.h" 00009 #include "mwindow.h" 00010 #include "mwindowgui.h" 00011 #include "preferences.h" 00012 #include "mainsession.h" 00013 #include "trackcanvas.h" 00014 #include "tracks.h" 00015 00016 // Read data from buffers and calculate peaks 00017 00018 IndexThread::IndexThread(MWindow *mwindow, 00019 IndexFile *index_file, 00020 Asset *asset, 00021 char *index_filename, 00022 int64_t buffer_size, 00023 int64_t length_source) 00024 { 00025 this->asset = asset; 00026 this->buffer_size = buffer_size; 00027 this->length_source = length_source; 00028 this->mwindow = mwindow; 00029 this->index_filename = index_filename; 00030 this->index_file = index_file; 00031 00032 // initialize output data 00033 int64_t index_size = mwindow->preferences->index_size / 00034 sizeof(float) + 1; // size of output file in floats 00035 00036 delete [] asset->index_buffer; 00037 delete [] asset->index_offsets; 00038 delete [] asset->index_sizes; 00039 00040 // buffer used for drawing during the build. This is not deleted in the asset 00041 asset->index_buffer = new float[index_size]; 00042 // This is deleted in the asset's destructor 00043 asset->index_offsets = new int64_t[asset->channels]; 00044 asset->index_sizes = new int64_t[asset->channels]; 00045 bzero(asset->index_buffer, index_size * sizeof(float)); 00046 00047 // initialization is completed in run 00048 for(int i = 0; i < TOTAL_BUFFERS; i++) 00049 { 00050 buffer_in[i] = new double*[asset->channels]; 00051 output_lock[i] = new Condition(0, "IndexThread::output_lock"); 00052 input_lock[i] = new Condition(1, "IndexThread::input_lock"); 00053 for(int j = 0; j < asset->channels; j++) 00054 { 00055 buffer_in[i][j] = new double[buffer_size]; 00056 } 00057 } 00058 00059 interrupt_flag = 0; 00060 } 00061 00062 IndexThread::~IndexThread() 00063 { 00064 for(int i = 0; i < TOTAL_BUFFERS; i++) 00065 { 00066 for(int j = 0; j < asset->channels; j++) 00067 { 00068 delete [] buffer_in[i][j]; 00069 } 00070 delete [] buffer_in[i]; 00071 delete output_lock[i]; 00072 delete input_lock[i]; 00073 } 00074 00075 delete [] asset->index_buffer; 00076 asset->index_buffer = 0; 00077 } 00078 00079 int IndexThread::start_build() 00080 { 00081 set_synchronous(1); 00082 interrupt_flag = 0; 00083 current_buffer = 0; 00084 for(int i = 0; i < TOTAL_BUFFERS; i++) last_buffer[i] = 0; 00085 start(); 00086 } 00087 00088 int IndexThread::stop_build() 00089 { 00090 join(); 00091 } 00092 00093 void IndexThread::run() 00094 { 00095 int done = 0; 00096 00097 // current high samples in index 00098 int64_t *highpoint; 00099 // current low samples in the index 00100 int64_t *lowpoint; 00101 // position in current indexframe 00102 int64_t *frame_position; 00103 int first_point = 1; 00104 00105 highpoint = new int64_t[asset->channels]; 00106 lowpoint = new int64_t[asset->channels]; 00107 frame_position = new int64_t[asset->channels]; 00108 00109 // predict first highpoint for each channel plus padding and initialize it 00110 for(int64_t channel = 0; channel < asset->channels; channel++) 00111 { 00112 highpoint[channel] = 00113 asset->index_offsets[channel] = 00114 (length_source / asset->index_zoom * 2 + 1) * channel; 00115 lowpoint[channel] = highpoint[channel] + 1; 00116 00117 frame_position[channel] = 0; 00118 } 00119 00120 int64_t index_start = 0; // end of index during last edit update 00121 asset->index_end = 0; // samples in source completed 00122 asset->old_index_end = 0; 00123 asset->index_status = INDEX_BUILDING; 00124 int64_t zoomx = asset->index_zoom; 00125 float *index_buffer = asset->index_buffer; // output of index build 00126 00127 while(!interrupt_flag && !done) 00128 { 00129 output_lock[current_buffer]->lock("IndexThread::run"); 00130 00131 if(last_buffer[current_buffer]) done = 1; 00132 if(!interrupt_flag && !done) 00133 { 00134 // process buffer 00135 int64_t fragment_size = input_len[current_buffer]; 00136 00137 for(int channel = 0; channel < asset->channels; channel++) 00138 { 00139 int64_t *highpoint_channel = &highpoint[channel]; 00140 int64_t *lowpoint_channel = &lowpoint[channel]; 00141 int64_t *frame_position_channel = &frame_position[channel]; 00142 double *buffer_source = buffer_in[current_buffer][channel]; 00143 00144 for(int64_t i = 0; i < fragment_size; i++) 00145 { 00146 if(*frame_position_channel == zoomx) 00147 { 00148 *highpoint_channel += 2; 00149 *lowpoint_channel += 2; 00150 *frame_position_channel = 0; 00151 // store and reset output values 00152 index_buffer[*highpoint_channel] = 00153 index_buffer[*lowpoint_channel] = 00154 buffer_source[i]; 00155 asset->index_sizes[channel] = *lowpoint_channel - 00156 asset->index_offsets[channel] + 00157 1; 00158 } 00159 else 00160 { 00161 // get high and low points 00162 if(first_point) 00163 { 00164 index_buffer[*highpoint_channel] = 00165 index_buffer[*lowpoint_channel] = buffer_source[i]; 00166 first_point = 0; 00167 } 00168 else 00169 { 00170 if(buffer_source[i] > index_buffer[*highpoint_channel]) 00171 index_buffer[*highpoint_channel] = buffer_source[i]; 00172 else 00173 if(buffer_source[i] < index_buffer[*lowpoint_channel]) 00174 index_buffer[*lowpoint_channel] = buffer_source[i]; 00175 } 00176 } 00177 (*frame_position_channel)++; 00178 } // end index one buffer 00179 } 00180 00181 asset->index_end += fragment_size; 00182 00183 // draw simultaneously with build 00184 index_file->redraw_edits(0); 00185 index_start = asset->index_end; 00186 } 00187 00188 input_lock[current_buffer]->unlock(); 00189 current_buffer++; 00190 if(current_buffer >= TOTAL_BUFFERS) current_buffer = 0; 00191 } 00192 00193 index_file->redraw_edits(1); 00194 00195 00196 // write the index file to disk 00197 asset->write_index(index_filename, 00198 (lowpoint[asset->channels - 1] + 1) * sizeof(float)); 00199 00200 00201 delete [] highpoint; 00202 delete [] lowpoint; 00203 delete [] frame_position; 00204 } 00205 00206 00207
1.4.4