<commit_before>/***************************************************************************
                           native_midi_lnx.c
			   -----------------
			   
    copyright            : (C) 2002 by <NAME>
    email                : <EMAIL>
 ***************************************************************************/

/* in this file is used code from PlayMidi    Copyright (C) 1994-1996 <NAME> */

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#if defined(linux) || defined(__FreeBSD__)

#ifndef __FreeBSD__
#include <getopt.h>
#endif
#include <fcntl.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/stat.h>
#include <string.h>
#include "SDL_thread.h"
#include "native_midi.h"
#include "playmidi.h"

SEQ_DEFINEBUF(SEQUENCERBLOCKSIZE);

int play_fm = 0, play_gus = 0, play_ext = 0, play_awe = 0;
int opl3_patch_aviable = 0, fm_patch_aviable = 0;

struct miditrack seq[MAXTRKS];
struct synth_info card_info[MAX_CARDS];

int FORCE_EXT_DEV = -1;
int chanmask = 0xffff, perc = PERCUSSION;
int dochan = 1, force8bit = 0, wantopl3 = FM_DEFAULT_MODE;
int patchloaded[256], fmloaded[256], useprog[16], usevol[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int reverb = 0, chorus = 0, nrsynths, nrmidis;
int sb_dev = -1, gus_dev = -1, ext_dev = -1, awe_dev = -1, p_remap = 0;
int seqfd,  MT32 = 0;
FILE *mfd;
unsigned long int default_tempo;
float skew = 1.0;
char ImPlaying = 0;
SDL_Thread *playevents_thread=NULL;

extern int ntrks;
extern char *gmvoice[256];
extern int mt32pgm[128];
extern int note_vel[16][128];
extern int playevents();
extern int gus_load(int);
extern int readmidi(unsigned char *, off_t);
extern void loadfm();

void seqbuf_dump();
int synth_setup();

struct _NativeMidiSong
{
    char *filebuf;
    unsigned long int file_size;
};

int native_midi_detect()
{

    int sbfd;
    int ret=0;    

    /* Open sequencer device */
    if ((seqfd = open(SEQUENCER_DEV, O_WRONLY, 0)) < 0) 
    {
	perror("open " SEQUENCER_DEV);
	return 0;
    }

    gus_dev = -1;
    sb_dev = -1;
    ext_dev = -1;
    awe_dev = -1;
    play_fm = 0;
    play_gus = 0;
    play_ext = 0;
    play_awe = 0;
    
    opl3_patch_aviable = 0;
    fm_patch_aviable = 0;

    sbfd = open(SBMELODIC, O_RDONLY, 0);
    if (sbfd != -1)
    {
	close(sbfd);
	sbfd = open(SBDRUMS, O_RDONLY, 0);
	if (sbfd != -1)
	{
            close(sbfd);
	    fm_patch_aviable = 1;
	}
    }

    sbfd = open(O3MELODIC, O_RDONLY, 0);
    if (sbfd != -1)
    {
        close(sbfd);
        sbfd = open(O3DRUMS, O_RDONLY, 0);
	if (sbfd != -1)
	{
            close(sbfd);
	    opl3_patch_aviable = 1;
	}
    }

    ret=synth_setup();

    /* Close sequencer device */
    close(seqfd);

    return ret;
}

NativeMidiSong *native_midi_loadsong(char *midifile)
{
    NativeMidiSong	*song = NULL;
    char 		*extra;
    int 		piped = 0;
    struct stat 	info;

    song = malloc(sizeof(NativeMidiSong));
    if (!song)
    {
	return NULL;
    };
    if (stat(midifile, &info) == -1) 
    {
        if ((extra = malloc(strlen(midifile) + 4)) == NULL)
        {
	    goto end;
	}
	sprintf(extra, "%s.mid", midifile);
	if (stat(extra, &info) == -1)
	{
	    free(extra);
	    goto end;
	}
	if ((mfd = fopen(extra, "r")) == NULL)
	{
	    free(extra);
	    goto end;
	}
	free(extra);
    } else
    {
        char *ext = strrchr(midifile, '.');
        if (ext && strcmp(ext, ".gz") == 0) 
	{
	    char temp[1024];
	    piped = 1;
	    sprintf(temp, "gzip -l %s", midifile);
	    if ((mfd = popen(temp, "r")) == NULL)
	    {
	        goto end;
	    }
	    fgets(temp, sizeof(temp), mfd); /* skip 1st line */
	    fgets(temp, sizeof(temp), mfd);
	    strtok(temp, " "); /* compressed size */
	    info.st_size = atoi(strtok(NULL, " ")); /* original size */
	    pclose(mfd);
	    sprintf(temp, "gzip -d -c %s",midifile);
	    if ((mfd = popen(temp, "r")) == NULL)
	    {
	        goto end;
	    }
	}else if ((mfd = fopen(midifile, "r")) == NULL)
	{
	    goto end;
	}
    }
    if ((song->filebuf = malloc(info.st_size)) == NULL)
    {
        if (piped)
        {
	    pclose(mfd);
	}else
	{
	    fclose(mfd);
	}
	goto end;
    }
    song->file_size=info.st_size;
    fread(song->filebuf, 1, info.st_size, mfd);
    if (piped)
    {
        pclose(mfd);
    } else
    {
        fclose(mfd);
    }
    
  return song;

end:
    free(song);
    return NULL;
}

NativeMidiSong *native_midi_loadsong_RW(SDL_RWops *rw)
{
	NativeMidiSong	*song = NULL;
	char 		*extra;

	song = malloc(sizeof(NativeMidiSong));
	if (!song) {
		return NULL;
	};

	SDL_RWseek(rw, 0, SEEK_END);
	song->file_size = SDL_RWtell(rw, 0, SEEK_CUR);
	SDL_RWseek(rw, 0, SEEK_SET);

	song->filebuf = malloc(song->file_size);
	if (!song->filebuf) {
		free(song);
		return NULL;
	}

	SDL_RWread(rw, song->filebuf, song->file_size, 1);
	return song;
}

void native_midi_freesong(NativeMidiSong *song)
{
    free(song->filebuf);
    free(song);
}

void native_midi_start(NativeMidiSong *song)
{

    int i, error = 0, j;

    for (i = 0; i < 16; i++)
    {
	useprog[i] = 0;	/* reset options */<commit_msg>Small fix for RWops usage<commit_after>/***************************************************************************
                           native_midi_lnx.c
			   -----------------
			   
    copyright            : (C) 2002 by <NAME>
    email                : <EMAIL>
 ***************************************************************************/

/* in this file is used code from PlayMidi    Copyright (C) 1994-1996 <NAME> */

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#if defined(linux) || defined(__FreeBSD__)

#ifndef __FreeBSD__
#include <getopt.h>
#endif
#include <fcntl.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/stat.h>
#include <string.h>
#include "SDL_thread.h"
#include "native_midi.h"
#include "playmidi.h"

SEQ_DEFINEBUF(SEQUENCERBLOCKSIZE);

int play_fm = 0, play_gus = 0, play_ext = 0, play_awe = 0;
int opl3_patch_aviable = 0, fm_patch_aviable = 0;

struct miditrack seq[MAXTRKS];
struct synth_info card_info[MAX_CARDS];

int FORCE_EXT_DEV = -1;
int chanmask = 0xffff, perc = PERCUSSION;
int dochan = 1, force8bit = 0, wantopl3 = FM_DEFAULT_MODE;
int patchloaded[256], fmloaded[256], useprog[16], usevol[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int reverb = 0, chorus = 0, nrsynths, nrmidis;
int sb_dev = -1, gus_dev = -1, ext_dev = -1, awe_dev = -1, p_remap = 0;
int seqfd,  MT32 = 0;
FILE *mfd;
unsigned long int default_tempo;
float skew = 1.0;
char ImPlaying = 0;
SDL_Thread *playevents_thread=NULL;

extern int ntrks;
extern char *gmvoice[256];
extern int mt32pgm[128];
extern int note_vel[16][128];
extern int playevents();
extern int gus_load(int);
extern int readmidi(unsigned char *, off_t);
extern void loadfm();

void seqbuf_dump();
int synth_setup();

struct _NativeMidiSong
{
    char *filebuf;
    unsigned long int file_size;
};

int native_midi_detect()
{

    int sbfd;
    int ret=0;    

    /* Open sequencer device */
    if ((seqfd = open(SEQUENCER_DEV, O_WRONLY, 0)) < 0) 
    {
	perror("open " SEQUENCER_DEV);
	return 0;
    }

    gus_dev = -1;
    sb_dev = -1;
    ext_dev = -1;
    awe_dev = -1;
    play_fm = 0;
    play_gus = 0;
    play_ext = 0;
    play_awe = 0;
    
    opl3_patch_aviable = 0;
    fm_patch_aviable = 0;

    sbfd = open(SBMELODIC, O_RDONLY, 0);
    if (sbfd != -1)
    {
	close(sbfd);
	sbfd = open(SBDRUMS, O_RDONLY, 0);
	if (sbfd != -1)
	{
            close(sbfd);
	    fm_patch_aviable = 1;
	}
    }

    sbfd = open(O3MELODIC, O_RDONLY, 0);
    if (sbfd != -1)
    {
        close(sbfd);
        sbfd = open(O3DRUMS, O_RDONLY, 0);
	if (sbfd != -1)
	{
            close(sbfd);
	    opl3_patch_aviable = 1;
	}
    }

    ret=synth_setup();

    /* Close sequencer device */
    close(seqfd);

    return ret;
}

NativeMidiSong *native_midi_loadsong(char *midifile)
{
    NativeMidiSong	*song = NULL;
    char 		*extra;
    int 		piped = 0;
    struct stat 	info;

    song = malloc(sizeof(NativeMidiSong));
    if (!song)
    {
	return NULL;
    };
    if (stat(midifile, &info) == -1) 
    {
        if ((extra = malloc(strlen(midifile) + 4)) == NULL)
        {
	    goto end;
	}
	sprintf(extra, "%s.mid", midifile);
	if (stat(extra, &info) == -1)
	{
	    free(extra);
	    goto end;
	}
	if ((mfd = fopen(extra, "r")) == NULL)
	{
	    free(extra);
	    goto end;
	}
	free(extra);
    } else
    {
        char *ext = strrchr(midifile, '.');
        if (ext && strcmp(ext, ".gz") == 0) 
	{
	    char temp[1024];
	    piped = 1;
	    sprintf(temp, "gzip -l %s", midifile);
	    if ((mfd = popen(temp, "r")) == NULL)
	    {
	        goto end;
	    }
	    fgets(temp, sizeof(temp), mfd); /* skip 1st line */
	    fgets(temp, sizeof(temp), mfd);
	    strtok(temp, " "); /* compressed size */
	    info.st_size = atoi(strtok(NULL, " ")); /* original size */
	    pclose(mfd);
	    sprintf(temp, "gzip -d -c %s",midifile);
	    if ((mfd = popen(temp, "r")) == NULL)
	    {
	        goto end;
	    }
	}else if ((mfd = fopen(midifile, "r")) == NULL)
	{
	    goto end;
	}
    }
    if ((song->filebuf = malloc(info.st_size)) == NULL)
    {
        if (piped)
        {
	    pclose(mfd);
	}else
	{
	    fclose(mfd);
	}
	goto end;
    }
    song->file_size=info.st_size;
    fread(song->filebuf, 1, info.st_size, mfd);
    if (piped)
    {
        pclose(mfd);
    } else
    {
        fclose(mfd);
    }
    
  return song;

end:
    free(song);
    return NULL;
}

NativeMidiSong *native_midi_loadsong_RW(SDL_RWops *rw)
{
	NativeMidiSong	*song = NULL;
	char 		*extra;

	song = malloc(sizeof(NativeMidiSong));
	if (!song) {
		return NULL;
	};

	SDL_RWseek(rw, 0, SEEK_END);
	song->file_size = SDL_RWtell(rw);
	SDL_RWseek(rw, 0, SEEK_SET);

	song->filebuf = malloc(song->file_size);
	if (!song->filebuf) {
		free(song);
		return NULL;
	}

	SDL_RWread(rw, song->filebuf, song->file_size, 1);
	return song;
}

void native_midi_freesong(NativeMidiSong *song)
{
    free(song->filebuf);
    free(song);
}

void native_midi_start(NativeMidiSong *song)
{

    int i, error = 0, j;

    for (i = 0; i < 16; i++)
    {
	useprog[i] = 0;	/* reset options */
{'fraction_non_alphanumeric': 0.19336967205790367, 'fraction_numerical': 0.0226074524171209, 'mean_word_length': 2.481181959564541, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5429345', 'n_tokens_mistral': 4604, 'n_tokens_neox': 4153, 'n_words': 966}