<commit_before>/* bzflag
 * Copyright (c) 1993 - 2003 <NAME>
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include <math.h>
#include "common.h"
#include "sound.h"
#include "global.h"
#include "TimeKeeper.h"
#include "PlatformFactory.h"
#include "BzfMedia.h"

const float		SpeedOfSound = 343.0f;			// meters/sec
const int		MaxEvents = 30;
const float		InterAuralDistance = 0.1f;		// meters

/*
 * producer/consumer shared data types and defines
 */

/* sound queue commands */
#define	SQC_CLEAR	0		/* no code; no data */
#define	SQC_SET_POS	1		/* no code; x,y,z,t */
#define	SQC_SET_VEL	2		/* no code; x,y,z */
#define	SQC_SET_VOLUME	3		/* code = new volume; no data */
#define	SQC_LOCAL_SFX	4		/* code=sfx; no data */
#define	SQC_WORLD_SFX	5		/* code=sfx; x,y,z of sfx source */
#define	SQC_FIXED_SFX	6		/* code=sfx; x,y,z of sfx source */
#define	SQC_JUMP_POS	7		/* no code; x,y,z,t */
#define	SQC_QUIT	8		/* no code; no data */
#define	SQC_IWORLD_SFX	9		/* code=sfx; x,y,z of sfx source */

struct SoundCommand {
  public:
    int			cmd;
    int			code;
    float		data[4];
};

typedef struct {
  long			length;		/* total number samples in data */
  long			mlength;	/* total number samples in mono */
  double		dmlength;	/* mlength as a double minus one */
  float*		data;		/* left in even, right in odd */
  float*		mono;		/* avg of channels for world sfx */
  float*		monoRaw;	/* mono with silence before & after */
  double		duration;	/* time to play sound */
} AudioSamples;


/*
 * local functions
 */

static void		sendSound(SoundCommand* s);
static void		audioLoop(void*);
static bool		allocAudioSamples();
static void		freeAudioSamples(void);
static int		resampleAudio(const float* in,
				int frames, int rate, AudioSamples* out);


/*
 * general purpose audio stuff
 */

static int		usingAudio = 0;
static const char*	soundFiles[] = {
				"fire",
				"explosion",
				"ricochet",
				"flag_grab",
				"flag_drop",
				"flag_won",
				"flag_lost",
				"flag_alert",
				"jump",
				"land",
				"teleport",
				"laser",
				"shock",
				"pop",
				"explosion",
				"flag_grab",
				"boom",
				"killteam",
				"phantom",
				"missile",
				"lock",
				"teamgrab",
				"hunt",
				"hunt_select",
				"steamroller",
				"thief",
				"burrow"
			};
#define	SFX_COUNT	((int)(sizeof(soundFiles) / sizeof(soundFiles[0])))

/*
 * producer/consumer shared arena
 */

static AudioSamples	soundSamples[SFX_COUNT];
static long		audioBufferSize;
static int		soundLevel;


void			openSound(const char*)
{
  if (usingAudio) return;			// already opened

  if (!PlatformFactory::getMedia()->openAudio())
    return;

  // initialize buffers
  for (int i = 0; i < SFX_COUNT; i++) {
    soundSamples[i].data = NULL;
    soundSamples[i].mono = NULL;
    soundSamples[i].monoRaw = NULL;
  }

  // open audio data files
  if (!allocAudioSamples()) {
    PlatformFactory::getMedia()->closeAudio();
    return;					// couldn't get samples
  }

  // start audio thread
  if (!PlatformFactory::getMedia()->startAudioThread(audioLoop, NULL)) {
    PlatformFactory::getMedia()->closeAudio();
    freeAudioSamples();
    return;
  }

  setSoundVolume(10);

  usingAudio = 1;
}

void			closeSound(void)
{
  if (!usingAudio) return;

  // send stop command to audio thread
  SoundCommand s;
  s.cmd = SQC_QUIT;
  s.code = 0;
  s.data[0] = 0.0f;
  s.data[1] = 0.0f;
  s.data[2] = 0.0f;
  s.data[3] = 0.0f;
  sendSound(&s);

  // stop audio thread
  PlatformFactory::getMedia()->stopAudioThread();

  // reset audio hardware
  PlatformFactory::getMedia()->closeAudio();

  // free memory used for sfx samples
  freeAudioSamples();

  usingAudio = 0;
}

bool			isSoundOpen()
{
  return usingAudio != 0;
}

static bool		allocAudioSamples()
{
  bool anyFile = false;

  for (int i = 0; i < SFX_COUNT; i++) {
    // read it
    int numFrames, rate;
    float* samples = PlatformFactory::getMedia()->
				readSound(soundFiles[i], numFrames, rate);
    if (samples && resampleAudio(samples, numFrames, rate, soundSamples + i))
      anyFile = true;
    delete[] samples;
  }

  return anyFile;
}

static void		freeAudioSamples(void)
{
  for (int i = 0; i < SFX_COUNT; i++) {
    delete[] soundSamples[i].data;
    delete[] soundSamples[i].monoRaw;
  }
}

static int		resampleAudio(const float* in,
				int frames, int rate, AudioSamples* out)<commit_msg>report if unable to read a file when in debug<commit_after>/* bzflag
 * Copyright (c) 1993 - 2003 <NAME>
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include <math.h>
#include "common.h"
#include "sound.h"
#include "global.h"
#include "TimeKeeper.h"
#include "PlatformFactory.h"
#include "BzfMedia.h"

const float		SpeedOfSound = 343.0f;			// meters/sec
const int		MaxEvents = 30;
const float		InterAuralDistance = 0.1f;		// meters

/*
 * producer/consumer shared data types and defines
 */

/* sound queue commands */
#define	SQC_CLEAR	0		/* no code; no data */
#define	SQC_SET_POS	1		/* no code; x,y,z,t */
#define	SQC_SET_VEL	2		/* no code; x,y,z */
#define	SQC_SET_VOLUME	3		/* code = new volume; no data */
#define	SQC_LOCAL_SFX	4		/* code=sfx; no data */
#define	SQC_WORLD_SFX	5		/* code=sfx; x,y,z of sfx source */
#define	SQC_FIXED_SFX	6		/* code=sfx; x,y,z of sfx source */
#define	SQC_JUMP_POS	7		/* no code; x,y,z,t */
#define	SQC_QUIT	8		/* no code; no data */
#define	SQC_IWORLD_SFX	9		/* code=sfx; x,y,z of sfx source */

struct SoundCommand {
  public:
    int			cmd;
    int			code;
    float		data[4];
};

typedef struct {
  long			length;		/* total number samples in data */
  long			mlength;	/* total number samples in mono */
  double		dmlength;	/* mlength as a double minus one */
  float*		data;		/* left in even, right in odd */
  float*		mono;		/* avg of channels for world sfx */
  float*		monoRaw;	/* mono with silence before & after */
  double		duration;	/* time to play sound */
} AudioSamples;


/*
 * local functions
 */

static void		sendSound(SoundCommand* s);
static void		audioLoop(void*);
static bool		allocAudioSamples();
static void		freeAudioSamples(void);
static int		resampleAudio(const float* in,
				int frames, int rate, AudioSamples* out);


/*
 * general purpose audio stuff
 */

static int		usingAudio = 0;
static const char*	soundFiles[] = {
				"fire",
				"explosion",
				"ricochet",
				"flag_grab",
				"flag_drop",
				"flag_won",
				"flag_lost",
				"flag_alert",
				"jump",
				"land",
				"teleport",
				"laser",
				"shock",
				"pop",
				"explosion",
				"flag_grab",
				"boom",
				"killteam",
				"phantom",
				"missile",
				"lock",
				"teamgrab",
				"hunt",
				"hunt_select",
				"steamroller",
				"thief",
				"burrow"
			};
#define	SFX_COUNT	((int)(sizeof(soundFiles) / sizeof(soundFiles[0])))

/*
 * producer/consumer shared arena
 */

static AudioSamples	soundSamples[SFX_COUNT];
static long		audioBufferSize;
static int		soundLevel;


void			openSound(const char*)
{
  if (usingAudio) return;			// already opened

  if (!PlatformFactory::getMedia()->openAudio())
    return;

  // initialize buffers
  for (int i = 0; i < SFX_COUNT; i++) {
    soundSamples[i].data = NULL;
    soundSamples[i].mono = NULL;
    soundSamples[i].monoRaw = NULL;
  }

  // open audio data files
  if (!allocAudioSamples()) {
    PlatformFactory::getMedia()->closeAudio();
#if DEBUG
    std::cout << "WARNING: Unable to open audio data files" << std::endl;
#endif
    return;					// couldn't get samples
  }

  // start audio thread
  if (!PlatformFactory::getMedia()->startAudioThread(audioLoop, NULL)) {
    PlatformFactory::getMedia()->closeAudio();
    freeAudioSamples();
#if DEBUG
    std::cout << "WARNING: Unable to start the audio thread" << std::endl;
#endif
    return;
  }

  setSoundVolume(10);

  usingAudio = 1;
}

void			closeSound(void)
{
  if (!usingAudio) return;

  // send stop command to audio thread
  SoundCommand s;
  s.cmd = SQC_QUIT;
  s.code = 0;
  s.data[0] = 0.0f;
  s.data[1] = 0.0f;
  s.data[2] = 0.0f;
  s.data[3] = 0.0f;
  sendSound(&s);

  // stop audio thread
  PlatformFactory::getMedia()->stopAudioThread();

  // reset audio hardware
  PlatformFactory::getMedia()->closeAudio();

  // free memory used for sfx samples
  freeAudioSamples();

  usingAudio = 0;
}

bool			isSoundOpen()
{
  return usingAudio != 0;
}

static bool		allocAudioSamples()
{
  bool anyFile = false;

  for (int i = 0; i < SFX_COUNT; i++) {
    // read it
    int numFrames, rate;
    float* samples = PlatformFactory::getMedia()->
				readSound(soundFiles[i], numFrames, rate);
    if (samples && resampleAudio(samples, numFrames, rate, soundSamples + i)) {
      anyFile = true;
    }
    delete[] samples;
  }

  return anyFile;
}

static void		freeAudioSamples(void)
{
  for (int i = 0; i < SFX_COUNT; i++) {
    delete[] soundSamples[i].data;
    delete[] soundSamples[i].monoRaw;
  }
}

static int		resampleAudio(const float* in,
				int frames, int rate, AudioSamples* out)
{'fraction_non_alphanumeric': 0.13464147792506, 'fraction_numerical': 0.010437323870159691, 'mean_word_length': 3.2026315789473685, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4186426', 'n_tokens_mistral': 3806, 'n_tokens_neox': 3406, 'n_words': 980}