rem: dma_buffer_size = AudioCtrl->ahiac_MaxBuffSamples * sizeof( WORD );
context: intAHIsub_Start( REG( d0, ULONG Flags ),                 REG( a2, struct AHIAudioCtrlDrv* AudioCtrl ) ){  AHIsub_Stop( Flags, AudioCtrl );  if(Flags & AHISF_PLAY)  {    ULONG dma_buffer_size;    ULONG dma_sample_frame_size;        /* Stop playback, free old buffers (if any) */        AHIsub_Stop( AHISF_PLAY, AudioCtrl );    /* Update cached/syncronized variables */    AHIsub_Update( AHISF_PLAY, AudioCtrl );        /* Allocate a new mixing buffer */    dd->mixbuffer = AllocVec( AudioCtrl->ahiac_BuffSize,			      MEMF_ANY | MEMF_PUBLIC );    if( dd->mixbuffer == NULL )    {      KPrintF( DRIVER_NAME ": Unable to allocate %ld bytes for mixing buffer.\n",	       AudioCtrl->ahiac_BuffSize );      return AHIE_NOMEM;    }    /* Allocate a voice buffer large enough for 16-bit double-buffered       playback (mono or stereo) */    if( AudioCtrl->ahiac_Flags & AHIACF_STEREO )    {      dma_buffer_size = AudioCtrl->ahiac_MaxBuffSamples * sizeof( WORD ) * 2;      dma_sample_frame_size = 4;    }    else    {      dma_buffer_size = AudioCtrl->ahiac_MaxBuffSamples * sizeof( WORD );      dma_sample_frame_size = 2;    }    if( emu10k1_voice_alloc_buffer( &dd->card,				    &dd->voice.mem,				    ( dma_buffer_size * 2 + PAGE_SIZE - 1 )				    / PAGE_SIZE ) < 0 )    {      KPrintF( DRIVER_NAME ": Unable to allocate voice buffer.\n" );      return AHIE_NOMEM;    }    dd->voice_buffer_allocated = TRUE;    memset( dd->voice.mem.addr, 0, dma_buffer_size * 2 );    dd->voice.usage = VOICE_USAGE_PLAYBACK;    if( AudioCtrl->ahiac_Flags & AHIACF_STEREO )    {      dd->voice.flags = VOICE_FLAGS_STEREO | VOICE_FLAGS_16BIT;    }    else    {      dd->voice.flags = VOICE_FLAGS_16BIT;    }    if( emu10k1_voice_alloc( &dd->card, &dd->voice ) < 0 )    {      KPrintF( DRIVER_NAME ":Unable to allocate voice.\n" );      return AHIE_UNKNOWN;    }    dd->voice_allocated = TRUE;        dd->voice.initial_pitch = (u16) ( srToPitch( AudioCtrl->ahiac_MixFreq ) >> 8 );    dd->voice.pitch_target  = samplerate_to_linearpitch( AudioCtrl->ahiac_MixFreq );    DPD(2, "Initial pitch --> %#x\n", dd->voice.initial_pitch);    /* start, startloop and endloop is unit sample frames, not bytes */    dd->voice.start     = ( ( dd->voice.mem.emupageindex << 12 )			    / dma_sample_frame_size );    dd->voice.endloop   = dd->voice.start + AudioCtrl->ahiac_MaxBuffSamples * 2;    dd->voice.startloop = dd->voice.start;        /* Make interrupt routine start at the correct location */    dd->current_position = dd->current_length;    dd->current_buffer   = ( dd->voice.mem.addr +			     dd->current_position * dma_sample_frame_size );        if( dd->voice.flags & VOICE_FLAGS_STEREO )    {      dd->voice.params[0].send_a             = 0xff;      dd->voice.params[0].send_b             = 0x0;      dd->voice.params[0].send_c             = 0x0;      dd->voice.params[0].send_d             = 0x0;      dd->voice.params[0].send_routing       = 0x3210;      dd->voice.params[0].volume_target      = 0xffff;      dd->voice.params[0].initial_fc         = 0xff;      dd->voice.params[0].initial_attn       = 0x00;      dd->voice.params[0].byampl_env_sustain = 0x7f;      dd->voice.params[0].byampl_env_decay   = 0x7f;      dd->voice.params[1].send_a             = 0x00;      dd->voice.params[1].send_b             = 0xff;      dd->voice.params[1].send_c             = 0x00;      dd->voice.params[1].send_d             = 0x00;      dd->voice.params[1].send_routing       = 0x3210;      dd->voice.params[1].volume_target      = 0xffff;      dd->voice.params[1].initial_fc         = 0xff;      dd->voice.params[1].initial_attn       = 0x00;      dd->voice.params[1].byampl_env_sustain = 0x7f;      dd->voice.params[1].byampl_env_decay   = 0x7f;    }    else    {      dd->voice.params[0].send_a             = 0xff;      dd->voice.params[0].send_b             = 0xff;      dd->voice.params[0].send_c             = 0x0;      dd->voice.params[0].send_d             = 0x0;      dd->voice.params[0].send_routing       = 0x3210;      dd->voice.params[0].volume_target      = 0xffff;      dd->voice.params[0].initial_fc         = 0xff;      dd->voice.params[0].initial_attn       = 0x00;      dd->voice.params[0].byampl_env_sustain = 0x7f;      dd->voice.params[0].byampl_env_decay   = 0x7f;    }    DPD(2, "voice: startloop=%x, endloop=%x\n",	dd->voice.startloop, dd->voice.endloop);	        emu10k1_voice_playback_setup( &dd->voice );    DPF(2, "emu10k1_waveout_start()\n");    dd->mixing_enabled = TRUE;        /* Enable timer interrupts (1 kHz) */    emu10k1_writefn0( &dd->card, TIMER_RATE, 48000 / 1000 );    emu10k1_irq_enable( &dd->card, INTE_INTERVALTIMERENB );        emu10k1_voices_start( &dd->voice, 1, 0 );  }  if( Flags & AHISF_RECORD )  {    return AHIE_UNKNOWN;  }  return AHIE_OK;}