
// SPDX-License-Identifier: CC-BY-NC-SA-4.0
//
// Copyright (C) 2026 Bit by Bit Signal Processing LLC (https://bxbsp.com)
//
// This work is placed under the "Creative Commons Attribution
// NonCommercial ShareAlike 4.0 International" license, known
// by the shortened acronym "CC-BY-NC-SA-4.0".
//
// This work 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.
//
// A CC-BY-NC-SA-4.0 license allows you to use this work for
// noncommercial purposes so long as attribution is made to the
// original author.  Modified versions of this work may be distributed,
// but only under the same license.  For further details, see the
// Creative Commons License "CC-BY-NC-SA-4.0".
//
// You should have received a copy of the CC-BY-NC-SA-4.0 license
// along with this work. If not, see
// <https://creativecommons.org/licenses/by-nc-sa/4.0/>.
//

#include "beeper.hh"
#include "beep_manager.hh"

#include <math.h>

void beeper::beep()
{
  audio_beep_manager()->do_beep_job(&job);
}

int16_t to_byte_order_le(int16_t in)
{
  union { int16_t d; unsigned char c[2]; } cvt;

  cvt.c[0] = in & 255;
  cvt.c[1] = in >> 8;

  return cvt.d;
}


beeper::beeper(float amplitude, float frequency_hz, float duration_milliseconds)
{
  int sample_rate_hz          = audio_beep_manager()->get_sample_rate_hz();
  int approximate_num_samples = duration_milliseconds * sample_rate_hz / 1000;
  int period                  = audio_beep_manager()->get_period_length();

  
  int num_periods = ( approximate_num_samples + period - 1 ) / period;

  if(num_periods<1)
    num_periods=1;
  
  int num_samples = period * num_periods;

  //printf("num_periods=%d, period=%d\n", num_periods, period);
  
  printf("Creating a beeper with amplitude %f, frequency %f, duration %fms (%d samples at %dHz)\n", 
	 amplitude, frequency_hz, duration_milliseconds, num_samples, sample_rate_hz);

  job.data_length = num_samples;
  job.data = new channels[num_samples];
  
  for(int i=0; i<num_samples; i++)
    {
      double   waveform      =  sin(double(i)*2.0*M_PI*frequency_hz/sample_rate_hz);
      double   amplitude_max =  30000;
      int16_t  value         =  int16_t(amplitude * waveform * amplitude_max);

      //printf("Beeper[%d] value %d\n", i, value);
      
      job.data[i].right = to_byte_order_le(value);
      job.data[i].left  = to_byte_order_le(value);
    }
}


beeper::~beeper()
{
  delete [] job.data;
}
