Combining chunks of pyaudio data into a single longer chunk - arrays

I have a pyaudio stream running like so:
self.stream = self.microphone.open(format=pyaudio.paInt16, channels=1, rate=self.SAMPLING_RATE, input=True, output=True, frames_per_buffer=self.SAMPLES_PER_CHUNK)
and I am saving each chunk to an array after decoding it through numpy like so:
data = self.stream.read(self.SAMPLES_PER_CHUNK)
data = np.frombuffer(data, dtype='b')
recorded.append(list(data))
And I would later on like to be able to combine these chunks into a single array and save them to a wav file like this:
from scipy.io.wavfile import write
total = []
for i in recorded[start:stop]:
total += i # the issue is here
write('output2.wav', 48000, np.array(total).astype('int16'))
But clearly it is not as simple as merging the arrays as the output file is always just a snippet of static. Could someone tell me how I should be doing this?

I actually realized that it was a question of decoding the data which means that if you change this:
data = np.frombuffer(data, dtype='b')
To this:
data = np.frombuffer(data, dtype='int16')
The rest of the code works just fine

Related

Byte array to Firestore

I have a byte array how do I store it in Firestore?
preferable to store as a File in Firestore Storage but storing them as custom object is fine too in Cloud Firestore.
I tried to make a file and use the function write Bytes() and on retrieving use read bytes but that is not able to work proper and causing some disruption as my byte array is a encrypted form of image which I need to store in Firestore. And Retrieve later and decrypt it.
Before I was trying to convert Byte Array to string but many people told that is no good practice as it will cause loss of data.
Than when I researched a bit few people recommended to use Blob and store the byte array but unfortunately I was unable to get the sample code for it.
val z = cipher.doFinal(byteArray)
val file = File.createTempFile("$name", null)
file.writeBytes(z)
Log.d("first","quick")
val storageReference = FirebaseStorage.getInstance()
.getReference("/image/0XhL4jD4XCemk38rcRkIEjJMgjh2/Aadhar/")
storageReference.putFile(Uri.fromFile(file))
.addOnSuccessListener {
Toast.makeText(context , "Success", Toast.LENGTH_SHORT).show()
}
Basically Z is the encrypted byte array that I somehow need to push to Firestore. I tried to make file and push in storage. Its Successfully completed.
But when I retrieve it back Something like below:-
val storageRef =
FirebaseStorage.getInstance().reference?.child("/image/0XhL4jD4XCemk38rcRkIEjJMgjh2/Aadhar/")
val localfile = File.createTempFile("temp", ".txt")
storageRef.getFile(localfile)
.addOnSuccessListener {
val bytes = localfile.readBytes()
var decryptedText: ByteArray = cipher.doFinal(bytes)
val configBmp = Bitmap.Config.valueOf(bitmap.config.name)
val bitmap_tmp = Bitmap.createBitmap(width, height, configBmp)
val buffer = ByteBuffer.wrap(decryptedText)
bitmap_tmp.copyPixelsFromBuffer(buffer)
img.setImageBitmap(bitmap_tmp)
}
The problem when I read bytes I got no clue what but something is going wrong there. I can be of sure that encryption and decryption both are working fine as I tested it Locally without pushing the byte array to Firestore and Just decrypt and it works perfectly good.
But when for the same byte array I try to store in file and push and retrieve later it doesn't works. The error I get is Illegal block size.
Simplified Question:-
Assume I have a byte array 'X'
How can I store it in Firestore [Cloud Firestore / Storage in form of files[preferred] with 0 loss of data and retrieve it back.
Help would be highly appreciated guys with a snippet of code to understand,
Thanks in adv.

Writing to a text file and losing data in Python?

I am logging data using IronPython (sensor OEM requires this), and writing that collected data to a .txt file using the first snippet below. My goal is to make real-time calculations on the collected data (like a running window variance), and plot it in real-time. I am reading the .txt file into a script I've written in Spyder.
I am losing about 3/4 of the data points somewhere between the data collection in my first script, and the data read in my Spyder script for the math calculation and visualization.
I am looking for some feedback for the way I am writing my data, and reading it; and if I am risking losing data somewhere along this way.
file = open("C:\\Users\Documents\\test4.txt", "a")
writer = csv.writer(file)
while True:
writer.writerow(myFunction())
file.flush()
In Spyder, I am reading in this file like the following:
def animate(i):
data = pd.read_csv("C:\\Users\Documents\\test4.txt")
data.columns = ['X', 'Y', 'Z']

Python: Can you extend an array on each iteration using glob (or similar) to read in files from a directory

Is there a way to extend an array that stores data from a file on each iteration of a for-loop and with command combo, using glob. Currently, I have something like
import glob
from myfnc import func
for filename in glob.glob('*.dta'):
with open(filename,'rb') as thefile:
fileHead, data = func(thefile)
where func is defined in another script myfnc. What this does is on each iteration in the directory, stores the data from each file in fileHead and data (as arrays), erasing whatever was there on the previous iteration. What I need is something that will extend each array on each pass. Is there a nice way to do this? It doesn't need to be a for-loop, with combo. That is just how I am reading in all files from the directory.
I thought of initializing the arrays beforehand and then try extending them after the with is done on one pass, but it was giving me some kind of error with the extend command. With the error, the code would look like
import glob
from myfnc import func
fileHead, data = [0]*2
for filename in glob.glob('*.dta'):
with open(filename,'rb') as thefile:
fileHeadExtend, dataExtend = func(thefile)
fileHead.extend(fileHeadExtend)
data.extend(dataExtend)
So, the issue that it has is fileHead and data are both initialized but as int's. However, I don't want want to initialize the arrays to so many zeros. There should not be any arbitrary values in there to begin with. So, that is where issue is lying for this.
You want:
import glob
from myfnc import func
fileHead = list()
data = list()
for filename in glob.glob('*.dta'):
with open(filename,'rb') as thefile:
fileHeadExtend, dataExtend = func(thefile)
fileHead.extend(fileHeadExtend)
data.extend(dataExtend)

In Python: Why does a Numpy array returned in a method have to be stored in the instance?

The issue is a bit complicated so I need to give you the full story:
I'm trying to create basic sound using the package pyaudio.
The pyaudio module asks for a callback function that reads audio data.
It basically looks like this:
def callback():
return sound.readframes()
I have a class that provides audio data. It creates a signal by indexing a numpy array that contains a wave length of a basic wave form. It basically looks like this:
class Wave(object):
data = [] # one wavelength of a basic waveform like a sine wave will be stored here
def readframes(self):
indices = # the indices for the next frames
# based on a frequency and the current position
return self.data[indices]
class SineWave(Wave):
data = # points of a sine wave in a numpy array
sound = SineWave()
# pyaudio now reads audio data in a non-blocking callback mode
Now to the problem:
There was noise between each call to readframes or each block of audio data. The sound itself was still intact, but there was an additional clicking. Increasing the size of the returned data block also increased the time between each click. I still don't quite know what caused the noise, but I fixed it by storing the returned numpy array in the instance instead of returning it directly.
This causes noise:
return self.data[indices]
This does not cause noise:
+ self.result = self.data[indices]
+ return self.result
It can't be an alteration of the data that causes the noise or else this wouldn't fix it. Why does the result have to be stored in the instance?
Update:
I also have to mention that the noise doesn't occur everytime I run the script. It occurs randomly about 50% of the runs. Either the noise appears right at the start and won't go away or it doesn't appear at all.
It looks like an issue with the initialization of the sound device, but how that could be related to my fix is a mistery.
Here is code that reproduces the noise problem:
import pyaudio
import time
from numpy import sin, linspace, arange, pi, float32, uint32
SR = 44100 # sampling rate
FPB = 2048 # frames per buffer
class SineWave(object):
"""A sine wave"""
data_size = 2**10
data = sin(linspace(0, 2*pi, data_size, endpoint=False, dtype=float32))
def __init__(self, frequency):
self.pos = 0
self.fq = frequency
self.ppf = self.data_size * self.fq / SR # points per frame
def readframes(self):
size = FPB
pos = self.pos
indices = (arange(pos, size+pos)*self.ppf).astype(uint32) & (self.data_size-1)
self.pos = (self.pos + size) % SR
self.result = self.data[indices]
return self.data[indices]
def callback(in_data, frame_count, time_info, status):
return sound.readframes(), pyaudio.paContinue
p = pyaudio.PyAudio()
stream = p.open(format=p.get_format_from_width(4),
channels=1,
rate=SR,
output=True,
stream_callback=callback,
frames_per_buffer=FPB)
sound = SineWave(440)
stream.start_stream()
time.sleep(2)
stream.stop_stream()
stream.close()
p.terminate()
On my system the noise appears in about 90% of the runs.
Changing
return self.data[indices]
to
return self.result
fixes it.
There shouldn't be a difference whether you store the intermediate array in the instance or not. I suspect there is some other problem going on that causes the error you're experiencing. Can you provide code that actually runs and exhibits the problem?
If you want to see a (hopefully!) working implementation, have a look at the play() function of the sounddevice module, especially at the loop argument. With this, you should be able to play your waveform repeatedly.
The only thing you need to store in the instance, is the frame index where you left off, just to continue with the following frame index in the next callback (and of course wrap around in the end). You should also consider the case where your wave form is shorter than an audio block. It might even be much shorter. I solved that by using a recursive function call, see the code.
UPDATE:
It's indeed quite strange that assigning to self "solves" your problem. I think this has something to do with how PyAudio interprets the returned array as Python buffer.
You should rewrite your code using the sounddevice module, which properly supports NumPy arrays and has a sane API for the callback function.
It's easy, just use this callback function:
def callback(outdata, frames, time, status):
if status:
print(status)
outdata[:, 0] = sound.readframes()
And start the stream with:
import sounddevice as sd
stream = sd.OutputStream(
channels=1, samplerate=SR, callback=callback, blocksize=FPB)
Apart from that, your code is flawed since it doesn't do any interpolation when reading from the wavetable.

Byte Array copy in Jsp

I am trying to append 2 images (as byte[] ) in GoogleAppEngine Java and then ask HttpResponseServlet to display it.
However, it does not seem like the second image is being appended.
Is there anything wrong with the snippet below?
...
resp.setContentType("image/jpeg");
byte[] allimages = new byte[1000000]; //1000kB in size
int destPos = 0;
for(Blob savedChart : savedCharts) {
byte[] imageData = savedChart.getBytes(); //imageData is 150k in size
System.arraycopy(imageData, 0, allimages, destPos, imageData.length);
destPos += imageData.length;
}
resp.getOutputStream().write(allimages);
return;
Regards
I would expect the browser/client to issue 2 separate requests for these images, and the servlet would supply each in turn.
You can't just concatenate images together (like most other data structures). What about headers etc.? At the moment you're providing 2 jpegs butted aainst one another and a browser won't handle that at all.
If you really require 2 images together, you're going to need some image processing library to do this for you (or perhaps, as noted, AWT). Check out the ImageIO library.
Seem that you have completely wrong concept about image file format and how they works in HTML.
In short, the arrays are copied very well without problem. But it is not the way how image works.
You will need to do AWT to combine images in Java

Resources