CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Mixing audio - INT speed problem

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Skirmitt



Joined: 19 May 2009
Posts: 60

View user's profile Send private message

Mixing audio - INT speed problem
PostPosted: Wed May 27, 2015 2:38 am     Reply with quote

I have a project that plays 2 sound files at once (mixed). There are large sounds stored on an SD card and small sounds stored in the flash of the PIC. I use a 18f2525 with the INTOSC at 32 MHz.

The sound from timer 1 needs to have a variable pitch. Timer 0 sound has fixed pitch.

Problem is that when I mix the sounds the pitch from timer 0 sounds not constant. I guess there is not enough time left to process everything. I did have to add HIGH priority to Timer 1 to fix the issue there. Would there be a way to fix it with timer 0 ?

Or am I at the max capabilities of the PIC.

Overclocking the PIC with crystal at 48 MHz did not help Confused

Code:

#int_timer0
timer0_isr()
{
set_timer0(65440);

//set_timer0( get_timer0() + 65440); //tried this also, did not work

if(playgear==1)
{
   dg=(int)gear[ig];
   ig++;
   if(ig==GEAR_LENGTH)
   {
      ig=0;     
      playgear=0;
      dg=128;
   }
}
}

#int_timer1 HIGH
void timer1_isr()
{
set_timer1(timerpit); //variable pitch

if (ReadPos != WritePos)
{     
     
    output=((int32)buffer1[ReadPos]+(int32)dr+(int32)db+(int32)dg)/4;
    output_b(output);

    int16 TempPos = ReadPos;
    TempPos++;
    if (TempPos == BUFF_SIZE)
        ReadPos = 0;
    else
        ReadPos = TempPos;       
}
}


Timer config:

Code:

setup_timer_0(t0_DIV_8 );     
setup_timer_1(t1_internal | t1_div_by_8 );
setup_timer_3(t3_internal | t3_div_by_8 );
enable_interrupts(int_timer0);
enable_interrupts(int_timer1);
enable_interrupts(int_timer3);
enable_interrupts(INT_RDA);
temtronic



Joined: 01 Jul 2010
Posts: 9100
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed May 27, 2015 4:55 am     Reply with quote

Don't know the 'format' of the 'music files' but I'll guess and say its beyond the PICs ability. There's a guy 'Black ???' that has a 1 bit sound program, been around for years, might be helpful.
In the 'old days' I'd just slap an 8 bit ISA sound card onto an '877. At 20 Megs it could handle the data transfers but memory was the 'bottleneck'. Yeesh that was 15-20 years ago....

Jay
Skirmitt



Joined: 19 May 2009
Posts: 60

View user's profile Send private message

PostPosted: Wed May 27, 2015 5:13 am     Reply with quote

It is 8 bit uncompressed PCM audio at 16 - 22 KHz.
Playing 1 stream is no problem and I don't feel that that is stressing the PIC. It feels like the duration of the INT handler is not constant when using 2 timers.
Ttelmah



Joined: 11 Mar 2010
Posts: 19217

View user's profile Send private message

PostPosted: Wed May 27, 2015 7:06 am     Reply with quote

If you use the timers without 'high', the duration _will_ be constant, _but_ the actual call to whichever handler occurs second, can be delayed by the duration of the first.
With high, the duration of the 'non high' handler can be increased by the duration of the high handler.

Both your handlers are rather slow/bulky. Realistically to do things like this with accurate timings, needs you to look carefully at the time involved in every line, and possibly consider 'cheat' approaches (working from a smaller buffer inside the ISR for example, and just 'swapping' buffers as they are used). Also things would be a lot better if you could reduce the number of ISR's involved. One single high frequency task would be better, and possibly not using ISR's at all. For instance, I do some BLDC motor applications involving synthesised variable width multi-phase PWM at 50KHz. This is done without ISR's at all. Instead the code uses the CCP, and _polls_ it's interrupt flag. It also tests for serial by polling the serial flag _only_ at the end of the cycle in the 'deadtime' before the next pulse. On a 48MHz PIC, six waveforms are all synthesised without a single missing cycle....
Skirmitt



Joined: 19 May 2009
Posts: 60

View user's profile Send private message

PostPosted: Wed May 27, 2015 8:49 am     Reply with quote

I tried a few things. One was toggling a pin in the timer 0 isr and this showed on the scope what I suspected, the frequency is not constant so probably timer 1 interrupts too much for the pic.

My knowledge does not reach far enough to implement your suggested aproach although I do understand what you want to do.

Would it be possible to use timer 1 to produce both 16 Khz data and 22 KHz where the 22KHz stream can be pitched.

I know presetting it to 65490 gives me around 22 Khz so I would need to calculate what the next preset would be to add the second sound. Would that be a possibility ?
RoGuE_StreaK



Joined: 02 Feb 2010
Posts: 73

View user's profile Send private message

PostPosted: Thu May 28, 2015 6:23 am     Reply with quote

To my way of thinking the two different interrupt rates are always going to create an issue; when they interrupt at or near the same time then one will take precedence and throw the other one off as it has to wait for completion.

This is something I'd be interested in figuring out, I myself am playing back multiple mixed raw 8bit PCMs @16kHz but no dynamic timing changes. But it's late and my brain isn't engaging, so I'll come back to it tomorrow (when I should be doing, you know, work)
I'm vaguely thinking something with flags and state machines, but my mental machinery wants to go to beddy-byes
Skirmitt



Joined: 19 May 2009
Posts: 60

View user's profile Send private message

PostPosted: Thu May 28, 2015 6:29 am     Reply with quote

Exactly, I guess no matter how fast the pic is working it will always be an issue.

I'm curious what your solution would be !
RoGuE_StreaK



Joined: 02 Feb 2010
Posts: 73

View user's profile Send private message

PostPosted: Thu May 28, 2015 6:47 am     Reply with quote

OK, last thought on the way to bed, do you actually NEED to change the timing, or can it be achieved in a faux way? eg. pitched microsamples? So just use the one interrupt for playback, and depending on the input status choose a certain pitched microsample to suit?

I don't know what you are trying to achieve, I'm envisaging something like those sound systems for RC planes that have a few big "startup" and "shutdown" sounds mixed with variable-pitched engine sounds tied into the revs... which to me would work fine/great with microsamples.
Skirmitt



Joined: 19 May 2009
Posts: 60

View user's profile Send private message

PostPosted: Thu May 28, 2015 6:56 am     Reply with quote

Exactly, it is a sound system for RC trucks. Microsamples would be ok but pitching is a bit better because then I have more control.
RoGuE_StreaK



Joined: 02 Feb 2010
Posts: 73

View user's profile Send private message

PostPosted: Thu May 28, 2015 10:15 pm     Reply with quote

Does the variable rate work by itself? ie. without the 16kHz stream? If so, obviously not an ideal solution, but why not just use two PICs, with one doing nothing but the variable stream and listening to commands from the primary?

Got any examples (eg. youtube) of the sort of sound you want to achieve? eg. here's a plain one from hobbyking:
https://www.youtube.com/watch?v=mV0ZuAz5fSY, seems to me that if you split it into say a max of 10 pitch tables it should still give pretty good response to throttle, maybe you could also fudge it and double the "throttle resolution" by mixing two neighbouring pitches at mid-pitch? So when it's "on pitch" mix the same waveform twice, when it's "mid-pitch" mix the lower and upper waveforms from the table (eg. 80Hz and 90Hz to fudge 85Hz). You can do this by soft-addition if you make 7bit samples (halve the volume and shift "down" by 64 samples), or if you hard-add them (two sound outputs) you can use two 8bit waveforms to effectively get 9bit.


But I don't know what kind of sounds a truck system (what kind of "truck"? Semi, Hummer, Monster, rock-crawler...?) is supposed to produce
Ttelmah



Joined: 11 Mar 2010
Posts: 19217

View user's profile Send private message

PostPosted: Fri May 29, 2015 12:35 am     Reply with quote

RoGuE_StreaK's suggestion is basically good.

Generate the sound with a chip like the PIC16F1508. Suddenly this job is easy. A few lines of code does the whole thing, without timing problems.....
Skirmitt



Joined: 19 May 2009
Posts: 60

View user's profile Send private message

PostPosted: Fri May 29, 2015 6:24 am     Reply with quote

The sounds are prerecorded ones I made with a microphone.
The board itself already has 2 PIC's on it. One 16F that reads all the servo signals with a timer and controls the lights. The other one (18F) does alle the sound.
I have sound for idle, leave, stop, driving and shut down. That alone works like a charm and is bugfree.
I wanted to add sounds for example air release, horn, reverse beep etc. But those have to played at a fixed rate.
So, a third PIC is a no go, for this design that is since the PCB is ready.

For now the only solution will be to prevent the primary sound from pitching I guess.

Making separate samples would involve a lot of time and overhauling my code.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group