+++ /dev/null
-
-/*
- * CINELERRA
- * Copyright (C) 1997-2014 Adam Williams <broadcast at earthling dot net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include "arender.h"
-#include "asset.h"
-#include "bcsignals.h"
-#include "bctimer.h"
-#include "cache.h"
-#include "clip.h"
-#include "condition.h"
-#include "edit.h"
-#include "edl.h"
-#include "edlsession.h"
-#include "errorbox.h"
-#include "file.h"
-#include "filesystem.h"
-#include "filexml.h"
-#include "format.inc"
-#include "indexable.h"
-#include "indexfile.h"
-#include "indexstate.h"
-#include "indexthread.h"
-#include "language.h"
-#include "localsession.h"
-#include "mainprogress.h"
-#include "mwindowgui.h"
-#include "mwindow.h"
-#include "preferences.h"
-#include "removefile.h"
-#include "renderengine.h"
-#include "resourcepixmap.h"
-#include "samples.h"
-#include "theme.h"
-#include "timelinepane.h"
-#include "trackcanvas.h"
-#include "tracks.h"
-#include "transportque.h"
-#include "vframe.h"
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <ctype.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <linux/iso_fs.h>
-
-// check for isofs volume_id for dvd/cdrom
-
-static int udf_volume_id(const char *path, char *fname)
-{
- struct stat st;
- if( stat(path,&st) ) return 1;
- // search mounted devices
- FILE *fp = fopen("/proc/mounts","r");
- if( !fp ) return 1;
-
- int result = 1;
- while( result && !feof(fp) && !ferror(fp) ) {
- char devpath[BCTEXTLEN], mpath[BCTEXTLEN];
- char options[BCTEXTLEN], line[BCTEXTLEN];
- char fstype[64], zero1[16], zero2[16];
- if( !fgets(&line[0], sizeof(line)-1, fp) ) break;
- int n = sscanf(&line[0], "%s %s %s %s %s %s\n",
- devpath, mpath, fstype, options, zero1, zero2);
- if( n != 6 ) continue;
- // check udf filesystems
- if( strcmp(fstype,"udf") != 0 ) continue;
- struct stat dst;
- if( stat(devpath,&dst) ) continue;
- if( st.st_dev != dst.st_rdev ) continue;
- int fd = open(devpath,O_RDONLY);
- if( fd < 0 ) continue;
- struct iso_primary_descriptor id;
- if( lseek(fd,0x8000,SEEK_SET) == 0x8000 )
- n = read(fd,&id,sizeof(id));
- close(fd);
- if( n != sizeof(id) ) continue;
- // look for magic number
- if( strncmp(ISO_STANDARD_ID,id.id,sizeof(id.id)) ) continue;
- // look for volume_id
- if( !isalnum(id.volume_id[0]) ) continue;
- char *bp = &id.volume_id[0], *cp = fname;
- for( int i=0; i<(int)sizeof(id.volume_id); ++i ) *cp++ = *bp++;
- while( --cp>=fname && *cp==' ' ) *cp = 0;
- if( !*fname ) continue;
- // fname = volume_id _ creation_date
- ++cp; *cp++ = '_'; bp = &id.creation_date[0];
- for( int i=0; i<(int)sizeof(id.creation_date)-1; ++i ) {
- if( !isdigit(*bp) ) break;
- *cp++ = *bp++;
- }
- *cp++ = 0;
- if( cp-fname > 4 ) result = 0;
- }
-
- fclose(fp);
- return result;
-}
-
-// Use native sampling rates for files so the same index can be used in
-// multiple projects.
-
-IndexFile::IndexFile(MWindow *mwindow)
-{
-//printf("IndexFile::IndexFile 1\n");
- reset();
- this->mwindow = mwindow;
-//printf("IndexFile::IndexFile 2\n");
- redraw_timer = new Timer;
-}
-
-IndexFile::IndexFile(MWindow *mwindow,
- Indexable *indexable)
-{
-//printf("IndexFile::IndexFile 2\n");
- reset();
- this->mwindow = mwindow;
- this->indexable = indexable;
- redraw_timer = new Timer;
-
- if(indexable)
- {
- indexable->add_user();
- source_channels = indexable->get_audio_channels();
- source_samplerate = indexable->get_sample_rate();
- source_length = indexable->get_audio_samples();
- }
-}
-
-IndexFile::~IndexFile()
-{
-//printf("IndexFile::~IndexFile 1\n");
- delete redraw_timer;
- if(indexable) indexable->remove_user();
- close_source();
-}
-
-void IndexFile::reset()
-{
- fd = 0;
- source = 0;
- interrupt_flag = 0;
- source_length = 0;
- source_channels = 0;
- indexable = 0;
- render_engine = 0;
- cache = 0;
-}
-
-IndexState* IndexFile::get_state()
-{
- IndexState *index_state = 0;
- if(indexable) index_state = indexable->index_state;
- return index_state;
-}
-
-
-
-int IndexFile::open_index()
-{
- IndexState *index_state = 0;
- int result = 0;
-
-// use buffer if being built
- index_state = get_state();
-
- if(index_state->index_status == INDEX_BUILDING)
- {
-// use buffer
- result = 0;
- }
- else
- if(!(result = open_file()))
- {
-// opened existing file
- if(read_info())
- {
- result = 1;
- close_index();
- }
- else
- {
- index_state->index_status = INDEX_READY;
- }
- }
- else
- {
- result = 1;
- }
-
- return result;
-}
-
-void IndexFile::delete_index(Preferences *preferences,
- Indexable *indexable, const char *suffix)
-{
- char index_filename[BCTEXTLEN];
- char source_filename[BCTEXTLEN];
- const char *path = indexable->path;
-
- get_index_filename(source_filename,
- preferences->index_directory,
- index_filename, path, suffix);
-//printf("IndexFile::delete_index %s %s\n", source_filename, index_filename);
- remove_file(index_filename);
-}
-
-int IndexFile::open_file()
-{
- int result = 0;
- const int debug = 0;
- const char *path = indexable->path;
-
-
-//printf("IndexFile::open_file %f\n", indexable->get_frame_rate());
-
- get_index_filename(source_filename,
- mwindow->preferences->index_directory,
- index_filename,
- path);
-
- if(debug) printf("IndexFile::open_file %d index_filename=%s\n",
- __LINE__,
- index_filename);
- fd = fopen(index_filename, "rb");
- if( fd != 0 )
- {
-// Index file already exists.
-// Get its last size without changing the real asset status.
- Indexable *test_indexable = new Indexable(0);
- if(indexable)
- test_indexable->copy_indexable(indexable);
- read_info(test_indexable);
- IndexState *index_state = test_indexable->index_state;
-
- FileSystem fs;
- if(fs.get_date(index_filename) < fs.get_date(test_indexable->path))
- {
- if(debug) printf("IndexFile::open_file %d index_date=" _LD " source_date=" _LD "\n",
- __LINE__,
- fs.get_date(index_filename),
- fs.get_date(test_indexable->path));
-
-// index older than source
- result = 2;
- fclose(fd);
- fd = 0;
- }
- else
- if(fs.get_size(test_indexable->path) != index_state->index_bytes)
- {
-// source file is a different size than index source file
- if(debug) printf("IndexFile::open_file %d index_size=" _LD " source_size=" _LD "\n",
- __LINE__,
- index_state->index_bytes,
- fs.get_size(test_indexable->path));
- result = 2;
- fclose(fd);
- fd = 0;
- }
- else
- {
- if(debug) printf("IndexFile::open_file %d\n",
- __LINE__);
- fseek(fd, 0, SEEK_END);
- file_length = ftell(fd);
- fseek(fd, 0, SEEK_SET);
- result = 0;
- }
- test_indexable->Garbage::remove_user();
- }
- else
- {
-// doesn't exist
- if(debug) printf("IndexFile::open_file %d index_filename=%s doesn't exist\n",
- __LINE__,
- index_filename);
- result = 1;
- }
-
- return result;
-}
-
-int IndexFile::open_source()
-{
-//printf("IndexFile::open_source %p %s\n", asset, asset->path);
- int result = 0;
- if(indexable && indexable->is_asset)
- {
- if(!source) source = new File;
-
- Asset *asset = (Asset*)indexable;
- if(source->open_file(mwindow->preferences,
- asset, 1, 0))
- {
- //printf("IndexFile::open_source() Couldn't open %s.\n", asset->path);
- result = 1;
- }
- else
- {
- FileSystem fs;
- asset->index_state->index_bytes = fs.get_size(asset->path);
- source_length = source->get_audio_length();
- }
- }
- else
- {
- TransportCommand command;
- command.command = NORMAL_FWD;
- command.get_edl()->copy_all((EDL*)indexable);
- command.change_type = CHANGE_ALL;
- command.realtime = 0;
- cache = new CICache(mwindow->preferences);
- render_engine = new RenderEngine(0,
- mwindow->preferences, 0, 0, 0);
- render_engine->set_acache(cache);
- render_engine->arm_command(&command);
- FileSystem fs;
- indexable->index_state->index_bytes = fs.get_size(indexable->path);
- }
-
- return result;
-}
-
-void IndexFile::close_source()
-{
- delete source;
- source = 0;
-
- delete render_engine;
- render_engine = 0;
-
- delete cache;
- cache = 0;
-}
-
-int64_t IndexFile::get_required_scale()
-{
- int64_t result = 1;
-
-
-// get scale of index file
-// Total peaks which may be stored in buffer
- int64_t peak_count = mwindow->preferences->index_size /
- (2 * sizeof(float) * source_channels);
- for(result = 1;
- source_length / result > peak_count;
- result *= 2)
- ;
-
-// Takes too long to draw from source on a CDROM. Make indexes for
-// everything.
-
- return result;
-}
-
-int IndexFile::get_index_filename(char *source_filename,
- char *index_directory,
- char *index_filename,
- const char *input_filename,
- const char *suffix)
-{
- const char *input_fn = input_filename;
- char volume_id[BCTEXTLEN];
-// Replace mount/directory with volume_id if isofs
- if( !udf_volume_id(input_filename, volume_id) )
- {
- char *cp = strrchr((char*)input_filename,'/');
- if( cp ) input_fn = cp + 1;
- for( cp=volume_id; *cp; ++cp );
- *cp++ = '_'; strcpy(cp, input_fn);
- input_fn = volume_id;
- }
-// Replace slashes and dots
- int i, j;
- int len = strlen(input_fn);
- for(i = 0, j = 0; i < len; i++)
- {
- if(input_fn[i] != '/' &&
- input_fn[i] != '.')
- source_filename[j++] = input_fn[i];
- else
- {
- if(i > 0)
- source_filename[j++] = '_';
- }
- }
- source_filename[j] = 0;
- FileSystem fs;
- fs.join_names(index_filename, index_directory, source_filename);
- strcat(index_filename, suffix ? suffix : ".idx");
- return 0;
-}
-
-int IndexFile::interrupt_index()
-{
- interrupt_flag = 1;
- return 0;
-}
-
-// Read data into buffers
-
-int IndexFile::create_index(MainProgressBar *progress)
-{
- int result = 0;
-SET_TRACE
-
- interrupt_flag = 0;
-
-// open the source file
- if(open_source()) return 1;
-
-SET_TRACE
-
- get_index_filename(source_filename,
- mwindow->preferences->index_directory,
- index_filename,
- indexable->path);
-
-SET_TRACE
-
-// Some file formats have their own sample index.
-// Test for index in stream table of contents
- if(source && !source->get_index(index_filename))
- {
- IndexState *index_state = get_state();
- index_state->index_status = INDEX_READY;
- redraw_edits(1);
- }
- else
-// Build index from scratch
- {
-SET_TRACE
-
-// Indexes are now built for everything since it takes too long to draw
-// from CDROM source.
-
-// get amount to read at a time in floats
- int64_t buffersize = 65536;
- char string[BCTEXTLEN];
- sprintf(string, _("Creating %s."), index_filename);
-
- progress->update_title(string);
- progress->update_length(source_length);
- redraw_timer->update();
-SET_TRACE
-
-// thread out index thread
- IndexThread *index_thread = new IndexThread(mwindow,
- this,
- index_filename,
- buffersize,
- source_length);
- index_thread->start_build();
-
-// current sample in source file
- int64_t position = 0;
- int64_t fragment_size = buffersize;
- int current_buffer = 0;
-
-
-// pass through file once
-// printf("IndexFile::create_index %d source_length=" _LD " source=%p progress=%p\n",
-// __LINE__,
-// source_length,
-// source,
-// progress);
-SET_TRACE
- while(position < source_length && !result)
- {
-SET_TRACE
- if(source_length - position < fragment_size && fragment_size == buffersize) fragment_size = source_length - position;
-
- index_thread->input_lock[current_buffer]->lock("IndexFile::create_index 1");
- index_thread->input_len[current_buffer] = fragment_size;
-
-SET_TRACE
- int cancelled = progress->update(position);
-//printf("IndexFile::create_index cancelled=%d\n", cancelled);
-SET_TRACE
- if(cancelled ||
- index_thread->interrupt_flag ||
- interrupt_flag)
- {
- result = 3;
- }
-
-
-SET_TRACE
- if(source && !result)
- {
-SET_TRACE
- for(int channel = 0;
- !result && channel < source_channels;
- channel++)
- {
-// Read from source file
- source->set_audio_position(position);
- source->set_channel(channel);
-
- if(source->read_samples(
- index_thread->buffer_in[current_buffer][channel],
- fragment_size))
- result = 1;
- }
-SET_TRACE
- }
- else
- if(render_engine && !result)
- {
-SET_TRACE
- if(render_engine->arender)
- {
- result = render_engine->arender->process_buffer(
- index_thread->buffer_in[current_buffer],
- fragment_size,
- position);
- }
- else
- {
- for(int i = 0; i < source_channels; i++)
- {
- bzero(index_thread->buffer_in[current_buffer][i]->get_data(),
- fragment_size * sizeof(double));
- }
- }
-SET_TRACE
- }
-SET_TRACE
-
-// Release buffer to thread
- if(!result)
- {
- index_thread->output_lock[current_buffer]->unlock();
- current_buffer++;
- if(current_buffer >= TOTAL_INDEX_BUFFERS) current_buffer = 0;
- position += fragment_size;
- }
- else
- {
- index_thread->input_lock[current_buffer]->unlock();
- }
-SET_TRACE
- }
-
-
-// end thread cleanly
- index_thread->input_lock[current_buffer]->lock("IndexFile::create_index 2");
- index_thread->last_buffer[current_buffer] = 1;
- index_thread->output_lock[current_buffer]->unlock();
- index_thread->stop_build();
-
-
- delete index_thread;
-
- }
-
-
-
- close_source();
-
-
-
- open_index();
-
- close_index();
-
- mwindow->edl->set_index_file(indexable);
- return 0;
-}
-
-
-
-int IndexFile::redraw_edits(int force)
-{
- int64_t difference = redraw_timer->get_scaled_difference(1000);
-
- if(difference > 250 || force)
- {
- redraw_timer->update();
- mwindow->gui->lock_window("IndexFile::redraw_edits");
- mwindow->edl->set_index_file(indexable);
- mwindow->gui->draw_indexes(indexable);
- mwindow->gui->unlock_window();
- }
- return 0;
-}
-
-
-
-
-int IndexFile::draw_index(
- TrackCanvas *canvas,
- ResourcePixmap *pixmap,
- Edit *edit,
- int x,
- int w)
-{
- const int debug = 0;
- IndexState *index_state = get_state();
- int pane_number = canvas->pane->number;
-//index_state->dump();
-
-SET_TRACE
- if(debug) printf("IndexFile::draw_index %d\n", __LINE__);
- if(index_state->index_zoom == 0)
- {
- printf(_("IndexFile::draw_index: index has 0 zoom\n"));
- return 0;
- }
- if(debug) printf("IndexFile::draw_index %d\n", __LINE__);
-
-// test channel number
- if(edit->channel > source_channels) return 1;
- if(debug) printf("IndexFile::draw_index %d source_samplerate=%d "
- "w=%d samplerate=" _LD " zoom_sample=" _LD "\n",
- __LINE__, source_samplerate, w,
- mwindow->edl->session->sample_rate,
- mwindow->edl->local_session->zoom_sample);
-
-// calculate a virtual x where the edit_x should be in floating point
- double virtual_edit_x = 1.0 *
- edit->track->from_units(edit->startproject) *
- mwindow->edl->session->sample_rate /
- mwindow->edl->local_session->zoom_sample -
- mwindow->edl->local_session->view_start[pane_number];
-
-// samples in segment to draw relative to asset
- double asset_over_session = (double)source_samplerate /
- mwindow->edl->session->sample_rate;
- int64_t startsource = (int64_t)(((pixmap->pixmap_x - virtual_edit_x + x) *
- mwindow->edl->local_session->zoom_sample +
- edit->startsource) *
- asset_over_session);
-// just in case we get a numerical error
- if (startsource < 0) startsource = 0;
- int64_t length = (int64_t)(w *
- mwindow->edl->local_session->zoom_sample *
- asset_over_session);
- int64_t lengthindex = length / index_state->index_zoom * 2;
- int64_t startindex = startsource / index_state->index_zoom * 2;
-// length of index to read in floats
-// length of index available in floats
- int64_t endindex = index_state->index_status == INDEX_BUILDING ?
- index_state->get_channel_used(edit->channel) * 2 :
- index_state->get_index_size(edit->channel);
-// Clamp length of index to read by available data
- if(startindex + lengthindex >= endindex )
- lengthindex = endindex - startindex;
- if( lengthindex <= 0 ) return 0;
-
-// Actual length read from file in bytes
- int64_t length_read;
-// Start and length of fragment to read from file in bytes.
- int64_t startfile, lengthfile;
- float *buffer = 0;
- int buffer_shared = 0;
- int center_pixel = mwindow->edl->local_session->zoom_track / 2;
- if( mwindow->edl->session->show_titles )
- center_pixel += mwindow->theme->get_image("title_bg_data")->get_h();
- //int miny = center_pixel - mwindow->edl->local_session->zoom_track / 2;
- //int maxy = center_pixel + mwindow->edl->local_session->zoom_track / 2;
- int x1 = 0, y1, y2;
-// get zoom_sample relative to index zoomx
- double index_frames_per_pixel = mwindow->edl->local_session->zoom_sample /
- index_state->index_zoom *
- asset_over_session;
-
-
-
- if(index_state->index_status == INDEX_BUILDING)
- {
-// index is in RAM, being built
- buffer = index_state->get_channel_buffer(edit->channel);
- if( !buffer ) return 0;
- buffer += startindex;
- buffer_shared = 1;
- }
- else
- {
-// add channel offset
- startindex += index_state->get_index_offset(edit->channel);
-// index is stored in a file
- buffer = new float[lengthindex + 1];
- buffer_shared = 0;
- startfile = index_state->index_start + startindex * sizeof(float);
- lengthfile = lengthindex * sizeof(float);
- length_read = 0;
-
- if(startfile < file_length)
- {
- fseek(fd, startfile, SEEK_SET);
-
- length_read = lengthfile;
- if(startfile + length_read > file_length)
- length_read = file_length - startfile;
-
- (void)fread(buffer, length_read + sizeof(float), 1, fd);
- }
-
- if(length_read < lengthfile) {
- int pos = length_read / sizeof(float);
- int file_length = lengthfile / sizeof(float);
- while( pos < file_length ) buffer[pos++] = 0;
- }
- }
-
- canvas->set_color(mwindow->theme->audio_color);
-
- double current_frame = 0;
- float highsample = buffer[0];
- float lowsample = buffer[1];
- int prev_y1 = center_pixel;
- int prev_y2 = center_pixel;
- int first_frame = 1;
- int zoom_y = mwindow->edl->local_session->zoom_y, zoom_y2 = zoom_y / 2;
- int max_y = canvas->get_h();
- int zmax_y = center_pixel + zoom_y2 - 1;
- if( zmax_y < max_y ) max_y = zmax_y;
-SET_TRACE
-
- for(int bufferposition = 0;
- bufferposition < lengthindex;
- bufferposition += 2)
- {
- if(current_frame >= index_frames_per_pixel)
- {
-
- int y1 = (int)(center_pixel - highsample * zoom_y2);
- int y2 = (int)(center_pixel - lowsample * zoom_y2);
- CLAMP(y1, 0, max_y); int next_y1 = y1;
- CLAMP(y2, 0, max_y); int next_y2 = y2;
-//printf("draw_line (%f,%f) = %d,%d, %d,%d\n", lowsample, highsample, x1 + x, y1, x1 + x, y2);
-
-//SET_TRACE
-// A different algorithm has to be used if it's 1 sample per pixel and the
-// index is used. Now the min and max values are equal so we join the max samples.
- if(mwindow->edl->local_session->zoom_sample == 1)
- {
- canvas->draw_line(x1 + x - 1, prev_y1, x1 + x, y1, pixmap);
- }
- else
- {
-// Extend line height if it doesn't connect to previous line
- if(!first_frame)
- {
- if(y1 > prev_y2) y1 = prev_y2 + 1;
- if(y2 < prev_y1) y2 = prev_y1 - 1;
- }
- else
- {
- first_frame = 0;
- }
-
-
-
- canvas->draw_line(x1 + x, y1, x1 + x, y2, pixmap);
- }
- current_frame -= index_frames_per_pixel;
- x1++;
- prev_y1 = next_y1;
- prev_y2 = next_y2;
- highsample = buffer[bufferposition];
- lowsample = buffer[bufferposition + 1];
- }
-
- current_frame++;
- highsample = MAX(highsample, buffer[bufferposition]);
- lowsample = MIN(lowsample, buffer[bufferposition + 1]);
- }
-SET_TRACE
-
-// Get last column
- if(current_frame)
- {
- y1 = (int)(center_pixel - highsample * zoom_y2);
- y2 = (int)(center_pixel - lowsample * zoom_y2);
- canvas->draw_line(x1 + x, y1, x1 + x, y2, pixmap);
- }
-
-SET_TRACE
-
-
-
- if(!buffer_shared) delete [] buffer;
-SET_TRACE
- if(debug) printf("IndexFile::draw_index %d\n", __LINE__);
- return 0;
-}
-
-int IndexFile::close_index()
-{
- if(fd)
- {
- fclose(fd);
- fd = 0;
- }
- return 0;
-}
-
-int IndexFile::remove_index()
-{
- IndexState *index_state = get_state();
- if(index_state->index_status == INDEX_READY ||
- index_state->index_status == INDEX_NOTTESTED)
- {
- close_index();
- remove(index_filename);
- }
- return 0;
-}
-
-int IndexFile::read_info(Indexable *test_indexable)
-{
- const int debug = 0;
-
-// Store format in actual asset.
-// If it's a nested EDL, we never want the format, just the index info.
- if(!test_indexable) test_indexable = indexable;
- if(!test_indexable) return 1;
-
- IndexState * index_state = test_indexable->index_state;
- if(index_state->index_status == INDEX_NOTTESTED)
- {
-// read start of index data
- int temp = fread((char*)&(index_state->index_start), sizeof(int64_t), 1, fd);
-//printf("IndexFile::read_info %d %f\n", __LINE__, test_indexable->get_frame_rate());
-
- if(!temp) return 1;
-// read test_indexable info from index
- char *data;
-
- data = new char[index_state->index_start];
- temp = fread(data, index_state->index_start - sizeof(int64_t), 1, fd);
- if(!temp) return 1;
-
- data[index_state->index_start - sizeof(int64_t)] = 0;
- FileXML xml;
- xml.read_from_string(data);
- delete [] data;
-
-
-
-// Read the file format & index state.
- if(test_indexable->is_asset)
- {
- Asset *asset = (Asset*)test_indexable;
- asset->read(&xml);
-
-//printf("IndexFile::read_info %d %f\n", __LINE__, asset->get_frame_rate());
-
- if(asset->format == FILE_UNKNOWN)
- {
-if(debug) printf("IndexFile::read_info %d\n", __LINE__);
- return 1;
- }
- }
- else
- {
-// Read only the index state for a nested EDL
- int result = 0;
-if(debug) printf("IndexFile::read_info %d\n", __LINE__);
- while(!result)
- {
- result = xml.read_tag();
- if(!result)
- {
- if(xml.tag.title_is("INDEX"))
- {
- index_state->read_xml(&xml, source_channels);
-if(debug) printf("IndexFile::read_info %d\n", __LINE__);
-if(debug) index_state->dump();
- result = 1;
- }
- }
- }
- }
- }
-
- return 0;
-}
-
-
-
-
-
-
-
-