So, what's the current status of everything?


Seems like Grench might be able to test things out sooner than I can. I'm merely a normal pre-preorder, and I didn't pay extra for a prototype.

IIRC NEON can handle a uint64 in its 64-bit registers. I'd recommend doing the multiply first in that case.

Sound like a plan, on previous page I already posted a function to double sample to 96, with this we got 44.1 to 96, seems enough doesnt it?
 
For the first step, sure. My code should also be able to handle 22.05kHz sample transcoding as well, which apparently is used by some samples for games that presumably don't use above 10kHz audio (nyquist would render anything above 11.025kHz being little more than noise).

That's assuming this is anywhere quick enough. I don't think you can precompute oldrate/newrate because even though I only need integer precision in the end, I can only guarantee that by multiplying it first then dividing the resulting huge number. It might be possible though, if the ratio stored in a floating point register gives 44100 exactly when rounded to int if you multiply it by 96000, that should guarantee the second boundaries line up at least, and from there I propose it's good enough to use.

Maybe it's fast enough to use anyway. I'm not sure how many cycles an integer divide takes from a NEON 64-bit register, and it needs to do that 96000 times a second, but even in my python form it seems to be somewhere around realtime.

But then you need to figure out getting this working inside the kernel, which I have no experience of myself.

And if someone figures out how to use the hardware transcoding first then this work is wasted, but there you go.
 
first paid prototype pyra shipped! this is an awesome milestone! congratulations ed! :cool:

I presume that is a sound played at boot-up, as opposed to a noisy spring?

Sounds pretty easily doable I imagine just by downloading the sound file and playing it... (via a start-up script)

i think he meant the audio-buffer release sound when the pandora sound-circuit goes to sleep. ;)
 
(nyquist would render anything above 11.025kHz being little more than noise).
I think, that's not what it says on the Nyquist-Shannon-tin. iirc, when you patch a frequency generator into an fft module, visualize that shit, and then turn the frequency knob continuously up, you see the peek in the spectrum wander to the right upt to the Nyquist freq and then wander left. I.e. higher freqs don't get drowned, but aliased. So that in case of downsampling one would first have to low pass filter.
But, could someone please correct or confirm what I just said?
 
I kind of both agree and disagree
If my input size was assured to be multipication of the output size, I could interpolate lineary either by averaging samples ( the quickest version would be adding both and shifting right by 1 to simulate division by 2)

However our issue is that the interpolation is non linear

The ratio for 98 to 44.1 is around 2.17, it means that for each sample, I'd want to copy it once more and add "0.17" sample and write both the input and the copy sample and "fake" sample to the output buffer

Since its 2d data, its interleaving mode does not matter more than transposing the data...

So if we could add "0.17" pixel it would be a simple upsample, but there is no such thing as 0.17 sample

However image processing suffer the same issue when we resize images to different aspect ratio, linear interpolation is used to approxmiate us closer to the real size, and than we upsample by a factor between 1 and 2 (1.17 for example) with anti aliasing algorithms

Timothy Lottes from nvidia created a very fast anti aliasing algorithm (which will fix the wave corners to fit between edges, which will make sound playback seems less bumpy and more directional), namely FXAA, which marked 6.7 ms on radeon 240, which makes me confident that the pyra is probably capable of about 3ms FXAA on 44.1 to 98 per second (which is equal to 44.1K 16bits) which is roughly 88K bytes, image processing on 50K bytes on ARM omap was already benchmarked for about 2 ms, and considering how fast FXAA is, I assume that even if we cant apply FXAA we can use the idea of scoring samples and averaging tham to create sample each N samples that will result in 98K samples if done ( if i % N == 0 create extra 1 sample based on moving average of previous M samples)

I read the article about FXAA, I actually am confident it is applicable to sound waves but I might be wrong, probably next week I will discover it


the upsample twice code is something similar to this

#include <stdint.h>
#ifdef __ARM__

#include <arm_neon.h> // for neon instrincts

// assumes input sample is preallocated with sizeof(int16_t)*size
// assumes output sample is preallocated with sozeof(int16_t)*size*2
void dualsample_int16(const int16_t* input_sample, size_t size, int16_t* output_sample)
{
const int16_t* end = input_sample + size;
int16_t* y = output_sample;
const int16_t* x = input_sample;
const int16_t* end_minus_8 = end - 8;
const int16_t* end_minus_4 = end - 4;

// one increment is done already inside the loop to save time for the already computed y += 8 required to write the sample twice and to increment
for(; x <= end_minus_8; x += 8, y += 8)
{
// Load vector of 8 int16s
int16x8_t sample_data = vld1q_s16(x);
// write to y sample once
vst1q_f16(y, sample_data);
// increment y to point to the next sample
y += 8;
// write to y sample twice, now the last 32 bits of y is a repeat of those 16 bits on x
vst1q_f16(y, sample_data);
}
// same algorithm, now for vector of 4's for the rest of the data that is not divisible by 8
for(; x <= end_minus_4; x += 4, y + =4)
{
int16x4_t sample_data = vld1_s16(x);
vst1_f16(y, sample_data);
y += 4;
vst1_f16(y, sample_data);
}
// naive, for the rest of the data that is not divisible by either 8 or 4
for(; x < end; x++, y++)
{
(y++)[0] = x[0];
y[0] = x[0];
}
}

#else

void dualsample_int16(const int16_t* input_sample, size_t size, int16_t* output_sample)
{
const int16_t* end = input_sample + size;
int16_t* y = output_sample;
for(const int16_t* x = input_sample; x < end; x++, y++)
{
(y++)[0] = x[0];
y[0] = x[0];
}
}

#endif
boring..
show me fft code
 
boring..
show me fft code

Never realized I am here to entertain you

anyways clearly I am not going to recreate the wheel

github.com/projectNe10/Ne10/blob/master/modules/dsp/NE10_fft_int16.c

which is BSD-3 license so we can link the .so and use it, I already tested it under emulation and it's one of the fastest and most precise fft implantation

their idea of summing and shifting right by 3 (because we got 8's, and their weight per channel is 1/8, so shifting by 3 is like dividing by 8) is really fast

it does lead inprecise complex to complex, it's more general purpose, but we don't really need complex dimension when we are dealing with sound waves...

I thought I was clear that I am going to base fft and ifft on ne10 on my previous post, when god offers you a fast library that you can hardly fight and you will most likely copy most of your code off from them, use it, the more 3rd party support we get (which will constantly update) which resolves our issues exactly, the better.

the idea will be that the above code that I posted will be fast 48->96 transform (which is as fast as about 2ms-4ms compute per second of audio sample, that's as fast as my 9900k does natively, which is overclocked to 5.3GHz with custom watercooling, so it says a lot) , levi's code will be fast 44.1 ->96 (when I will neonize it, which seems easy enough) and ne10's-based fft, transform and ifft will be audiophile mode (which will work from any sample rate to any sample rate)

the only question is what filter I will apply on the frequency channel once I fft it, butter low seems really cool when I tested it out, you can easily do with numpy (NE10 is here only to do it faster, we can test our theory on python offline easily to make sure we are right, if we can't do it in python using that method we OBVIOUSLY can't do it in C)

I also wrote FXAA for neon, and since neon offers quick int->float->int vector conversion, it was REALLY fast scoring about 7ms for 44.1 -> 96 per second of audio, and really precise, but it missed reoccuring waves that differ in chunks, I found a way to overcome this by changing the factors between inputs shaders and output shaders, which clearly doesn't affect compute time and leads to better results, the question is which ones are more right
 
Don't do 44.1Khz to 96K in the hardware driver.

At most support 8K, 12K, 16K, 24K, 32K, 48K, and 96K then let the software/userspace handle the other conversions itself.

No point in having software that can output 48Khz just fine be tricked into using 44.1Khz only to have the driver resample everything wasting cpu, battery life, and possibly doing a worse job of it.

With ALSA software can request a preferred sampling rate and has to check what it actually selected:

Code:
        if ((snd_pcm_hw_params_set_rate_near((snd_pcm_t *)dev_handle, (snd_pcm_hw_params_t*)hw_params, (uint *)&actual_rate, 0)) < 0) {
            xerrorf("ALSA ERROR: snd_pcm_hw_params_set_rate_near\n");
        }

MP3, OGG, AAC, and other FFT-based audio format are already in the frequency-domain.
It's much better if the source frequency-domain media can be decoded right into the target sample rate.
 
I think, that's not what it says on the Nyquist-Shannon-tin. iirc, when you patch a frequency generator into an fft module, visualize that shit, and then turn the frequency knob continuously up, you see the peek in the spectrum wander to the right upt to the Nyquist freq and then wander left. I.e. higher freqs don't get drowned, but aliased. So that in case of downsampling one would first have to low pass filter.
But, could someone please correct or confirm what I just said?
I don't know about what happens after you fft everything, but working purely in the sample domain. A signal at precisely the nyquist frequency would at best be sampled as an up point then a down point then an up point and so on, which turns into a sin wave when you pump that through a DAC and a loudspeaker, although the aplitude depends on the exact phase you landed on. Probably a better example is slightly below the nyquist frequency, because then every so often the wave will cycle round and hit the maxiumum amplitude, which is enough to kick the diagphragm in the tweeter to wobble right and output the right wave.

But if you go above the nyquist frequency then you'll pick something out of one half sin cycle, then something somewhere else out of the next. Just above nyquist would be represented by a frequency just below nyquist I think, and twice nyquist would be silent, but generally these post-nyquist frequencies are filtered out because even if they do generate a lower frequency tone it's unlikely to be in tune with the rest of the music.

So yes, I think the aliasing would go left after nyquist at least for a bit.

Actually that might be a problem with my 2k beep sample, because the code generates 10 octaves worth of harmonics, which from 420Hz gets you up to some 43kHz I think. I think the second harmonic would be in range (but I think the code only uses odd harmonics) and the third should be well north of the 1kHz nyquist, but it might explain why the sample degenerated to noise as it faded out at the end.
 
Indeed, that's all done in the analogue domain, which is a matter of a handful of caps and resistors. Then the sampling occurs, which is the transition into the digital domain.
 
Good to see that there is a little progress on the Pyra Project

Is it just me, or is the order-stat page down?
I'm getting 403
 
Yep, looks like they've been taken down. Good job too, they'd grown somewhat unreliable and aren't suitable once actual mass production starts, and very slightly arguably aren't really preorders when paid prototypes are out in the wild.

Edit: To be precise, they still seem to be there but their perms have been revoked. This looks to have been done deliberately, because other files I checked in the same folder are still accessible to me.
 
I just received a shipping notice for a prototype!
You are the third one of us to appear. Welcome!

#4 is @funkyarif. He received his first earlier today: https://pyra-handheld.com/boards/threads/preparing-for-a-prototype.76956/post-1666945

I am #8 and mine is stuck at a German FedEx sorting facility and will now be here Friday instead of Tuesday: https://pyra-handheld.com/boards/threads/preparing-for-a-prototype.76956/post-1666972

I can't believe I'm actually asking this, but, if you don't mind, what is your prototype order number?
 
I'm afraid I don't know the number. I don't think it was on anything Evil Dragon sent.
 
I'm afraid I don't know the number. I don't think it was on anything Evil Dragon sent.
From the contents of the package that @funkyarif received, I suspect you will know the answer to that question on delivery.
 
Back
Top