Beispiel #1
0
/*
 * Quartett to mod converter
 *   03.02.2000 by Settel
 */


// Includes /*fold00*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <math.h>
#include "pattern.h"
#include "voice.h"
#include "common.h"
#include "mod.h"

// Defines /*fold00*/
#define BASEFREQ 0x879c
#define SAMPLESTRETCH 0.95
#define SPEED 0x80

#define PITCH_TOO_LOW    0x10000
#define PITCH_TOO_HIGH   0x20000
#define VOICE_MAP_LOWER  0x100
#define VOICE_MAP_HIGHER 0x200

// Globals /*fold00*/
char *pattern_buf=NULL;
char *voices_buf=NULL;
int pattern_buf_len=0;
int voices_buf_len=0;
struct channel chan[4];

int min_step_width=1<<16;
int num_steps=0;

int mod_patterns_num=0;
char *mod_patterns_buf=NULL;

struct sample samples[20];
int voice_map[31|VOICE_MAP_HIGHER|VOICE_MAP_LOWER];
int voice_rev_map[31];

int mod_pitch_tab[36];

// init_mod_pitch_tab /*fold00*/
void init_mod_pitch_tab(){
#if 1
   int i;
   for(i=0;i<36;i++) mod_pitch_tab[i]=freqtab[i];
#else
   int i;
   double c=exp(log(2)/12.0);

   char buf[4096];
   int fd;

   fd=open("freq.mod",O_RDONLY);
   if(fd<0){
      perror("open()");
      exit(1);
   }
   read(fd,buf,sizeof(buf));
   close(fd);

   for(i=0;i<36;i++) mod_pitch_tab[i]=(int)((856.0/pow(c,i))+0.5);

   for(i=0;i<36;i++){
      fd=X32(*((unsigned long *)(buf+i*16+1084)));
      fd>>=16;
      fd&=0x7FFF;
      printf("%2i: %3i <-> %3i  (%3i)\n",i,mod_pitch_tab[i],fd,mod_pitch_tab[i]-fd);

   }
#endif
}

// read_4v /*fold00*/
void read_4v(char *name){
   int fd;
   struct stat stat_buf;
   int len;

   if(stat(name,&stat_buf)){
      perror("stat()");
      exit(1);
   }
   pattern_buf_len=stat_buf.st_size;
   pattern_buf=(char *)malloc(pattern_buf_len);
   if(!pattern_buf){
      pattern_buf_len=0;
      perror("malloc()");
      exit(1);
   }

   fd=open(name,O_RDONLY);
   if(fd<0){
      perror("open()");
      exit(1);
   }

   len=read(fd,pattern_buf,pattern_buf_len);
   if(len<0){
      perror("read()");
      exit(1);
   }else if(len!=pattern_buf_len){
      fprintf(stderr,"read incomplete\n");
      exit(1);
   }

   close(fd);
}

// read_set /*fold00*/
void read_set(char *name){
   int fd;
   struct stat stat_buf;
   int len;

   if(stat(name,&stat_buf)){
      perror("stat()");
      exit(1);
   }
   voices_buf_len=stat_buf.st_size;
   voices_buf=(char *)malloc(voices_buf_len+32768);
   if(!voices_buf){
      voices_buf_len=0;
      perror("malloc()");
      exit(1);
   }

   fd=open(name,O_RDONLY);
   if(fd<0){
      perror("open()");
      exit(1);
   }

   len=read(fd,voices_buf,voices_buf_len);
   if(len<0){
      perror("read()");
      exit(1);
   }else if(len!=voices_buf_len){
      fprintf(stderr,"read incomplete\n");
      exit(1);
   }

   close(fd);
}

// dump_channel /*fold00*/
void dump_channel(int i){
   struct note *note;

   for(note=chan[i].start;note<chan[i].end;note++){
      printf(" %3i:  %c %5i %08lx %08lx\n",note-chan[i].start,
             note->cmd,note->delay,
             note->val1,note->val2);
   }
}

// preprocess_4v /*fold00*/
void preprocess_4v(){
   int i;
   struct note *note;

   note=(struct note*)(pattern_buf+16);
   for(i=0;i<4;i++){
      printf("process channel %i: ",i);
      chan[i].start=note;
      while(1){
         note->cmd=X16(note->cmd);
         note->delay=X16(note->delay);
         note->val1=X32(note->val1);
         note->val2=X32(note->val2);

         switch(note->cmd){
         case NOTE_LOOPSTART:
         case NOTE_LOOPEND:
         case NOTE_VOICE:
            note->delay=0;
            break;
         }

         if(note->cmd==NOTE_END) break;
         note++;
      }
      chan[i].end=note;
      note++;
      printf("length %i\n",chan[i].end-chan[i].start);

   }
}
Beispiel #2
0
/*
 * Quartett to mod converter
 *   03.02.2000 by Settel
 */


// Includes /*fold00*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <math.h>
#include "pattern.h"
#include "voice.h"
#include "common.h"
#include "mod.h"

// Defines /*fold00*/
#define BASEFREQ 0x879c
#define SAMPLESTRETCH 0.95
#define SPEED 0x80

#define PITCH_TOO_LOW    0x10000
#define PITCH_TOO_HIGH   0x20000
#define VOICE_MAP_LOWER  0x100
#define VOICE_MAP_HIGHER 0x200

// Globals /*fold00*/
char *pattern_buf=NULL;
char *voices_buf=NULL;
int pattern_buf_len=0;
int voices_buf_len=0;
struct channel chan[4];

int min_step_width=1<<16;
int num_steps=0;

int mod_patterns_num=0;
char *mod_patterns_buf=NULL;

struct sample samples[20];
int voice_map[31|VOICE_MAP_HIGHER|VOICE_MAP_LOWER];
int voice_rev_map[31];

int mod_pitch_tab[36];

// init_mod_pitch_tab /*fold00*/
void init_mod_pitch_tab(){
#if 1
   int i;
   for(i=0;i<36;i++) mod_pitch_tab[i]=freqtab[i];
#else
   int i;
   double c=exp(log(2)/12.0);

   char buf[4096];
   int fd;

   fd=open("freq.mod",O_RDONLY);
   if(fd<0){
      perror("open()");
      exit(1);
   }
   read(fd,buf,sizeof(buf));
   close(fd);

   for(i=0;i<36;i++) mod_pitch_tab[i]=(int)((856.0/pow(c,i))+0.5);

   for(i=0;i<36;i++){
      fd=X32(*((unsigned long *)(buf+i*16+1084)));
      fd>>=16;
      fd&=0x7FFF;
      printf("%2i: %3i <-> %3i  (%3i)\n",i,mod_pitch_tab[i],fd,mod_pitch_tab[i]-fd);

   }
#endif
}

// read_4v /*fold00*/
void read_4v(char *name){
   int fd;
   struct stat stat_buf;
   int len;

   if(stat(name,&stat_buf)){
      perror("stat()");
      exit(1);
   }
   pattern_buf_len=stat_buf.st_size;
   pattern_buf=(char *)malloc(pattern_buf_len);
   if(!pattern_buf){
      pattern_buf_len=0;
      perror("malloc()");
      exit(1);
   }

   fd=open(name,O_RDONLY);
   if(fd<0){
      perror("open()");
      exit(1);
   }

   len=read(fd,pattern_buf,pattern_buf_len);
   if(len<0){
      perror("read()");
      exit(1);
   }else if(len!=pattern_buf_len){
      fprintf(stderr,"read incomplete\n");
      exit(1);
   }

   close(fd);
}

// read_set /*fold00*/
void read_set(char *name){
   int fd;
   struct stat stat_buf;
   int len;

   if(stat(name,&stat_buf)){
      perror("stat()");
      exit(1);
   }
   voices_buf_len=stat_buf.st_size;
   voices_buf=(char *)malloc(voices_buf_len+32768);
   if(!voices_buf){
      voices_buf_len=0;
      perror("malloc()");
      exit(1);
   }

   fd=open(name,O_RDONLY);
   if(fd<0){
      perror("open()");
      exit(1);
   }

   len=read(fd,voices_buf,voices_buf_len);
   if(len<0){
      perror("read()");
      exit(1);
   }else if(len!=voices_buf_len){
      fprintf(stderr,"read incomplete\n");
      exit(1);
   }

   close(fd);
}

// dump_channel /*fold00*/
void dump_channel(int i){
   struct note *note;

   for(note=chan[i].start;note<chan[i].end;note++){
      printf(" %3i:  %c %5i %08lx %08lx\n",note-chan[i].start,
             note->cmd,note->delay,
             note->val1,note->val2);
   }
}

// preprocess_4v /*fold00*/
void preprocess_4v(){
   int i;
   struct note *note;

   note=(struct note*)(pattern_buf+16);
   for(i=0;i<4;i++){
      printf("process channel %i: ",i);
      chan[i].start=note;
      while(1){
         note->cmd=X16(note->cmd);
         note->delay=X16(note->delay);
         note->val1=X32(note->val1);
         note->val2=X32(note->val2);

         switch(note->cmd){
         case NOTE_LOOPSTART:
         case NOTE_LOOPEND:
         case NOTE_VOICE:
            note->delay=0;
            break;
         }

         if(note->cmd==NOTE_END) break;
         note++;
      }
      chan[i].end=note;
      note++;
      printf("length %i\n",chan[i].end-chan[i].start);

   }
}

// preprocess_set /*fold00*/
void preprocess_set(){
   int i,j;
   struct setheader *setheader=(struct setheader *)voices_buf;
   unsigned long *offset;

   memset(voice_map,-1,sizeof(voice_map));
   memset(voice_rev_map,-1,sizeof(voice_rev_map));
   memset(samples,0,sizeof(samples));
   for(i=0;i<20;i++){
      strncpy(samples[i].name,setheader->name[i],6);
      offset=(unsigned long *)setheader->offset;
      offset+=i;
      samples[i].descr=(struct sam_descr *)(voices_buf+X32(*offset));
      if(X32(*offset)==0 || ((char *)samples[i].descr)+8>voices_buf+voices_buf_len){
         samples[i].descr=NULL;
         samples[i].start=NULL;
         samples[i].len=0;
         samples[i].repstart=0;
         samples[i].replen=0;
         voice_map[i]=-1;
      }else{
         voice_map[i]=i;
         voice_rev_map[i]=i;
         samples[i].start=voices_buf+X32(*offset)+8;
         samples[i].len=X16(samples[i].descr->len)&0x7FFF;
         samples[i].repstart=(X16(samples[i].descr->len)&0x7FFF)-
            (X16(samples[i].descr->replen)&0x7FFF);
         samples[i].replen=X16(samples[i].descr->replen)&0x7FFF;

         for(j=0;j<i;j++){
            if(samples[j].descr==samples[i].descr){
               samples[i].descr=NULL;
               samples[i].start=NULL;
               samples[i].len=0;
               samples[i].repstart=0;
               samples[i].replen=0;

               voice_map[i]=j;
               voice_rev_map[i]=-1;
               break;
            }
         }
      }
      printf("sam %2i: mapped to %2i,",i,voice_map[i]);
      if(voice_map[i]>=0){
         printf(" \"%6s\", %6i\n",samples[voice_map[i]].name,samples[voice_map[i]].len);
      }else{
         printf("\n");
      }
   }
}
Beispiel #3
0
/*
 * Quartett to mod converter
 *   03.02.2000 by Settel
 */


// Includes /*fold00*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <math.h>
#include "pattern.h"
#include "voice.h"
#include "common.h"
#include "mod.h"

// Defines /*fold00*/
#define BASEFREQ 0x879c
#define SAMPLESTRETCH 0.95
#define SPEED 0x80

#define PITCH_TOO_LOW    0x10000
#define PITCH_TOO_HIGH   0x20000
#define VOICE_MAP_LOWER  0x100
#define VOICE_MAP_HIGHER 0x200

// Globals /*fold00*/
char *pattern_buf=NULL;
char *voices_buf=NULL;
int pattern_buf_len=0;
int voices_buf_len=0;
struct channel chan[4];

int min_step_width=1<<16;
int num_steps=0;

int mod_patterns_num=0;
char *mod_patterns_buf=NULL;

struct sample samples[20];
int voice_map[31|VOICE_MAP_HIGHER|VOICE_MAP_LOWER];
int voice_rev_map[31];

int mod_pitch_tab[36];

// init_mod_pitch_tab /*fold00*/
void init_mod_pitch_tab(){
#if 1
   int i;
   for(i=0;i<36;i++) mod_pitch_tab[i]=freqtab[i];
#else
   int i;
   double c=exp(log(2)/12.0);

   char buf[4096];
   int fd;

   fd=open("freq.mod",O_RDONLY);
   if(fd<0){
      perror("open()");
      exit(1);
   }
   read(fd,buf,sizeof(buf));
   close(fd);

   for(i=0;i<36;i++) mod_pitch_tab[i]=(int)((856.0/pow(c,i))+0.5);

   for(i=0;i<36;i++){
      fd=X32(*((unsigned long *)(buf+i*16+1084)));
      fd>>=16;
      fd&=0x7FFF;
      printf("%2i: %3i <-> %3i  (%3i)\n",i,mod_pitch_tab[i],fd,mod_pitch_tab[i]-fd);

   }
#endif
}
Beispiel #4
0
int have_ip_ipv6(const char *ip)
{
	FILE *if_inet6;
	struct in6_addr addr6, query_addr;
	unsigned int b[4];
	char tmp_ip[INET6_ADDRSTRLEN+1];
	char name[20]; /* IFNAMSIZ aka IF_NAMESIZE is 16 */
	int i;

	/* don't want to do getaddrinfo lookup, but inet_pton get's confused by
	 * %eth0 link local scope specifiers. So we have a temporary copy
	 * without that part. */
	for (i=0; ip[i] && ip[i] != '%' && i < INET6_ADDRSTRLEN; i++)
		tmp_ip[i] = ip[i];
	tmp_ip[i] = 0;

	if (inet_pton(AF_INET6, tmp_ip, &query_addr) <= 0)
		return 0;

#define PROC_IF_INET6 "/proc/net/if_inet6"
	if_inet6 = fopen(PROC_IF_INET6, "r");
	if (!if_inet6) {
		if (errno != ENOENT)
			perror("open of " PROC_IF_INET6 " failed:");
#undef PROC_IF_INET6
		return 0;
	}

	while (fscanf
	       (if_inet6,
		X32(08) X32(08) X32(08) X32(08) " %*x %*x %*x %*x %s",
		b, b + 1, b + 2, b + 3, name) > 0) {
		for (i = 0; i < 4; i++)
			addr6.s6_addr32[i] = cpu_to_be32(b[i]);

		if (memcmp(&query_addr, &addr6, sizeof(struct in6_addr)) == 0) {
			fclose(if_inet6);
			return 1;
		}
	}
	fclose(if_inet6);
	return 0;
}
Beispiel #5
0
/*
 * Quartett to mod converter
 *   03.02.2000 by Settel
 */


// Includes /*fold00*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <math.h>
#include "pattern.h"
#include "voice.h"
#include "common.h"
#include "mod.h"

// Defines /*fold00*/
#define BASEFREQ 0x879c
#define SAMPLESTRETCH 0.95
#define SPEED 0x80

#define PITCH_TOO_LOW    0x10000
#define PITCH_TOO_HIGH   0x20000
#define VOICE_MAP_LOWER  0x100
#define VOICE_MAP_HIGHER 0x200

// Globals /*fold00*/
char *pattern_buf=NULL;
char *voices_buf=NULL;
int pattern_buf_len=0;
int voices_buf_len=0;
struct channel chan[4];

int min_step_width=1<<16;
int num_steps=0;

int mod_patterns_num=0;
char *mod_patterns_buf=NULL;

struct sample samples[20];
int voice_map[31|VOICE_MAP_HIGHER|VOICE_MAP_LOWER];
int voice_rev_map[31];

int mod_pitch_tab[36];

// init_mod_pitch_tab /*fold00*/
void init_mod_pitch_tab(){
#if 1
   int i;
   for(i=0;i<36;i++) mod_pitch_tab[i]=freqtab[i];
#else
   int i;
   double c=exp(log(2)/12.0);

   char buf[4096];
   int fd;

   fd=open("freq.mod",O_RDONLY);
   if(fd<0){
      perror("open()");
      exit(1);
   }
   read(fd,buf,sizeof(buf));
   close(fd);

   for(i=0;i<36;i++) mod_pitch_tab[i]=(int)((856.0/pow(c,i))+0.5);

   for(i=0;i<36;i++){
      fd=X32(*((unsigned long *)(buf+i*16+1084)));
      fd>>=16;
      fd&=0x7FFF;
      printf("%2i: %3i <-> %3i  (%3i)\n",i,mod_pitch_tab[i],fd,mod_pitch_tab[i]-fd);

   }
#endif
}

// read_4v /*fold00*/
void read_4v(char *name){
   int fd;
   struct stat stat_buf;
   int len;

   if(stat(name,&stat_buf)){
      perror("stat()");
      exit(1);
   }
   pattern_buf_len=stat_buf.st_size;
   pattern_buf=(char *)malloc(pattern_buf_len);
   if(!pattern_buf){
      pattern_buf_len=0;
      perror("malloc()");
      exit(1);
   }

   fd=open(name,O_RDONLY);
   if(fd<0){
      perror("open()");
      exit(1);
   }

   len=read(fd,pattern_buf,pattern_buf_len);
   if(len<0){
      perror("read()");
      exit(1);
   }else if(len!=pattern_buf_len){
      fprintf(stderr,"read incomplete\n");
      exit(1);
   }

   close(fd);
}

// read_set /*fold00*/
void read_set(char *name){
   int fd;
   struct stat stat_buf;
   int len;

   if(stat(name,&stat_buf)){
      perror("stat()");
      exit(1);
   }
   voices_buf_len=stat_buf.st_size;
   voices_buf=(char *)malloc(voices_buf_len+32768);
   if(!voices_buf){
      voices_buf_len=0;
      perror("malloc()");
      exit(1);
   }

   fd=open(name,O_RDONLY);
   if(fd<0){
      perror("open()");
      exit(1);
   }

   len=read(fd,voices_buf,voices_buf_len);
   if(len<0){
      perror("read()");
      exit(1);
   }else if(len!=voices_buf_len){
      fprintf(stderr,"read incomplete\n");
      exit(1);
   }

   close(fd);
}

// dump_channel /*fold00*/
void dump_channel(int i){
   struct note *note;

   for(note=chan[i].start;note<chan[i].end;note++){
      printf(" %3i:  %c %5i %08lx %08lx\n",note-chan[i].start,
             note->cmd,note->delay,
             note->val1,note->val2);
   }
}

// preprocess_4v /*fold00*/
void preprocess_4v(){
   int i;
   struct note *note;

   note=(struct note*)(pattern_buf+16);
   for(i=0;i<4;i++){
      printf("process channel %i: ",i);
      chan[i].start=note;
      while(1){
         note->cmd=X16(note->cmd);
         note->delay=X16(note->delay);
         note->val1=X32(note->val1);
         note->val2=X32(note->val2);

         switch(note->cmd){
         case NOTE_LOOPSTART:
         case NOTE_LOOPEND:
         case NOTE_VOICE:
            note->delay=0;
            break;
         }

         if(note->cmd==NOTE_END) break;
         note++;
      }
      chan[i].end=note;
      note++;
      printf("length %i\n",chan[i].end-chan[i].start);

   }
}

// preprocess_set /*fold00*/
void preprocess_set(){
   int i,j;
   struct setheader *setheader=(struct setheader *)voices_buf;
   unsigned long *offset;

   memset(voice_map,-1,sizeof(voice_map));
   memset(voice_rev_map,-1,sizeof(voice_rev_map));
   memset(samples,0,sizeof(samples));
   for(i=0;i<20;i++){
      strncpy(samples[i].name,setheader->name[i],6);
      offset=(unsigned long *)setheader->offset;
      offset+=i;
      samples[i].descr=(struct sam_descr *)(voices_buf+X32(*offset));
      if(X32(*offset)==0 || ((char *)samples[i].descr)+8>voices_buf+voices_buf_len){
         samples[i].descr=NULL;
         samples[i].start=NULL;
         samples[i].len=0;
         samples[i].repstart=0;
         samples[i].replen=0;
         voice_map[i]=-1;
      }else{
         voice_map[i]=i;
         voice_rev_map[i]=i;
         samples[i].start=voices_buf+X32(*offset)+8;
         samples[i].len=X16(samples[i].descr->len)&0x7FFF;
         samples[i].repstart=(X16(samples[i].descr->len)&0x7FFF)-
            (X16(samples[i].descr->replen)&0x7FFF);
         samples[i].replen=X16(samples[i].descr->replen)&0x7FFF;

         for(j=0;j<i;j++){
            if(samples[j].descr==samples[i].descr){
               samples[i].descr=NULL;
               samples[i].start=NULL;
               samples[i].len=0;
               samples[i].repstart=0;
               samples[i].replen=0;

               voice_map[i]=j;
               voice_rev_map[i]=-1;
               break;
            }
         }
      }
      printf("sam %2i: mapped to %2i,",i,voice_map[i]);
      if(voice_map[i]>=0){
         printf(" \"%6s\", %6i\n",samples[voice_map[i]].name,samples[voice_map[i]].len);
      }else{
         printf("\n");
      }
   }
}

// count_steps /*fold00*/
void count_steps(){
   int count_steps_sub(struct note *start,struct note *end){
      struct note *note;
      struct note *loopstart;
      struct note *loopend;
      int count=0;
      int count2;
      int depth=0;

      for(note=start,loopstart=start;note<=end;note++){
         switch(note->cmd){
         case NOTE_LOOPSTART:
            if(depth++==0) loopstart=note+1;
            break;
         case NOTE_LOOPEND:
            if(--depth==0){
               loopend=note-1;
               count2=count_steps_sub(loopstart,loopend);
               loopstart=start;
               count2+=note->delay;
               count-=note->delay;
               count+=count2*(NOTE_LOOP_CNT(note));
            }
            break;
         }

         count+=note->delay;
         if(note->delay>0){
            min_step_width=min_step_width>note->delay?note->delay:min_step_width;
         }
      }
      return count;
   }

   int i;
   int count;

   for(i=0;i<4;i++){
      count=0;
      count=count_steps_sub(chan[i].start,chan[i].end-1);
      printf("pattern %i has %i steps\n",i,count);
      if(count>num_steps) num_steps=count;
   }
   printf("min. step width is %i\n",min_step_width);
}


// write_mod /*fold00*/
void write_mod(char *name){
   struct mod_header mod_header;
   double stretch=SAMPLESTRETCH;
   int newlen[32];
   int fd;
   int len,pos;
   int i,j;
   int samnr;

   memset(newlen,0,sizeof(newlen));
   printf("creating MOD header\n");
   memset(&mod_header,0,sizeof(mod_header));
   mod_header.magic[0]='M';
   mod_header.magic[1]='.';
   mod_header.magic[2]='K';
   mod_header.magic[3]='.';

   mod_header.num_pos=mod_patterns_num;
   mod_header.repstartpos=0;
   for(i=0;i<mod_patterns_num;i++)
       mod_header.poslist[i]=i;

   for(j=0;j<19;j++) mod_header.name[j]=(j<(signed int)strlen(name))?name[j]:' ';
   mod_header.name[19]=0;

   printf("creating sample table\n");
   for(i=0;i<31;i++){
      samnr=voice_rev_map[i];
      if(samnr>=0){
         struct mod_saminfo *sam=&mod_header.saminfo[i];

         for(j=0;j<20;j++) sam->name[j]=(j<(signed int)strlen(samples[samnr].name))?samples[samnr].name[j]:' ';

         if(samnr&(VOICE_MAP_HIGHER|VOICE_MAP_LOWER)){
            sam->name[17]='(';
            sam->name[18]='T';
            sam->name[19]=')';
         }

         sam->finetune=Y16(0);
         newlen[i]=(unsigned short)(samples[samnr].len*stretch);
         sam->len=Y16(newlen[i]>>1);
         sam->vol=Y16(VOL_MAX);
         if(samples[samnr].replen==0xffff || samples[samnr].repstart==samples[samnr].len){
            sam->repstart=Y16(0);
            sam->replen=Y16(1);
         }else{
            sam->repstart=Y16((unsigned short)(samples[samnr].repstart*stretch)>>1);
            sam->replen=Y16((unsigned short)(samples[samnr].replen*stretch)>>1);
         }
      }
   }

   printf("writing mod: \n");
   fd=open(name,O_WRONLY|O_CREAT,0666);
   if(fd<0){
      perror("open()");
      exit(1);
   }
   printf("header\n");
   len=write(fd,&mod_header,sizeof(mod_header));
   if(len!=sizeof(mod_header)){
      fprintf(stderr,"write incomplete\n");
      exit(1);
   }

   printf("patterns\n");

   // insert speed command
   {
	   unsigned long l;
	   l=X32(*(unsigned long *)mod_patterns_buf);
	   l&=0xFFFFF000;
	   l|=0x00000F06;
	   *(unsigned long *)mod_patterns_buf=Y32(l);

	   l=X32(*(unsigned long *)(mod_patterns_buf+4));
	   l&=0xFFFFF000;
	   l|=0x00000F00+SPEED;
	   *(unsigned long *)(mod_patterns_buf+4)=Y32(l);
   }

   for(pos=0;pos<mod_patterns_num*1024;){
      len=write(fd,mod_patterns_buf+pos,mod_patterns_num*1024-pos);
      if(len<0) break;
      pos+=len;
   }
   if(pos!=mod_patterns_num*1024){
      fprintf(stderr,"write incomplete\n");
      exit(1);
   }

   for(i=0;i<32;i++){
      unsigned char newsample[65536];

      samnr=voice_rev_map[i];
      if(samnr<0) continue;
      printf("sample %2i; start: %#08lx, len: %8i\n",i,(unsigned long)samples[samnr].start,samples[samnr].len);
      // if(samnr&(VOICE_MAP_HIGHER|VOICE_MAP_LOWER)){
      // }else{

#if 0
      // save sample without processing
	  char *x;
      for(j=0,x=samples[samnr].start;j<samples[samnr].len;j++,x++){
          // if(samnr==14) printf("%8i\n",j);
         *x=((unsigned char)*x)-0x80;
      }
      // }
      len=write(fd,samples[samnr].start,samples[samnr].len);
      if(len!=samples[samnr].len){
         fprintf(stderr,"write incomplete\n");
         exit(1);
      }
#else
      // resample
      for(j=0;j<newlen[i];j++){
          newsample[j]=((unsigned char)(samples[samnr].start[(int)(j/stretch)]))-0x80;
      }
      len=write(fd,newsample,newlen[i]);
      if(len!=newlen[i]){
         fprintf(stderr,"write incomplete (%i != %i)\n",len,newlen[i]);
         exit(1);
      }
#endif
   }

   close(fd);
}