Subversion Repositories Games.Carmageddon

Rev

Rev 18 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include "3d.h"
  2. #include "audio.h"
  3. #include "harness/trace.h"
  4. #include "resource.h"
  5. #include "s3sound.h"
  6. #include <math.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9.  
  10. tS3_vector3 gS3_listener_position_old;
  11. tS3_vector3 gS3_listener_position_now;
  12. tS3_vector3 gS3_listener_vel_now;
  13. tS3_vector3 gS3_listener_left_now;
  14.  
  15. void* gS3_listener_pos_ptr;
  16. void* gS3_listener_vel_ptr;
  17. void* gS3_listener_left_ptr;
  18.  
  19. int gS3_listener_pos_is_brender;
  20. int gS3_listener_vel_is_brender;
  21. int gS3_listener_left_is_brender;
  22.  
  23. float dword_531D9C;
  24. float flt_531D7C;
  25. float flt_531D98;
  26.  
  27. void S3Set3DSoundEnvironment(float a1, float a2, float a3) {
  28.     float tmp;
  29.  
  30.     if (a1 == -1.0f) {
  31.         a1 = 0.25f;
  32.     }
  33.     if (a2 == -1.0f) {
  34.         a2 = 1.2f;
  35.     }
  36.     if (a3 == -1.0f) {
  37.         a3 = 130000.0f;
  38.     }
  39.     dword_531D9C = a1;
  40.     tmp = sqrtf(a3 / a2);
  41.     flt_531D7C = tmp;
  42.     flt_531D98 = tmp * dword_531D9C;
  43.     gS3_listener_position_now.x = 0.0;
  44.     gS3_listener_position_now.y = 0.0;
  45.     gS3_listener_position_now.z = 0.0;
  46.     gS3_listener_vel_now.x = 0.0;
  47.     gS3_listener_vel_now.y = 0.0;
  48.     gS3_listener_vel_now.z = 0.0;
  49.     gS3_listener_left_now.x = 0.0;
  50.     gS3_listener_left_now.y = 0.0;
  51.     gS3_listener_left_now.z = 0.0;
  52. }
  53.  
  54. void S3CopyVector3(void* a1, void* a2, int pBrender_vector) {
  55.     if (pBrender_vector) {
  56.         S3CopyBrVector3((tS3_vector3*)a1, (br_vector3*)a2);
  57.     } else {
  58.         S3CopyS3Vector3((tS3_vector3*)a1, (tS3_vector3*)a2);
  59.     }
  60. }
  61.  
  62. void S3CopyBrVector3(tS3_vector3* a1, br_vector3* a2) {
  63.     a1->x = a2->v[0];
  64.     a1->y = a2->v[1];
  65.     a1->z = a2->v[2];
  66. }
  67.  
  68. void S3CopyS3Vector3(tS3_vector3* a1, tS3_vector3* a2) {
  69.     *a1 = *a2;
  70. }
  71.  
  72. void S3BindListenerPositionBRender(br_vector3* pos) {
  73.     gS3_listener_pos_ptr = pos;
  74.     gS3_listener_pos_is_brender = 1;
  75.     S3CopyBrVector3(&gS3_listener_position_old, pos);
  76. }
  77.  
  78. void S3BindListenerVelocityBRender(br_vector3* vel) {
  79.     gS3_listener_vel_ptr = vel;
  80.     gS3_listener_vel_is_brender = 1;
  81. }
  82.  
  83. void S3BindListenerLeftBRender(br_vector3* left) {
  84.     gS3_listener_left_ptr = left;
  85.     gS3_listener_left_is_brender = 1;
  86. }
  87.  
  88. void S3UpdateListenerVectors(void) {
  89.     if (gS3_listener_pos_ptr) {
  90.         S3CopyVector3(&gS3_listener_position_now, gS3_listener_pos_ptr, gS3_listener_pos_is_brender);
  91.     }
  92.     if (gS3_listener_vel_ptr) {
  93.         S3CopyVector3(&gS3_listener_vel_now, gS3_listener_vel_ptr, gS3_listener_vel_is_brender);
  94.     } else {
  95.         gS3_listener_vel_now.x = (gS3_listener_position_now.x - gS3_listener_position_old.x) / 1000.0 * gS3_service_time_delta;
  96.         gS3_listener_vel_now.y = (gS3_listener_position_now.y - gS3_listener_position_old.y) / 1000.0 * gS3_service_time_delta;
  97.         gS3_listener_vel_now.z = (gS3_listener_position_now.z - gS3_listener_position_old.z) / 1000.0 * gS3_service_time_delta;
  98.         gS3_listener_position_old = gS3_listener_position_now;
  99.     }
  100.     if (gS3_listener_left_ptr) {
  101.         S3CopyVector3(&gS3_listener_left_now, gS3_listener_left_ptr, gS3_listener_left_is_brender);
  102.     } else {
  103.         gS3_listener_left_now.x = gS3_listener_position_now.x + 1.0;
  104.         gS3_listener_left_now.y = gS3_listener_position_now.y;
  105.         gS3_listener_left_now.z = gS3_listener_position_now.z;
  106.     }
  107. }
  108.  
  109. void S3ServiceAmbientSoundSources(void) {
  110.     tS3_sound_source* s; // [esp+Ch] [ebp-4h]
  111.  
  112.     for (s = gS3_sound_sources; s; s = s->next) {
  113.         if (s->ambient == 0) {
  114.             continue;
  115.         }
  116.         if (s->period > 0) {
  117.             s->time_since_last_played += gS3_service_time_delta;
  118.         }
  119.         if (s->channel && s->channel->tag != s->tag) {
  120.             S3StopChannel(s->channel);
  121.             s->channel = NULL;
  122.             s->tag = 0;
  123.         }
  124.  
  125.         if (s->channel != NULL) {
  126.             continue;
  127.         }
  128.         if (s->time_since_last_played <= s->period || !s->period || s->tag) {
  129.             if ((s->ambient_repeats == 0 || s->period == 0) && s->tag == 0) {
  130.                 if (s->volume > 0 && S3ServiceSoundSource(s) == 0) {
  131.                     s->channel = NULL;
  132.                     s->tag = 0;
  133.                 }
  134.                 s->time_since_last_played = 0;
  135.             }
  136.         } else {
  137.             if (s->volume > 0 && S3ServiceSoundSource(s) == 0) {
  138.                 s->channel = NULL;
  139.                 s->tag = 0;
  140.             }
  141.             s->time_since_last_played = 0;
  142.         }
  143.     }
  144. }
  145.  
  146. int S3UpdateSpatialSound(tS3_channel* chan) {
  147.     int close_enough_to_play; // [esp+10h] [ebp-4h]
  148.  
  149.     if (chan->sound_source_ptr && chan->sound_source_ptr->ambient) {
  150.         close_enough_to_play = S3Calculate3D(chan, 1);
  151.     } else {
  152.         close_enough_to_play = S3Calculate3D(chan, 0);
  153.     }
  154.     if (close_enough_to_play) {
  155.         S3SyncSampleVolumeAndPan(chan);
  156.         S3SyncSampleRate(chan);
  157.     }
  158.     return close_enough_to_play;
  159. }
  160.  
  161. int S3BindAmbientSoundToOutlet(tS3_outlet* pOutlet, int pSound, tS3_sound_source* source, float pMax_distance, int pPeriod, int pRepeats, int pVolume, int pPitch, int pSpeed) {
  162.     tS3_descriptor* desc; // [esp+Ch] [ebp-4h]
  163.  
  164.     if (!gS3_enabled) {
  165.         return 0;
  166.     }
  167.     if (!source) {
  168.         return eS3_error_nonexistant_source;
  169.     }
  170.     desc = S3GetDescriptorByID(pSound);
  171.     if (!desc) {
  172.         return eS3_error_bad_id;
  173.     }
  174.     if (desc->type != eS3_ST_sample) {
  175.         return 0;
  176.     }
  177.     if ((!desc->sound_data || (desc->flags & 2) != 0) && !S3LoadSample(pSound)) {
  178.         return eS3_error_load_sound;
  179.     }
  180.     if (pVolume > 255) {
  181.         pVolume = 255;
  182.     }
  183.     if (pVolume < 0) {
  184.         pVolume = 128;
  185.     }
  186.     if (pPitch < 0) {
  187.         pPitch = 0x10000;
  188.     }
  189.     if (pSpeed < 0) {
  190.         pSpeed = 0x10000;
  191.     }
  192.     source->bound_outlet = pOutlet;
  193.     source->sound_id = pSound;
  194.     source->volume = pVolume;
  195.     source->max_distance_sq = pMax_distance;
  196.     source->period = pPeriod;
  197.     source->pitch = pPitch;
  198.     source->speed = pSpeed;
  199.     source->ambient = 1;
  200.  
  201.     source->ambient_repeats = pRepeats < 0 ? 0 : pRepeats;
  202.     source->time_since_last_played = pPeriod;
  203.     source->channel = NULL;
  204.     source->tag = 0;
  205.     return eS3_error_none;
  206. }
  207.  
  208. void S3UpdateSoundSource(tS3_outlet* outlet, tS3_sound_tag tag, tS3_sound_source* src, float pMax_distance_squared, int pPeriod, tS3_repeats pAmbient_repeats, tS3_volume pVolume, int pPitch, tS3_speed pSpeed) {
  209.     tS3_channel* chan;    // [esp+28h] [ebp-Ch]
  210.     tS3_descriptor* desc; // [esp+2Ch] [ebp-8h]
  211.     int is_sample;        // [esp+30h] [ebp-4h]
  212.  
  213.     is_sample = 0;
  214.     if (!gS3_enabled || !src) {
  215.         return;
  216.     }
  217.     chan = src->channel;
  218.     if (tag != -1 && src->sound_id != tag) {
  219.         desc = S3GetDescriptorByID(tag);
  220.         if (desc == NULL) {
  221.             return;
  222.         }
  223.         if (desc->type == eS3_ST_sample) {
  224.             src->sound_id = tag;
  225.             if ((desc->sound_data == NULL || (desc->flags & 2) != 0) && !S3LoadSample(tag)) {
  226.                 return;
  227.             }
  228.             is_sample = 1;
  229.         }
  230.     }
  231.     if (pSpeed != -1) {
  232.         if (pSpeed < 1) {
  233.             pSpeed = 0x10000;
  234.         }
  235.         src->speed = pSpeed;
  236.     }
  237.     if (pPitch != -1) {
  238.         if (pPitch < 1) {
  239.             pPitch = 0x10000;
  240.         }
  241.         src->pitch = pPitch;
  242.         if (chan && chan->descriptor && chan->descriptor->type == eS3_ST_sample) {
  243.             chan->initial_pitch = S3IRandomBetweenLog(chan->descriptor->min_pitch, chan->descriptor->max_pitch, ((tS3_sample*)chan->descriptor->sound_data)->rate);
  244.             chan->initial_pitch *= ldexpf(src->pitch, -16);
  245.             chan->initial_pitch *= ldexpf(src->speed, -16);
  246.         }
  247.     }
  248.     if (pAmbient_repeats != -1) {
  249.         src->ambient_repeats = MAX(0, pAmbient_repeats);
  250.         if (chan) {
  251.             chan->repetitions = src->ambient_repeats;
  252.         }
  253.     }
  254.     if (pMax_distance_squared != -1.0f) {
  255.         src->max_distance_sq = pMax_distance_squared;
  256.         if (chan) {
  257.             chan->pMax_distance_squared = pMax_distance_squared;
  258.         }
  259.     }
  260.     if (pPeriod != -1) {
  261.         src->period = pPeriod;
  262.     }
  263.     if (pVolume != -1) {
  264.         if (pVolume > 255) {
  265.             pVolume = 255;
  266.         }
  267.         if (pVolume < 0) {
  268.             pVolume = 128;
  269.         }
  270.         if (src->volume != pVolume) {
  271.             src->volume = pVolume;
  272.         }
  273.         if (chan) {
  274.             chan->initial_volume = pVolume;
  275.         }
  276.     }
  277.     if (chan) {
  278.         if (chan->sound_source_ptr != src) {
  279.             S3StopChannel(chan);
  280.         }
  281.         if (!pVolume || is_sample) {
  282.             chan->spatial_sound = 0;
  283.             chan->needs_service = 1;
  284.             S3StopChannel(chan);
  285.             src->channel = 0;
  286.             src->tag = 0;
  287.         }
  288.     }
  289. }
  290.  
  291. void S3StopSoundSource(tS3_sound_source* src) {
  292.     if (!gS3_enabled) {
  293.         return;
  294.     }
  295.     if (src) {
  296.         if (src->channel && src->tag && src->channel->tag == src->tag) {
  297.             src->channel->termination_reason = eS3_tr_stopped;
  298.             src->channel->spatial_sound = 0;
  299.             S3StopChannel(src->channel);
  300.             src->channel->sound_source_ptr = NULL;
  301.         }
  302.         src->ambient = 0;
  303.     }
  304. }
  305.  
  306. tS3_sound_tag S3ServiceSoundSource(tS3_sound_source* src) {
  307.     tS3_channel* chan;    // [esp+30h] [ebp-10h]
  308.     tS3_outlet* outlet;   // [esp+34h] [ebp-Ch]
  309.     tS3_descriptor* desc; // [esp+3Ch] [ebp-4h]
  310.  
  311.     if (!src) {
  312.         return 0;
  313.     }
  314.     if (!gS3_enabled || !src->ambient) {
  315.         src->tag = 0;
  316.         src->channel = 0;
  317.         return 0;
  318.     }
  319.     outlet = src->bound_outlet;
  320.     desc = S3GetDescriptorByID(src->sound_id);
  321.     if (desc == NULL) {
  322.         gS3_last_error = eS3_error_bad_id;
  323.         return 0;
  324.     }
  325.     if (desc->type) {
  326.         return 0;
  327.     }
  328.     memset(&gS3_channel_template, 0, sizeof(gS3_channel_template));
  329.     gS3_channel_template.initial_volume = src->volume;
  330.     gS3_channel_template.rate = S3IRandomBetweenLog(desc->min_pitch, desc->max_pitch, ((tS3_sample*)desc->sound_data)->rate);
  331.     if (src->pitch < 0) {
  332.         src->pitch = 0x10000;
  333.     }
  334.     if (src->speed < 0) {
  335.         src->speed = 0x10000;
  336.     }
  337.  
  338.     gS3_channel_template.rate = ldexp(src->pitch, -16) * gS3_channel_template.rate;
  339.     if (!outlet->independent_pitch) {
  340.         gS3_channel_template.rate = ldexp(src->speed, -16) * gS3_channel_template.rate;
  341.     }
  342.     gS3_channel_template.initial_pitch = gS3_channel_template.rate;
  343.     gS3_channel_template.sound_source_ptr = src;
  344.     if (!src->velocity_ptr) {
  345.         S3CopyVector3(&gS3_channel_template.lastpos, src->position_ptr, src->brender_vector);
  346.     }
  347.     gS3_channel_template.pMax_distance_squared = src->max_distance_sq;
  348.     if (S3Calculate3D(&gS3_channel_template, 1) == 0) {
  349.         src->tag = 0;
  350.         src->channel = NULL;
  351.         return 0;
  352.     }
  353.  
  354.     chan = S3AllocateChannel(outlet, desc->priority * (gS3_channel_template.right_volume + gS3_channel_template.left_volume + 1));
  355.     if (chan == NULL) {
  356.         gS3_last_error = eS3_error_channel_alloc;
  357.         src->tag = 0;
  358.         src->channel = NULL;
  359.         return 0;
  360.     }
  361.  
  362.     if ((desc->sound_data && (desc->flags & 2) == 0) || S3LoadSample(src->sound_id)) {
  363.         chan->left_volume = gS3_channel_template.left_volume * chan->volume_multiplier;
  364.         chan->right_volume = gS3_channel_template.right_volume * chan->volume_multiplier;
  365.         chan->rate = gS3_channel_template.rate;
  366.         chan->position.x = gS3_channel_template.position.x;
  367.         chan->position.y = gS3_channel_template.position.y;
  368.         chan->position.z = gS3_channel_template.position.z;
  369.         chan->velocity.x = gS3_channel_template.velocity.x;
  370.         chan->velocity.y = gS3_channel_template.velocity.y;
  371.         chan->velocity.z = gS3_channel_template.velocity.z;
  372.         chan->lastpos.x = gS3_channel_template.lastpos.x;
  373.         chan->lastpos.y = gS3_channel_template.lastpos.y;
  374.         chan->lastpos.z = gS3_channel_template.lastpos.z;
  375.         chan->initial_volume = gS3_channel_template.initial_volume;
  376.         chan->initial_pitch = gS3_channel_template.initial_pitch;
  377.         chan->pMax_distance_squared = gS3_channel_template.pMax_distance_squared;
  378.         chan->spatial_sound = 2;
  379.         chan->sound_source_ptr = src;
  380.         chan->descriptor = desc;
  381.         chan->tag = S3GenerateTag(outlet);
  382.         chan->repetitions = src->ambient_repeats;
  383.         chan->needs_service = 0;
  384.         chan->termination_reason = 0;
  385.         S3ExecuteSampleFilterFuncs(chan);
  386.         if (S3PlaySample(chan)) {
  387.             src->tag = chan->tag;
  388.             src->channel = chan;
  389.             return chan->tag;
  390.         } else {
  391.             chan->needs_service = 1;
  392.             gS3_last_error = eS3_error_start_sound;
  393.             return 0;
  394.         }
  395.     } else {
  396.         gS3_last_error = eS3_error_load_sound;
  397.         chan->needs_service = 1;
  398.         return 0;
  399.     }
  400. }
  401.  
  402. tS3_sound_tag S3StartSound3D(tS3_outlet* pOutlet, tS3_sound_id pSound, tS3_vector3* pInitial_position, tS3_vector3* pInitial_velocity, tS3_repeats pRepeats, tS3_volume pVolume, tS3_pitch pPitch, tS3_speed pSpeed) {
  403.     tS3_channel* chan;    // [esp+30h] [ebp-Ch]
  404.     tS3_descriptor* desc; // [esp+38h] [ebp-4h]
  405.  
  406.     if (!gS3_enabled) {
  407.         return 0;
  408.     }
  409.     desc = S3GetDescriptorByID(pSound);
  410.     if (!desc) {
  411.         gS3_last_error = eS3_error_bad_id;
  412.         return 0;
  413.     }
  414.     if (desc->type != eS3_ST_sample) {
  415.         return 0;
  416.     }
  417.  
  418.     if ((desc->sound_data == NULL || (desc->flags & 2) != 0) && S3LoadSample(pSound) == 0) {
  419.         gS3_last_error = eS3_error_load_sound;
  420.         return 0;
  421.     }
  422.     if (pVolume > 255) {
  423.         pVolume = 255;
  424.     }
  425.     if (pVolume < 0) {
  426.         pVolume = S3IRandomBetween(desc->min_volume, desc->max_volume, 128);
  427.     }
  428.     memset(&gS3_channel_template, 0, sizeof(gS3_channel_template));
  429.     gS3_channel_template.volume_multiplier = 1.0;
  430.     gS3_channel_template.sound_source_ptr = 0;
  431.     gS3_channel_template.pMax_distance_squared = 150.0;
  432.     gS3_channel_template.right_volume = pVolume;
  433.     gS3_channel_template.left_volume = pVolume;
  434.     gS3_channel_template.initial_volume = pVolume;
  435.     gS3_channel_template.rate = S3IRandomBetweenLog(desc->min_pitch, desc->max_pitch, ((tS3_sample*)desc->sound_data)->rate);
  436.     if (pPitch == -1) {
  437.         pPitch = 0x10000;
  438.     }
  439.     if (pSpeed == -1) {
  440.         pSpeed = 0x10000;
  441.     }
  442.     gS3_channel_template.rate = ldexpf(pPitch, -16) * gS3_channel_template.rate;
  443.     if (!pOutlet->independent_pitch) {
  444.         gS3_channel_template.rate = ldexpf(pSpeed, -16) * gS3_channel_template.rate;
  445.     }
  446.     gS3_channel_template.initial_pitch = gS3_channel_template.rate;
  447.     gS3_channel_template.position = *pInitial_position;
  448.     gS3_channel_template.velocity = *pInitial_velocity;
  449.  
  450.     if (S3Calculate3D(&gS3_channel_template, 0) == 0) {
  451.         return 0;
  452.     }
  453.     chan = S3AllocateChannel(pOutlet, desc->priority * (gS3_channel_template.right_volume + gS3_channel_template.left_volume + 1));
  454.     if (chan) {
  455.         chan->left_volume = gS3_channel_template.left_volume * chan->volume_multiplier;
  456.         chan->right_volume = gS3_channel_template.right_volume * chan->volume_multiplier;
  457.         chan->rate = gS3_channel_template.rate;
  458.         chan->spatial_sound = 1;
  459.         chan->sound_source_ptr = 0;
  460.         chan->descriptor = desc;
  461.         chan->needs_service = 0;
  462.         chan->termination_reason = 0;
  463.         chan->position = gS3_channel_template.position;
  464.         chan->lastpos = gS3_channel_template.lastpos;
  465.         chan->velocity = gS3_channel_template.velocity;
  466.         chan->repetitions = MAX(pRepeats, 0);
  467.         chan->tag = S3GenerateTag(pOutlet);
  468.         chan->initial_volume = gS3_channel_template.initial_volume;
  469.         chan->initial_pitch = gS3_channel_template.initial_pitch;
  470.         chan->pMax_distance_squared = gS3_channel_template.pMax_distance_squared;
  471.         S3ExecuteSampleFilterFuncs(chan);
  472.         if (S3PlaySample(chan) != 0) {
  473.             return chan->tag;
  474.         } else {
  475.             chan->needs_service = 1;
  476.             gS3_last_error = eS3_error_start_sound;
  477.             return 0;
  478.         }
  479.     } else {
  480.         gS3_last_error = eS3_error_channel_alloc;
  481.         return 0;
  482.     }
  483. }
  484.  
  485. int S3Calculate3D(tS3_channel* chan, int pIs_ambient) {
  486.     float attenuation;                  // [esp+2Ch] [ebp-1Ch]
  487.     float doppler_shift;                // [esp+30h] [ebp-18h]
  488.     float vol_multiplier;               // [esp+38h] [ebp-10h]
  489.     tS3_sound_source* sound_source_ptr; // [esp+3Ch] [ebp-Ch]
  490.     float dist_squared;                 // [esp+40h] [ebp-8h]
  491.     float dist;                         // [esp+44h] [ebp-4h]
  492.  
  493.     sound_source_ptr = chan->sound_source_ptr;
  494.     if (sound_source_ptr) {
  495.         if (sound_source_ptr->position_ptr) {
  496.             S3CopyVector3(&chan->position, sound_source_ptr->position_ptr, sound_source_ptr->brender_vector);
  497.         }
  498.         if (sound_source_ptr->velocity_ptr) {
  499.             S3CopyVector3(&chan->velocity, sound_source_ptr->velocity_ptr, sound_source_ptr->brender_vector);
  500.         } else {
  501.             chan->velocity.x = (chan->position.x - chan->lastpos.x) / 1000.0f * gS3_service_time_delta;
  502.             chan->velocity.y = (chan->position.y - chan->lastpos.y) / 1000.0f * gS3_service_time_delta;
  503.             chan->velocity.z = (chan->position.z - chan->lastpos.z) / 1000.0f * gS3_service_time_delta;
  504.             chan->lastpos = chan->position;
  505.         }
  506.     }
  507.     dist_squared = (chan->position.z - gS3_listener_position_now.z) * (chan->position.z - gS3_listener_position_now.z)
  508.         + (chan->position.x - gS3_listener_position_now.x) * (chan->position.x - gS3_listener_position_now.x)
  509.         + (chan->position.y - gS3_listener_position_now.y) * (chan->position.y - gS3_listener_position_now.y);
  510.     if (dist_squared < 0) {
  511.         dist_squared = dist_squared * -1.0;
  512.     }
  513.  
  514.     if (chan->pMax_distance_squared < dist_squared) {
  515.         return 0;
  516.     }
  517.     if (dist_squared == 0.0f) {
  518.         dist = 0.0f;
  519.     } else {
  520.         dist = sqrtf(dist_squared);
  521.     }
  522.     if (pIs_ambient) {
  523.         doppler_shift = 1.0f - ((chan->position.z - gS3_listener_position_now.z) * (chan->velocity.z - gS3_listener_vel_now.z) + (chan->velocity.y - gS3_listener_vel_now.y) * (chan->position.y - gS3_listener_position_now.y) + (chan->position.x - gS3_listener_position_now.x) * (chan->velocity.x - gS3_listener_vel_now.x)) / dist / flt_531D98;
  524.         if (doppler_shift > 2.0f) {
  525.             doppler_shift = 2.0f;
  526.         } else if (doppler_shift < 0.5f) {
  527.             doppler_shift = 0.5;
  528.         }
  529.         chan->rate = chan->initial_pitch * doppler_shift;
  530.     } else {
  531.         chan->rate = chan->initial_pitch;
  532.     }
  533.  
  534.     vol_multiplier = 1.0f / (dist / 6.0f + 1.0f);
  535.     if (!gS3_inside_cockpit) {
  536.         vol_multiplier = vol_multiplier * 1.3f;
  537.     }
  538.     attenuation = (chan->position.z - gS3_listener_position_now.z) * gS3_listener_left_now.z
  539.         + (chan->position.y - gS3_listener_position_now.y) * gS3_listener_left_now.y
  540.         + (chan->position.x - gS3_listener_position_now.x) * gS3_listener_left_now.x;
  541.     if (attenuation < -1.0f) {
  542.         attenuation -= ceil(attenuation);
  543.     }
  544.     if (attenuation > 1.0f) {
  545.         attenuation -= floor(attenuation);
  546.     }
  547.     chan->left_volume = (attenuation + 1.0f) / 2.0f * ((double)chan->initial_volume * vol_multiplier) * chan->volume_multiplier;
  548.     if (chan->left_volume < 0) {
  549.         chan->left_volume = 0;
  550.     }
  551.     chan->right_volume = (1.0f - attenuation) / 2.0f * ((double)chan->initial_volume * vol_multiplier) * chan->volume_multiplier;
  552.     if (chan->right_volume < 0) {
  553.         chan->right_volume = 0;
  554.     }
  555.     if (chan->left_volume > 255) {
  556.         chan->left_volume = 255;
  557.     }
  558.     if (chan->right_volume > 255) {
  559.         chan->right_volume = 255;
  560.     }
  561.     return 1;
  562. }
  563.