void output_special_tag(Context& ctx, std::string *out, const TreeNode& tag) { if (tag.mName == "lina:fireball") { const TreeAttribute *a1 = tag.Attrib("src"); const TreeAttribute *a2 = tag.Attrib("dst"); if (!a1 || !a2) error(ctx, "<lina:fireball> requires SRC and DST attributes"); g_fileCopies[a2->mValue] = a1->mValue; } else if (tag.mName == "lina:write") { const TreeAttribute *a = tag.Attrib("file"); if (!a) error(ctx, "<lina:write> must specify FILE"); std::string s; std::list<TreeNode *> tempStack; ctx.construction_stack.swap(tempStack); int cdataCount = ctx.cdata_count; int preCount = ctx.pre_count; ctx.cdata_count = 0; ctx.pre_count = 0; bool bHoldingSpace = ctx.holding_space; bool bEatNextSpace = ctx.eat_next_space; ctx.holding_space = false; ctx.eat_next_space = true; output_tag_contents(ctx, &s, tag); ctx.holding_space = bHoldingSpace; ctx.eat_next_space = bEatNextSpace; ctx.pre_count = cdataCount; ctx.cdata_count = preCount; ctx.construction_stack.swap(tempStack); std::string filename(create_output_filename(a->mValue)); FILE *f = fopen(filename.c_str(), "wb"); if (!f) error(ctx, "couldn't create \"%s\"", a->mValue.c_str()); fwrite(s.data(), s.length(), 1, f); fclose(f); printf("created file: %s\n", a->mValue.c_str()); } else if (tag.mName == "lina:body") { // printf("outputting:\n"); // dump_parse_tree(*ctx.invocation_stack.back(), 4); output_tag_contents(ctx, out, *ctx.invocation_stack.back()); } else if (tag.mName == "lina:tag") { const TreeAttribute *a = tag.Attrib("name"); if (!a) error(ctx, "<lina:tag> must have NAME attribute"); ctx.construction_stack.push_back(ctx.mpDocument->AllocNode()); TreeNode *new_tag = ctx.construction_stack.back(); new_tag->mpLocation = tag.mpLocation; new_tag->mLineno = tag.mLineno; new_tag->mName = a->mValue; new_tag->mbIsText = false; new_tag->mbIsControl = false; // compatibility if (!new_tag->mName.compare(0, 2, "w:")) new_tag->mName.replace(0, 2, "lina:"); output_tag_contents(ctx, NULL, tag); ctx.construction_stack.pop_back(); output_tag(ctx, out, *new_tag); } else if (tag.mName == "lina:arg") { if (!out && ctx.construction_stack.empty()) error(ctx, "<lina:arg> can only be used in an output context"); const TreeAttribute *a = tag.Attrib("name"); if (!a) error(ctx, "<lina:arg> must have NAME attribute"); if (ctx.invocation_stack.empty()) error(ctx, "<lina:arg> can only be used during macro expansion"); std::list<const TreeNode *>::const_iterator it(ctx.invocation_stack.end()); --it; int levels = 1; const char *name = a->mValue.c_str(); while(*name == '^') { ++levels; ++name; if (it == ctx.invocation_stack.begin()) error(ctx, "Number of up-scope markers in name exceeds macro nesting level"); --it; } const TreeNode& macrotag = **it; const TreeAttribute *a2 = macrotag.Attrib(name); if (!a2) error(ctx, "macro invocation <%s> does not have an attribute \"%s\"", macrotag.mName.c_str(), name); if (out) { *out += a2->mValue; ctx.eat_next_space = false; ctx.holding_space = false; } else { TreeNode *t = ctx.mpDocument->AllocNode(); t->mpLocation = tag.mpLocation; t->mLineno = tag.mLineno; t->mbIsControl = false; t->mbIsText = true; t->mName = a2->mValue; ctx.construction_stack.back()->mChildren.push_back(t); } } else if (tag.mName == "lina:if-arg") { const TreeAttribute *a = tag.Attrib("name"); if (!a) error(ctx, "<lina:if-arg> must have NAME attribute"); if (ctx.invocation_stack.empty()) error(ctx, "<lina:if-arg> can only be used during macro expansion"); const TreeNode& macrotag = *ctx.invocation_stack.back(); const TreeAttribute *a2 = macrotag.Attrib(a->mValue); if (a2) output_tag_contents(ctx, out, tag); } else if (tag.mName == "lina:if-not-arg") { const TreeAttribute *a = tag.Attrib("name"); if (!a) error(ctx, "<lina:if-not-arg> must have NAME attribute"); if (ctx.invocation_stack.empty()) error(ctx, "<lina:if-not-arg> can only be used during macro expansion"); const TreeNode& macrotag = *ctx.invocation_stack.back(); const TreeAttribute *a2 = macrotag.Attrib(a->mValue); if (!a2) output_tag_contents(ctx, out, tag); } else if (tag.mName == "lina:attrib") { if (ctx.construction_stack.empty()) error(ctx, "<lina:attrib> can only be used in a <lina:tag> element"); const TreeAttribute *a = tag.Attrib("name"); if (!a) error(ctx, "<lina:attrib> must have NAME attribute"); std::string s; std::list<TreeNode *> tempStack; ctx.construction_stack.swap(tempStack); ++ctx.cdata_count; ++ctx.pre_count; bool bHoldingSpace = ctx.holding_space; bool bEatNextSpace = ctx.eat_next_space; ctx.holding_space = false; ctx.eat_next_space = true; output_tag_contents(ctx, &s, tag); ctx.holding_space = bHoldingSpace; ctx.eat_next_space = bEatNextSpace; --ctx.pre_count; --ctx.cdata_count; ctx.construction_stack.swap(tempStack); TreeNode *t = ctx.construction_stack.back(); TreeAttribute new_att; if (tag.Attrib("novalue")) { new_att.mbNoValue = true; } else { new_att.mbNoValue = false; new_att.mValue = s; } new_att.mName = a->mValue; t->mAttribs.push_back(new_att); } else if (tag.mName == "lina:pull") { if (ctx.invocation_stack.empty()) error(ctx, "<lina:pull> can only be used during macro expansion"); const TreeAttribute *a = tag.Attrib("name"); if (!a) error(ctx, "<lina:pull> must have NAME attribute"); const TreeNode *t = ctx.find_tag(a->mValue); if (!t) error(ctx, "cannot find tag <%s> referenced in <lina:pull>", a->mValue.c_str()); output_tag_contents(ctx, out, *t); } else if (tag.mName == "lina:for-each") { const TreeAttribute *a = tag.Attrib("name"); if (!a) error(ctx, "<lina:for-each> must have NAME attribute"); std::string node_name; const TreeNode *parent; if (ctx.invocation_stack.empty()) { if (!a->mValue.empty() && a->mValue[0] == '/') parent = ctx.mpDocument->mpRoot->ResolvePath(a->mValue.substr(1), node_name); else error(ctx, "path must be absolute if not in macro context"); } else { std::list<const TreeNode *>::reverse_iterator it(ctx.invocation_stack.rbegin()), itEnd(ctx.invocation_stack.rend()); for(; it!=itEnd; ++it) { parent = (*it)->ResolvePath(a->mValue, node_name); if(parent) break; if (!a->mValue.empty() && a->mValue[0] == '/') break; } } if (!parent) error(ctx, "cannot resolve path \"%s\"", a->mValue.c_str()); std::list<TreeNode *>::const_iterator it2(parent->mChildren.begin()), it2End(parent->mChildren.end()); ctx.invocation_stack.push_back(NULL); for(; it2!=it2End; ++it2) { if ((*it2)->mName == node_name) { ctx.invocation_stack.back() = *it2; output_tag_contents(ctx, out, tag); } } ctx.invocation_stack.pop_back(); } else if (tag.mName == "lina:apply") { const TreeAttribute *a = tag.Attrib("name"); if (!a) error(ctx, "<lina:apply> must have NAME attribute"); std::map<std::string, TreeNode *>::const_iterator it(ctx.mpDocument->mMacros.find(a->mValue)); if (it == ctx.mpDocument->mMacros.end()) error(ctx, "macro \"%s\" undeclared", a->mValue.c_str()); std::list<TreeNode *>::const_iterator it2(tag.mChildren.begin()), it2End(tag.mChildren.end()); ctx.invocation_stack.push_back(NULL); for(; it2!=it2End; ++it2) { if (!(*it2)->mbIsText) { ctx.invocation_stack.back() = *it2; output_tag_contents(ctx, out, *(*it).second); } } ctx.invocation_stack.pop_back(); } else if (tag.mName == "lina:if-present") { if (ctx.invocation_stack.empty()) error(ctx, "<lina:if-present> can only be used during macro expansion"); const TreeAttribute *a = tag.Attrib("name"); if (!a) error(ctx, "<lina:if-present> must have NAME attribute"); const TreeNode *t = ctx.find_tag(a->mValue); if (t) output_tag_contents(ctx, out, tag); } else if (tag.mName == "lina:if-not-present") { if (ctx.invocation_stack.empty()) error(ctx, "<lina:if-not-present> can only be used during macro expansion"); const TreeAttribute *a = tag.Attrib("name"); if (!a) error(ctx, "<lina:if-not-present> must have NAME attribute"); const TreeNode *t = ctx.find_tag(a->mValue); if (!t) output_tag_contents(ctx, out, tag); } else if (tag.mName == "lina:pre") { ++ctx.pre_count; ++ctx.cdata_count; if (!out) output_standard_tag(ctx, out, tag); else { output_tag_contents(ctx, out, tag); } --ctx.cdata_count; --ctx.pre_count; } else if (tag.mName == "lina:cdata") { ++ctx.cdata_count; if (!out) output_standard_tag(ctx, out, tag); else output_tag_contents(ctx, out, tag); --ctx.cdata_count; } else if (tag.mName == "lina:delay") { std::list<TreeNode *>::const_iterator it(tag.mChildren.begin()), itEnd(tag.mChildren.end()); for(; it!=itEnd; ++it) { output_standard_tag(ctx, out, **it); } } else if (tag.mName == "lina:dump-stack") { dump_stack(ctx); } else if (tag.mName == "lina:replace") { const TreeAttribute *a = tag.Attrib("from"); if (!a || a->mbNoValue) error(ctx, "<lina:replace> must have FROM attribute"); const TreeAttribute *a2 = tag.Attrib("to"); if (!a2 || a2->mbNoValue) error(ctx, "<lina:replace> must have TO attribute"); const std::string& x = a->mValue; const std::string& y = a2->mValue; std::string s, t; std::string::size_type i = 0; output_tag_contents(ctx, &s, tag); for(;;) { std::string::size_type j = s.find(x, i); if (j != i) t.append(s, i, j-i); if (j == std::string::npos) break; t.append(y); i = j + x.size(); } TreeNode *new_tag = ctx.mpDocument->AllocNode(); new_tag->mpLocation = tag.mpLocation; new_tag->mLineno = tag.mLineno; new_tag->mbIsText = true; new_tag->mbIsControl = false; new_tag->mName = t; output_tag(ctx, out, *new_tag); } else if (tag.mName == "lina:set-option") { const TreeAttribute *a_name = tag.Attrib("name"); if (!a_name) error(ctx, "<lina:set-option> must have NAME attribute"); if (a_name->mValue == "link-truncate") { const TreeAttribute *a_val = tag.Attrib("baseurl"); if (!a_val || a_val->mbNoValue) error(ctx, "option \"link-truncate\" requires BASEURL attribute"); bool bTruncate = !tag.Attrib("notruncate"); g_truncateURLs.push_back(std::make_pair(a_val->mValue, bTruncate)); } else if (a_name->mValue == "output-dir") { const TreeAttribute *a_val = tag.Attrib("target"); if (!a_val || a_val->mbNoValue) error(ctx, "option \"output-dir\" requires TARGET attribute"); g_outputDir = a_val->mValue; } else if (a_name->mValue == "tag-info") { const TreeAttribute *a_tagname = tag.Attrib("tag"); if (!a_tagname || a_tagname->mbNoValue) error(ctx, "option \"tag-info\" requires TAG attribute"); const TreeAttribute *a_cdata = tag.Attrib("cdata"); if (!a_cdata || a_cdata->mbNoValue) error(ctx, "option \"tag-info\" requires CDATA attribute"); TreeNode::SetSupportsCDATA(a_tagname->mValue, is_true(a_cdata->mValue)); } else error(ctx, "option \"%s\" unknown\n", a_name->mValue.c_str()); } else if (tag.mName == "lina:data") { // do nothing } else if (tag.mName == "lina:source") { if (out) { std::list<TreeNode *>::const_iterator itBegin(tag.mChildren.begin()), it(itBegin), itEnd(tag.mChildren.end()); for(; it!=itEnd; ++it) { output_source_tags(ctx, out, **it); } } } else if (tag.mName == "lina:htmlhelp-toc") { const TreeAttribute *a_val = tag.Attrib("file"); if (!a_val || a_val->mbNoValue) error(ctx, "<lina:htmlhelp-toc> requires FILE attribute"); const std::string filename(create_output_filename(a_val->mValue)); // build new tag with TOC contents ctx.construction_stack.push_back(ctx.mpDocument->AllocNode()); TreeNode *new_tag = ctx.construction_stack.back(); new_tag->mpLocation = tag.mpLocation; new_tag->mLineno = tag.mLineno; new_tag->mName = a_val->mValue; new_tag->mbIsText = false; new_tag->mbIsControl = false; output_tag_contents(ctx, NULL, tag); ctx.construction_stack.pop_back(); output_tag(ctx, out, *new_tag); FILE *f = fopen(filename.c_str(), "wb"); if (!f) error(ctx, "couldn't create htmlhelp toc \"%s\"", a_val->mValue.c_str()); output_toc(f, *new_tag); fclose(f); } else if (tag.mName == "lina:htmlhelp-project") { const TreeAttribute *file_val = tag.Attrib("file"); if (!file_val || file_val->mbNoValue) error(ctx, "<lina:htmlhelp-project> requires FILE attribute"); const TreeAttribute *output_val = tag.Attrib("output"); if (!output_val || output_val->mbNoValue) error(ctx, "<lina:htmlhelp-project> requires OUTPUT attribute"); const TreeAttribute *toc_val = tag.Attrib("toc"); if (!toc_val || toc_val->mbNoValue) error(ctx, "<lina:htmlhelp-project> requires TOC attribute"); const TreeAttribute *title_val = tag.Attrib("title"); if (!title_val || title_val->mbNoValue) error(ctx, "<lina:htmlhelp-project> requires TITLE attribute"); const std::string filename(create_output_filename(file_val->mValue)); FILE *f = fopen(filename.c_str(), "wb"); if (!f) error(ctx, "couldn't create htmlhelp project \"%s\"", file_val->mValue.c_str()); fprintf(f, "[OPTIONS]\n" "Auto Index=Yes\n" "Compatibility=1.1 or later\n" "Compiled file=%s\n" "Contents file=%s\n" "Default topic=index.html\n" "Display compile progress=no\n" "Full-text search=Yes\n" , output_val->mValue.c_str() , toc_val->mValue.c_str() ); const TreeAttribute *fullstop_val = tag.Attrib("fullstop"); if (fullstop_val && !fullstop_val->mbNoValue) fprintf(f, "Full text search stop list file=%s\n", fullstop_val->mValue.c_str()); fprintf(f, "Language=0x0409 English (United States)\n" "Title=%s\n" "\n" "[FILES]\n" , title_val->mValue.c_str() ); std::list<std::string>::const_iterator it(g_htmlHelpFiles.begin()), itEnd(g_htmlHelpFiles.end()); for(; it!=itEnd; ++it) { fprintf(f, "%s\n", (*it).c_str()); } fclose(f); } else if (tag.mName == "lina:htmlhelp-addfile") { const TreeAttribute *file_val = tag.Attrib("file"); if (!file_val || file_val->mbNoValue) error(ctx, "<lina:htmlhelp-addfile> requires FILE attribute"); g_htmlHelpFiles.push_back(file_val->mValue); } else { std::string macroName(tag.mName, 5, std::string::npos); std::map<std::string, TreeNode *>::const_iterator it = ctx.mpDocument->mMacros.find(macroName); if (it == ctx.mpDocument->mMacros.end()) error(ctx, "macro <lina:%s> not found", macroName.c_str()); // dump_stack(ctx); // printf("executing macro: %s (%s:%d)\n", tag.mName.c_str(), tag.mLocation->name.c_str(), tag.mLineno); ctx.invocation_stack.push_back(&tag); output_tag_contents(ctx, out, *(*it).second); ctx.invocation_stack.pop_back(); // printf("exiting macro: %s (%s:%d)\n", tag.mName.c_str(), tag.mLocation->name.c_str(), tag.mLineno); } }
static bool do_join() { int i,bytes_to_skip,bytes_to_xfer; proc_info output_proc; char outfilename[FILENAME_SIZE]; wlong total=0; unsigned char header[CANONICAL_HEADER_SIZE]; FILE *output; wave_info *joined_info; bool success; progress_info proginfo; success = FALSE; create_output_filename("","",outfilename); for (i=0;i<numfiles;i++) total += files[i]->data_size; if (all_files_cd_quality && (total % CD_BLOCK_SIZE) != 0) { pad_bytes = CD_BLOCK_SIZE - (total % CD_BLOCK_SIZE); if (JOIN_NOPAD != pad_type) total += pad_bytes; } if (NULL == (joined_info = new_wave_info(NULL))) { st_error("could not allocate memory for joined file information"); } joined_info->chunk_size = total + CANONICAL_HEADER_SIZE - 8; joined_info->channels = files[0]->channels; joined_info->samples_per_sec = files[0]->samples_per_sec; joined_info->avg_bytes_per_sec = files[0]->avg_bytes_per_sec; joined_info->rate = files[0]->rate; joined_info->block_align = files[0]->block_align; joined_info->bits_per_sample = files[0]->bits_per_sample; joined_info->data_size = total; joined_info->wave_format = files[0]->wave_format; joined_info->problems = (files[0]->problems & PROBLEM_NOT_CD_QUALITY); if (PROB_ODD_SIZED_DATA(joined_info)) joined_info->chunk_size++; joined_info->total_size = joined_info->chunk_size + 8; joined_info->length = joined_info->data_size / joined_info->rate; joined_info->exact_length = (double)joined_info->data_size / (double)joined_info->rate; length_to_str(joined_info); proginfo.initialized = FALSE; proginfo.prefix = "Joining"; proginfo.clause = "-->"; proginfo.filename1 = files[0]->filename; proginfo.filedesc1 = files[0]->m_ss; proginfo.filename2 = outfilename; proginfo.filedesc2 = joined_info->m_ss; proginfo.bytes_total = files[0]->total_size; prog_update(&proginfo); if (NULL == (output = open_output_stream(outfilename,&output_proc))) { st_error("could not open output file"); } make_canonical_header(header,joined_info); if (write_n_bytes(output,header,CANONICAL_HEADER_SIZE,&proginfo) != CANONICAL_HEADER_SIZE) { prog_error(&proginfo); st_warning("error while writing %d-byte WAVE header",CANONICAL_HEADER_SIZE); goto cleanup; } if (all_files_cd_quality && (JOIN_PREPAD == pad_type) && pad_bytes) { if (pad_bytes != write_padding(output,pad_bytes,&proginfo)) { prog_error(&proginfo); st_warning("error while pre-padding with %d zero-bytes",pad_bytes); goto cleanup; } } for (i=0;i<numfiles;i++) { proginfo.bytes_total = files[i]->total_size; proginfo.filename1 = files[i]->filename; proginfo.filedesc1 = files[i]->m_ss; prog_update(&proginfo); if (!open_input_stream(files[i])) { prog_error(&proginfo); st_warning("could not reopen input file"); goto cleanup; } bytes_to_skip = files[i]->header_size; while (bytes_to_skip > 0) { bytes_to_xfer = min(bytes_to_skip,CANONICAL_HEADER_SIZE); if (read_n_bytes(files[i]->input,header,bytes_to_xfer,NULL) != bytes_to_xfer) { prog_error(&proginfo); st_warning("error while reading %d bytes of data",bytes_to_xfer); goto cleanup; } bytes_to_skip -= bytes_to_xfer; } if (transfer_n_bytes(files[i]->input,output,files[i]->data_size,&proginfo) != files[i]->data_size) { prog_error(&proginfo); st_warning("error while transferring %lu bytes of data",files[i]->data_size); goto cleanup; } prog_success(&proginfo); close_input_stream(files[i]); } if (all_files_cd_quality && JOIN_POSTPAD == pad_type && pad_bytes) { if (pad_bytes != write_padding(output,pad_bytes,NULL)) { prog_error(&proginfo); st_warning("error while post-padding with %d zero-bytes",pad_bytes); goto cleanup; } } if ((JOIN_NOPAD == pad_type) && PROB_ODD_SIZED_DATA(joined_info) && (1 != write_padding(output,1,NULL))) { prog_error(&proginfo); st_warning("error while NULL-padding odd-sized data chunk"); goto cleanup; } if (all_files_cd_quality) { if (JOIN_NOPAD != pad_type) { if (pad_bytes) st_info("%s-padded output file with %d zero-bytes.\n",((JOIN_PREPAD == pad_type)?"Pre":"Post"),pad_bytes); else st_info("No padding needed.\n"); } else { st_info("Output file was not padded, "); if (pad_bytes) st_info("though it needs %d bytes of padding.\n",pad_bytes); else st_info("nor was it needed.\n"); } } success = TRUE; cleanup: if ((CLOSE_CHILD_ERROR_OUTPUT == close_output(output,output_proc)) || !success) { success = FALSE; remove_file(outfilename); st_error("failed to join files"); } return success; }
static bool split_file(wave_info *info) { unsigned char header[CANONICAL_HEADER_SIZE]; char outfilename[FILENAME_SIZE],filenum[FILENAME_SIZE]; int current; wint discard,bytes; bool success; wlong leadin_bytes, leadout_bytes, bytes_to_xfer; progress_info proginfo; // uwe double start_time, end_time, last_end_time; success = FALSE; proginfo.initialized = FALSE; proginfo.prefix = "Splitting"; proginfo.clause = "-->"; proginfo.filename1 = info->filename; proginfo.filedesc1 = info->m_ss; proginfo.filename2 = NULL; proginfo.filedesc2 = NULL; proginfo.bytes_total = 0; if (!open_input_stream(info)) { prog_error(&proginfo); st_error("could not reopen input file: [%s]",info->filename); } discard = info->header_size; while (discard > 0) { bytes = min(discard,CANONICAL_HEADER_SIZE); if (read_n_bytes(info->input,header,bytes,NULL) != bytes) { prog_error(&proginfo); st_error("error while discarding %d-byte WAVE header",info->header_size); } discard -= bytes; } leadin_bytes = (leadin) ? smrt_parse((unsigned char *)leadin,info) : 0; leadout_bytes = (leadout) ? smrt_parse((unsigned char *)leadout,info) : 0; adjust_for_leadinout(leadin_bytes,leadout_bytes); // uwe transcription st_output("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); st_output("<Trans version=\"2\">\n\n"); start_time = end_time = last_end_time = 0; for (current=0;current<numfiles;current++) { if (SPLIT_INPUT_CUE == input_type && cueinfo.format) { create_output_filename(cueinfo.filenames[current],"",outfilename); } else { st_snprintf(filenum,8,num_format,current+offset); create_output_filename(filenum,"",outfilename); } files[current]->chunk_size = files[current]->data_size + CANONICAL_HEADER_SIZE - 8; files[current]->channels = info->channels; files[current]->samples_per_sec = info->samples_per_sec; files[current]->avg_bytes_per_sec = info->avg_bytes_per_sec; files[current]->block_align = info->block_align; files[current]->bits_per_sample = info->bits_per_sample; files[current]->wave_format = info->wave_format; files[current]->rate = info->rate; files[current]->length = files[current]->data_size / (wlong)info->rate; files[current]->exact_length = (double)files[current]->data_size / (double)info->rate; files[current]->total_size = files[current]->chunk_size + 8; length_to_str(files[current]); proginfo.filedesc2 = files[current]->m_ss; proginfo.bytes_total = files[current]->total_size; if (extract_track[current]) { proginfo.prefix = "Splitting"; proginfo.filename2 = outfilename; // uwe transcription start_time += last_end_time; end_time += files[current]->data_size / (wlong)info->rate; last_end_time = end_time; printf("<Turn startTime=\"%.2f\"", start_time); // %.2f st_output(" endTime=\"%.2f\"", end_time); st_output(" splitFilename=\"%s\"", outfilename); st_output(" speaker=\"spk1\">\n"); st_output("<Sync time=\"%.2f\"/>\n", start_time); st_output("***Include transcript words here***\n"); st_output("</Turn>\n"); if (NULL == (files[current]->output = open_output_stream(outfilename,&files[current]->output_proc))) { prog_error(&proginfo); st_error("could not open output file"); } } else { proginfo.prefix = "Skipping "; proginfo.filename2 = NULLDEVICE; if (NULL == (files[current]->output = open_output(NULLDEVICE))) { prog_error(&proginfo); st_error("while skipping track %d: could not open output file: [%s]",current+1,NULLDEVICE); } files[current]->output_proc.pid = NO_CHILD_PID; } if (PROB_ODD_SIZED_DATA(files[current])) files[current]->chunk_size++; make_canonical_header(header,files[current]); // uwe disable //prog_update(&proginfo); if (write_n_bytes(files[current]->output,header,CANONICAL_HEADER_SIZE,&proginfo) != CANONICAL_HEADER_SIZE) { prog_error(&proginfo); st_warning("error while writing %d-byte WAVE header",CANONICAL_HEADER_SIZE); goto cleanup; } /* if this is not the first file, finish up writing previous file, and simultaneously start writing to current file */ if (0 != current) { /* write overlapping lead-in/lead-out data to both previous and current files */ if (transfer_n_bytes2(info->input,files[current]->output,files[current-1]->output,leadin_bytes+leadout_bytes,&proginfo) != leadin_bytes+leadout_bytes) { prog_error(&proginfo); st_warning("error while transferring %ld bytes of lead-in/lead-out",leadin_bytes+leadout_bytes); goto cleanup; } /* pad and close previous file */ if (PROB_ODD_SIZED_DATA(files[current-1]) && (1 != write_padding(files[current-1]->output,1,&proginfo))) { prog_error(&proginfo); st_warning("error while NULL-padding odd-sized data chunk"); goto cleanup; } close_output(files[current-1]->output,files[current-1]->output_proc); } /* transfer unique non-overlapping data from input file to current file */ bytes_to_xfer = files[current]->new_data_size; if (0 != current) bytes_to_xfer -= leadout_bytes; if (numfiles - 1 != current) bytes_to_xfer -= leadin_bytes; if (transfer_n_bytes(info->input,files[current]->output,bytes_to_xfer,&proginfo) != bytes_to_xfer) { prog_error(&proginfo); st_warning("error while transferring %ld bytes of data",bytes_to_xfer); goto cleanup; } /* if this is the last file, close it */ if (numfiles - 1 == current) { /* pad and close current file */ if (PROB_ODD_SIZED_DATA(files[current]) && (1 != write_padding(files[current]->output,1,&proginfo))) { prog_error(&proginfo); st_warning("error while NULL-padding odd-sized data chunk"); goto cleanup; } close_output(files[current]->output,files[current]->output_proc); // uwe transcription st_output("</Trans>\n"); } // uwe disable // prog_success(&proginfo); } close_input_stream(info); success = TRUE; cleanup: if (!success) { close_output(files[current]->output,files[current]->output_proc); remove_file(outfilename); st_error("failed to split file"); } return success; }