Added missing files

This commit is contained in:
ekeeke31 2010-08-24 12:52:46 +00:00
parent b8506f31b7
commit c2d54eb63a
3 changed files with 217 additions and 3 deletions

163
source/sound/blip.c Normal file
View File

@ -0,0 +1,163 @@
/* http://www.slack.net/~ant/ */
#include "blip.h"
//#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
/* Copyright (C) 2003-2008 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
General Public License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. This
module 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. See the GNU Lesser General Public License for more
details. You should have received a copy of the GNU Lesser General Public
License along with this module; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
enum { buf_extra = 2 }; /* extra samples to save past end */
enum { time_bits = 16 }; /* bits in fraction of fixed-point sample counts */
enum { time_unit = 1 << time_bits };
enum { phase_bits = 15 }; /* bits in fraction of deltas in buffer */
enum { phase_count = 1 << phase_bits };
enum { phase_shift = time_bits - phase_bits };
typedef int buf_t; /* type of element in delta buffer */
struct blip_buffer_t
{
int factor; /* clocks to samples conversion factor */
int offset; /* fractional position of clock 0 in delta buffer */
int amp; /* current output amplitude (sum of all deltas up to now) */
int size; /* size of delta buffer */
buf_t buf [65536]; /* delta buffer, only size elements actually allocated */
};
blip_buffer_t* blip_alloc( double clock_rate, double sample_rate, int size )
{
/* Allocate space for structure and delta buffer */
blip_buffer_t* s = (blip_buffer_t*) malloc(
offsetof (blip_buffer_t, buf) + (size + buf_extra) * sizeof (buf_t) );
if ( s != NULL )
{
/* Calculate output:input ratio and convert to fixed-point */
double ratio = sample_rate / clock_rate;
s->factor = (int) (ratio * time_unit + 0.5);
s->size = size;
blip_clear( s );
}
return s;
}
void blip_free( blip_buffer_t* s )
{
free( s );
}
void blip_clear( blip_buffer_t* s )
{
s->offset = 0;
s->amp = 0;
memset( s->buf, 0, (s->size + buf_extra) * sizeof (buf_t) );
}
void blip_add( blip_buffer_t* s, int clocks, int delta )
{
/* Convert to fixed-point time in terms of output samples */
int fixed_time = clocks * s->factor + s->offset;
/* Extract whole and fractional parts */
int index = fixed_time >> time_bits; /* whole */
int phase = fixed_time >> phase_shift & (phase_count - 1); /* fraction */
/* Split delta between first and second samples */
int second = delta * phase;
int first = delta * phase_count - second;
/* Be sure index is within buffer */
//assert( index >= 0 && index+1 < s->size + buf_extra );
/* Add deltas to buffer */
s->buf [index ] += first;
s->buf [index+1] += second;
}
int blip_clocks_needed( const blip_buffer_t* s, int samples )
{
int fixed_needed;
if ( samples > s->size )
samples = s->size;
/* Fixed-point number of samples needed in addition to those in buffer */
fixed_needed = samples * time_unit - s->offset;
/* If more are needed, convert to clocks and round up */
return (fixed_needed <= 0) ? 0 : (fixed_needed - 1) / s->factor + 1;
}
void blip_end_frame( blip_buffer_t* s, int clocks )
{
s->offset += clocks * s->factor;
/* Ensure time wasn't past end of buffer */
//assert( blip_samples_avail( s ) <= s->size );
}
int blip_samples_avail( const blip_buffer_t* s )
{
return s->offset >> time_bits;
}
/* Removes n samples from buffer */
static void remove_samples( blip_buffer_t* s, int n )
{
int remain = blip_samples_avail( s ) + buf_extra - n;
s->offset -= n * time_unit;
//assert( s->offset >= 0 );
/* Copy remaining samples to beginning of buffer and clear the rest */
memmove( s->buf, &s->buf [n], remain * sizeof (buf_t) );
memset( &s->buf [remain], 0, n * sizeof (buf_t) );
}
int blip_read_samples( blip_buffer_t* s, short out [], int count, int stereo )
{
/* can't read more than available */
int avail = blip_samples_avail( s );
if ( count > avail )
count = avail;
if ( count )
{
/* Sum deltas and write out */
int i;
for ( i = 0; i < count; ++i )
{
int sample;
/* Apply slight high-pass filter */
s->amp -= s->amp >> 9;
/* Add next delta */
s->amp += s->buf [i];
/* Calculate output sample */
sample = s->amp >> phase_bits;
/* Keep within 16-bit sample range */
if ( sample < -32768 ) sample = -32768;
if ( sample > +32767 ) sample = +32767;
out [i << stereo] = sample;
}
remove_samples( s, count );
}
return count;
}

51
source/sound/blip.h Normal file
View File

@ -0,0 +1,51 @@
/* Fast sound synthesis buffer for use in real-time emulators of electronic
sound generator chips like those in early video game consoles. Uses linear
interpolation. Higher-quality versions are available that use sinc-based
band-limited synthesis. */
#ifndef BLIP_H
#define BLIP_H
#ifdef __cplusplus
extern "C" {
#endif
/* Creates a new blip_buffer with specified input clock rate, output
sample rate, and size (in samples), or returns NULL if out of memory. */
typedef struct blip_buffer_t blip_buffer_t;
blip_buffer_t* blip_alloc( double clock_rate, double sample_rate, int size );
/* Frees memory used by a blip_buffer. No effect if NULL is passed. */
void blip_free( blip_buffer_t* );
/* Removes all samples and clears buffer. */
void blip_clear( blip_buffer_t* );
/* Adds an amplitude transition of delta at specified time in source clocks.
Delta can be negative. */
void blip_add( blip_buffer_t*, int time, int delta );
/* Number of additional clocks needed until n samples will be available.
If buffer cannot even hold n samples, returns number of clocks until buffer
becomes full. */
int blip_clocks_needed( const blip_buffer_t*, int samples_needed );
/* Ends current time frame of specified duration and make its samples available
(along with any still-unread samples) for reading with read_samples(), then
begins a new time frame at the end of the current frame. */
void blip_end_frame( blip_buffer_t*, int duration );
/* Number of samples available for reading with read(). */
int blip_samples_avail( const blip_buffer_t* );
/* Reads at most n samples out of buffer into out, removing them from from
the buffer. Returns number of samples actually read and removed. If stereo is
true, increments 'out' one extra time after writing each sample, to allow
easy interleving of two channels into a stereo output buffer. */
int blip_read_samples( blip_buffer_t*, short out [], int n, int stereo );
#ifdef __cplusplus
}
#endif
#endif

View File

@ -21,17 +21,17 @@
25/04/07 Eke-Eke (Genesis Plus GX)
- Removed stereo GG support (unused)
- Rade SN76489_Update outputs 16bits mono samples
- Made SN76489_Update outputs 16bits mono samples
- Replaced volume table with VGM plugin's one
05/01/09 Eke-Eke (Genesis Plus GX)
- Modified Cut-Off frequency (according to Steve Snake: http://www.smspower.org/forums/viewtopic.php?t=1746)
25/05/09 Eke-Eke (Genesis Plus GX)
24/08/10 Eke-Eke (Genesis Plus GX)
- Removed multichip support (unused)
- Removed alternate volume table, panning & mute support (unused)
- Removed configurable Feedback and Shift Register Width (always use Sega ones)
- Added linear resampling using Blip Buffer (Blargg's implementation: http://www.smspower.org/forums/viewtopic.php?t=11376)
- Added linear resampling using Blip Buffer (based on Blargg's implementation: http://www.smspower.org/forums/viewtopic.php?t=11376)
*/
#include "shared.h"