4 * Copyright (C) 2009 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "bcsignals.h"
25 #include "condition.h"
27 #include "edlsession.h"
29 #include "indexfile.h"
30 #include "indexstate.h"
31 #include "indexthread.h"
33 #include "maxchannels.h"
35 #include "mwindowgui.h"
36 #include "preferences.h"
37 #include "mainsession.h"
40 #include "trackcanvas.h"
43 // Read data from buffers and calculate peaks
45 IndexThread::IndexThread(MWindow *mwindow,
46 IndexFile *index_file,
49 int64_t length_source)
52 this->buffer_size = buffer_size;
53 this->length_source = length_source;
54 this->mwindow = mwindow;
55 this->index_filename = index_filename;
56 this->index_file = index_file;
58 // initialization is completed in run
59 for(int i = 0; i < TOTAL_INDEX_BUFFERS; i++)
61 // Must allocate MAX_CHANNELS for a nested EDL
62 int min_channels = MAX(MAX_CHANNELS, index_file->source_channels);
63 buffer_in[i] = new Samples*[min_channels];
64 bzero(buffer_in[i], sizeof(Samples*) * min_channels);
66 output_lock[i] = new Condition(0, "IndexThread::output_lock");
67 input_lock[i] = new Condition(1, "IndexThread::input_lock");
69 for(int j = 0; j < index_file->source_channels; j++)
71 buffer_in[i][j] = new Samples(buffer_size);
75 //printf("IndexThread::IndexThread %d\n", __LINE__);
76 //index_state->dump();
81 IndexThread::~IndexThread()
83 for(int i = 0; i < TOTAL_INDEX_BUFFERS; i++)
85 for(int j = 0; j < index_file->source_channels; j++)
87 delete buffer_in[i][j];
89 delete [] buffer_in[i];
90 delete output_lock[i];
95 void IndexThread::start_build()
99 for(int i = 0; i < TOTAL_INDEX_BUFFERS; i++) last_buffer[i] = 0;
103 void IndexThread::stop_build()
108 void IndexThread::run()
111 IndexState *index_state = index_file->get_state();
112 int index_channels = index_file->source_channels;
113 index_state->add_audio_stream(index_channels, index_file->source_length);
114 index_state->init_scan(mwindow->preferences->index_size);
115 index_state->index_status = INDEX_BUILDING;
117 while(!interrupt_flag && !done) {
118 output_lock[current_buffer]->lock("IndexThread::run");
120 if(last_buffer[current_buffer]) done = 1;
121 if(!interrupt_flag && !done) {
123 int64_t len = input_len[current_buffer];
124 for( int ch=0; ch<index_channels; ++ch ) {
125 double *samples = buffer_in[current_buffer][ch]->get_data();
126 index_state->put_data(ch,samples,len);
129 // draw simultaneously with build
130 index_file->redraw_edits(0);
133 input_lock[current_buffer]->unlock();
135 if(current_buffer >= TOTAL_INDEX_BUFFERS) current_buffer = 0;
138 index_file->redraw_edits(1);
140 // write the index file to disk
141 Asset *asset = index_file->indexable->is_asset ? (Asset*)index_file->indexable : 0;
142 index_state->create_index(index_filename, asset);