📄 vlm5030.c
字号:
phase = PH_STOP;
goto phase_stop; /* continue to stop phase */
}
/* Set old target as new start of frame */
current_energy = old_energy;
current_pitch = old_pitch;
memcpy( current_k , old_k , sizeof(current_k) );
/* is this a zero energy frame? */
if (current_energy == 0)
{
/*printf("processing frame: zero energy\n");*/
target_energy = 0;
target_pitch = current_pitch;
memcpy( target_k , current_k , sizeof(target_k) );
}
else
{
/*printf("processing frame: Normal\n");*/
/*printf("*** Energy = %d\n",current_energy);*/
/*printf("proc: %d %d\n",last_fbuf_head,fbuf_head);*/
target_energy = new_energy;
target_pitch = new_pitch;
memcpy( target_k , new_k , sizeof(target_k) );
}
}
/* next interpolator */
/* Update values based on step values */
/*printf("\n");*/
interp_effect = (int)(interp_coeff[(FR_SIZE-1) - (interp_count%FR_SIZE)]);
current_energy += (target_energy - current_energy) / interp_effect;
if (old_pitch != 0)
current_pitch += (target_pitch - current_pitch) / interp_effect;
/*printf("*** Energy = %d\n",current_energy);*/
current_k[0] += (target_k[0] - current_k[0]) / interp_effect;
current_k[1] += (target_k[1] - current_k[1]) / interp_effect;
current_k[2] += (target_k[2] - current_k[2]) / interp_effect;
current_k[3] += (target_k[3] - current_k[3]) / interp_effect;
current_k[4] += (target_k[4] - current_k[4]) / interp_effect;
current_k[5] += (target_k[5] - current_k[5]) / interp_effect;
current_k[6] += (target_k[6] - current_k[6]) / interp_effect;
current_k[7] += (target_k[7] - current_k[7]) / interp_effect;
current_k[8] += (target_k[8] - current_k[8]) / interp_effect;
current_k[9] += (target_k[9] - current_k[9]) / interp_effect;
interp_count --;
}
/* calcrate digital filter */
if (old_energy == 0)
{
/* generate silent samples here */
current_val = 0x00;
}
else if (old_pitch == 0)
{
/* generate unvoiced samples here */
randbit = (rand () % 2) * 2 - 1;
current_val = (randbit * current_energy) / 4;
}
else
{
/* generate voiced samples here */
if (pitch_count < sizeof (chirptable))
current_val = (chirptable[pitch_count] * current_energy) / 256;
else
current_val = 0x00;
}
/* Lattice filter here */
u[10] = current_val;
u[9] = u[10] - ((current_k[9] * x[9]) / 32768);
u[8] = u[ 9] - ((current_k[8] * x[8]) / 32768);
u[7] = u[ 8] - ((current_k[7] * x[7]) / 32768);
u[6] = u[ 7] - ((current_k[6] * x[6]) / 32768);
u[5] = u[ 6] - ((current_k[5] * x[5]) / 32768);
u[4] = u[ 5] - ((current_k[4] * x[4]) / 32768);
u[3] = u[ 4] - ((current_k[3] * x[3]) / 32768);
u[2] = u[ 3] - ((current_k[2] * x[2]) / 32768);
u[1] = u[ 2] - ((current_k[1] * x[1]) / 32768);
u[0] = u[ 1] - ((current_k[0] * x[0]) / 32768);
x[9] = x[8] + ((current_k[8] * u[8]) / 32768);
x[8] = x[7] + ((current_k[7] * u[7]) / 32768);
x[7] = x[6] + ((current_k[6] * u[6]) / 32768);
x[6] = x[5] + ((current_k[5] * u[5]) / 32768);
x[5] = x[4] + ((current_k[4] * u[4]) / 32768);
x[4] = x[3] + ((current_k[3] * u[3]) / 32768);
x[3] = x[2] + ((current_k[2] * u[2]) / 32768);
x[2] = x[1] + ((current_k[1] * u[1]) / 32768);
x[1] = x[0] + ((current_k[0] * u[0]) / 32768);
x[0] = u[0];
/* clipping, buffering */
if (u[0] > 511)
buffer[buf_count] = 127;
else if (u[0] < -512)
buffer[buf_count] = -128;
else
buffer[buf_count] = u[0] >> 2;
buf_count++;
/* sample count */
sample_count--;
/* pitch */
pitch_count++;
if (pitch_count >= current_pitch )
pitch_count = 0;
/* size */
size--;
}
/* return;*/
}
/* stop phase */
phase_stop:
switch( phase )
{
case PH_SETUP:
sample_count -= size;
if( sample_count <= 0 )
{
/* pin_BSY = 1; */
phase = PH_WAIT;
}
break;
case PH_STOP:
sample_count -= size;
if( sample_count <= 0 )
{
pin_BSY = 0;
phase = PH_IDLE;
}
}
/* silent buffering */
while (size > 0)
{
buffer[buf_count++] = 0x00;
size--;
}
}
/* realtime update */
void VLM5030_update(void)
{
int newpos;
if (Machine->sample_rate == 0) return;
if( !sampling_mode )
{
/* docode mode */
newpos = cpu_scalebyfcount(buffer_len); /* get current position based on the timer */
if (newpos - sample_pos < MIN_SLICE)
return;
if (sample_pos < buffer_len)
vlm5030_process (outbuffer + sample_pos, newpos - sample_pos);
sample_pos = newpos;
}
else
{
/* sampling mode (check busy flag) */
if( pin_ST == 0 && pin_BSY == 1 )
{
if( osd_get_sample_status(channel+1) )
pin_BSY = 0;
}
}
}
/* get BSY pin level */
int VLM5030_BSY(void)
{
VLM5030_update();
return pin_BSY;
}
/* latch contoll data */
void VLM5030_data_w(int offset,int data)
{
latch_data = data;
}
/* set RST pin level : reset / set table address A8-A15 */
void VLM5030_RST (int pin )
{
if( pin_RST )
{
if( !pin )
{ /* H -> L : latch high address table */
pin_RST = 0;
/* table_h = latch_data * 256; */
table_h = 0;
}
}
else
{
if( pin )
{ /* L -> H : reset chip */
pin_RST = 1;
if( pin_BSY )
{
if( sampling_mode )
osd_stop_sample( channel+1 );
phase = PH_RESET;
pin_BSY = 0;
}
}
}
}
/* set VCU pin level : ?? unknown */
void VLM5030_VCU(int pin)
{
/* unknown */
intf->vcu = pin;
return;
}
/* set ST pin level : set table address A0-A7 / start speech */
void VLM5030_ST(int pin )
{
int table = table_h | latch_data;
if( pin_ST != pin )
{
/* pin level is change */
if( !pin )
{ /* H -> L */
pin_ST = 0;
/* start speech */
if (Machine->sample_rate == 0)
{
pin_BSY = 0;
return;
}
/* set play mode samplingfile or emulate */
sampling_mode = check_samplefile(table/2);
if( !sampling_mode )
{
VLM5030_update();
/* docode mode */
VLM5030_address = (((int)VLM5030_rom[table])<<8)|VLM5030_rom[table+1];
/* reset process status */
interp_count = sample_count = 0;
/* clear filter */
/* after 3 sampling start */
phase = PH_RUN;
}
else
{
/* sampling mode */
int num = table>>1;
osd_play_sample(channel+1,
Machine->samples->sample[num]->data,
Machine->samples->sample[num]->length,
Machine->samples->sample[num]->smpfreq,
Machine->samples->sample[num]->volume,
0);
}
}
else
{ /* L -> H */
pin_ST = 1;
/* setup speech , BSY on after 30ms? */
phase = PH_SETUP;
sample_count = 1; /* wait time for busy on */
pin_BSY = 1; /* */
}
}
}
/* start VLM5030 with sound rom */
/* speech_rom == 0 -> use sampling data mode */
int VLM5030_sh_start( struct VLM5030interface *interface )
{
intf = interface;
buffer_len = intf->baseclock / 440 / Machine->drv->frames_per_second;
emulation_rate = buffer_len * Machine->drv->frames_per_second;
sample_pos = 0;
pin_BSY = pin_RST = pin_ST = 0;
/* VLM5030_VCU(intf->vcu); */
VLM5030_rom = Machine->memory_region[intf->memory_region];
if ((outbuffer = malloc(buffer_len)) == 0)
{
return 1;
}
memset(outbuffer,0x80,buffer_len);
channel = get_play_channels(2);
return 0;
}
/* update VLM5030 */
void VLM5030_sh_update( void )
{
if (Machine->sample_rate == 0) return;
if( !sampling_mode )
{
if (sample_pos < buffer_len)
vlm5030_process (outbuffer + sample_pos, buffer_len - sample_pos);
sample_pos = 0;
osd_play_streamed_sample(channel,(signed char *)outbuffer,buffer_len,emulation_rate,intf->volume,OSD_PAN_CENTER);
}
}
/* update VLM5030 */
void VLM5030_sh_stop( void )
{
if (outbuffer != 0 )
{
free( outbuffer );
outbuffer = 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -