effect_stereoreverse.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 11 Sep 2001 19:14:36 +0000
changeset 113 c0c3018bd787
child 114 83ab4ef4458b
permissions -rw-r--r--
Ryan C. Gordon - Tue Sep 11 12:05:54 PDT 2001
* Reworked playwave.c to make it more useful as a mixer testbed
* Added a realtime sound effect API to SDL_mixer.h
* Added the following standard sound effects:
panning, distance attenuation, basic positional audio, stereo reversal
* Added API for mixer versioning: Mix_Linked_Version() and MIX_VERSION()
slouken@113
     1
/*
slouken@113
     2
    MIXERLIB:  An audio mixer library based on the SDL library
slouken@113
     3
    Copyright (C) 1997-1999  Sam Lantinga
slouken@113
     4
slouken@113
     5
    This library is free software; you can redistribute it and/or
slouken@113
     6
    modify it under the terms of the GNU Library General Public
slouken@113
     7
    License as published by the Free Software Foundation; either
slouken@113
     8
    version 2 of the License, or (at your option) any later version.
slouken@113
     9
slouken@113
    10
    This library is distributed in the hope that it will be useful,
slouken@113
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@113
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@113
    13
    Library General Public License for more details.
slouken@113
    14
slouken@113
    15
    You should have received a copy of the GNU Library General Public
slouken@113
    16
    License along with this library; if not, write to the Free
slouken@113
    17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
slouken@113
    18
slouken@113
    19
    This file by Ryan C. Gordon (icculus@linuxgames.com)
slouken@113
    20
slouken@113
    21
    These are some internally supported special effects that use SDL_mixer's
slouken@113
    22
    effect callback API. They are meant for speed over quality.  :)
slouken@113
    23
*/
slouken@113
    24
slouken@113
    25
/* $Id$ */
slouken@113
    26
slouken@113
    27
#include <stdio.h>
slouken@113
    28
#include <stdlib.h>
slouken@113
    29
#include <sys/time.h>
slouken@113
    30
#include <unistd.h>
slouken@113
    31
#include "SDL.h"
slouken@113
    32
#include "SDL_mixer.h"
slouken@113
    33
slouken@113
    34
#define __MIX_INTERNAL_EFFECT__
slouken@113
    35
#include "effects_internal.h"
slouken@113
    36
slouken@113
    37
/* profile code:
slouken@113
    38
    #include <sys/time.h>
slouken@113
    39
    #include <unistd.h>
slouken@113
    40
    struct timeval tv1;
slouken@113
    41
    struct timeval tv2;
slouken@113
    42
    
slouken@113
    43
    gettimeofday(&tv1, NULL);
slouken@113
    44
slouken@113
    45
        ... do your thing here ...
slouken@113
    46
slouken@113
    47
    gettimeofday(&tv2, NULL);
slouken@113
    48
    printf("%ld\n", tv2.tv_usec - tv1.tv_usec);
slouken@113
    49
*/
slouken@113
    50
slouken@113
    51
slouken@113
    52
slouken@113
    53
/*
slouken@113
    54
 * Stereo reversal effect...this one's pretty straightforward...
slouken@113
    55
 */
slouken@113
    56
slouken@113
    57
static void _Eff_reversestereo16(int chan, void *stream, int len, void *udata)
slouken@113
    58
{
slouken@113
    59
    /* 16 bits * 2 channels. */
slouken@113
    60
    Uint32 *ptr = (Uint32 *) stream;
slouken@113
    61
    int i;
slouken@113
    62
slouken@113
    63
    for (i = 0; i < len; i += sizeof (Uint32), ptr++) {
slouken@113
    64
        *ptr = (((*ptr) & 0xFFFF0000) >> 16) | (((*ptr) & 0x0000FFFF) << 16);
slouken@113
    65
    }
slouken@113
    66
}
slouken@113
    67
slouken@113
    68
slouken@113
    69
static void _Eff_reversestereo8(int chan, void *stream, int len, void *udata)
slouken@113
    70
{
slouken@113
    71
    /* 8 bits * 2 channels. */
slouken@113
    72
    Uint32 *ptr = (Uint32 *) stream;
slouken@113
    73
    int i;
slouken@113
    74
slouken@113
    75
    /* get the last two bytes if len is not divisible by four... */
slouken@113
    76
    if (len % sizeof (Uint32) != 0) {
slouken@113
    77
        Uint16 *p = (Uint16 *) (((Uint8 *) stream) + (len - 2));
slouken@113
    78
        *p = (((*p) & 0xFF00) >> 8) | (((*ptr) & 0x00FF) << 8);
slouken@113
    79
        len -= 2;
slouken@113
    80
    }
slouken@113
    81
slouken@113
    82
    for (i = 0; i < len; i += sizeof (Uint32), ptr++) {
slouken@113
    83
        *ptr = (((*ptr) & 0x0000FF00) >> 8) | (((*ptr) & 0x000000FF) << 8) |
slouken@113
    84
               (((*ptr) & 0xFF000000) >> 8) | (((*ptr) & 0x00FF0000) << 8);
slouken@113
    85
    }
slouken@113
    86
}
slouken@113
    87
slouken@113
    88
slouken@113
    89
int Mix_SetReverseStereo(int channel, int flip)
slouken@113
    90
{
slouken@113
    91
    Mix_EffectFunc_t f = NULL;
slouken@113
    92
    int channels;
slouken@113
    93
    Uint16 format;
slouken@113
    94
slouken@113
    95
    Mix_QuerySpec(NULL, &format, &channels);
slouken@113
    96
slouken@113
    97
    if (channels == 2) {
slouken@113
    98
        if ((format & 0xFF) == 16)
slouken@113
    99
            f = _Eff_reversestereo16;
slouken@113
   100
        else if ((format & 0xFF) == 8)
slouken@113
   101
            f = _Eff_reversestereo8;
slouken@113
   102
        else {
slouken@113
   103
            Mix_SetError("Unsupported audio format");
slouken@113
   104
            return(0);
slouken@113
   105
        }
slouken@113
   106
slouken@113
   107
        if (!flip) {
slouken@113
   108
            return(Mix_UnregisterEffect(channel, f));
slouken@113
   109
        } else {
slouken@113
   110
            return(Mix_RegisterEffect(channel, f, NULL, NULL));
slouken@113
   111
        }
slouken@113
   112
    }
slouken@113
   113
slouken@113
   114
    return(1);
slouken@113
   115
}
slouken@113
   116
slouken@113
   117
slouken@113
   118
/* end of effect_stereoreverse.c ... */
slouken@113
   119