PyAudio. How to record while playing sound - pyaudio

I used PyAudio for recording and sounding.
Both can work respectively, but I couldn't record while sounding.
It always first sound and record or record and sound.
I tried thread but did not work.

You could try the playrec() function from http://python-sounddevice.rtfd.org/.
import sounddevice as sd
myrecording = sd.playrec(myarray, samplerate, channels=2)

Related

currentTime set to different value after loadmetadata event during seek

I am currently on an adventure with my sanity at stake where I try to simply play an mp3 file on my web-application. This mp3 is loaded chunk-wise in order to make the experience more responsive.
Even though the documentation of the MediaSource API is just remarkably, almost violently, useful and hundreds of well explained examples pave the way towards salvation, I find myself not able to make everything work properly.
The last issue I am facing is the seeking-functionality. The simple idea I had for this feature is to simply kill everything that's alive, burn everything down and revive again. To be more precise, if the user seeks, I stop the machinery and start playing everything from scratch, but with the desired offset (in seconds).
Everything is working so far except one last thing: currentTime, gets set to a different value after I have set it to the time that the user requested.
The track continues playing as expected but the problem is that currentTime is what's being used to visualize the current location within the track for the user.
This is how the events take place before and after the user seeks
[play-click] <--- User clicks play button
:
[timeupdate] currentTime: 00.01
[timeupdate] currentTime: 00.02
[timeupdate] currentTime: 00.03
[seek-click] <--- User seeks, stop() is called and then playFrom(seconds)
[loadstart] currentTime: 33.33 # This is the (correct) time set in playFrom(seconds)
[loadmetadata] currentTime: 10.12 # Now the time gets set to this (wrong) value
[seek] currentTime: 10.12 # The triggered seek event comes in
[seeked] currentTime: 10.12
[canplay] currentTime: 10.12
[playing] currentTime: 10.12
[timeupdate] currentTime: 10.13 # Track continues to play correctly but this value is still wrong
:
This is how seeking takes place:
public play(track: Track) {
this.track = track;
this.playFrom(0);
}
public seekTo(seconds: number) {
this.stop();
this.playFrom(seconds);
}
public stop() {
this.logger.debug('Stop ..');
this.sourceBuffer.abort();
this.audioObj.pause();
this.removeEvents(this.audioObj, this.audioEvents, this.audioEventsHandler);
this.audioObj = null;
this.sourceBuffer = null;
this.mediaSource = null;
}
Now, the playFrom(seconds) method is a bit more complicated than that but all it really does is re-create everything that I just destroyed:
private playFrom(seconds: number) {
this.logger.debug(`Start playing from ${seconds.toFixed(2)} seconds`)
// [:] (collapsed some less important code here)
// Create the media source object
this.mediaSource = new MediaSource();
this.mediaSource.addEventListener('sourceopen', this.onSourceOpen);
// Create audio element
this.audioObj = document.createElement('audio');
this.audioObj.src = URL.createObjectURL(this.mediaSource);
this.audioObj.currentTime = seconds;
this.addEvents(this.audioObj, this.audioEvents, this.audioEventsHandler);
this.logger.debug(`Object-url: ${this.audioObj.src}`);
this.state = {currentTime: seconds, playing: true};
}
How can I get the correct current-time here?
I tried another idea where I was tring to create and add a new SourceBuffer to the MediaSource and let it play the audio from there but I wasn't able to do that either.
What is the duration reported by the MediaSource (or by the media element) at the time of issuing the seek to the media element? If it is infinite, you may need to use the {set,clear}LiveSeekableRange APIs in MSE to let the implementation know if you wish to let the player seek beyond the currently buffered media's highest presentation end time. Alternatively, you could possibly set the MediaSource duration before seeking to be something finite, but at least as high as the highest currently buffered media presentation end time.

Corona SDK piano app - swapping sounds, etc

So basically I am making piano app in Corona SDK (my first project) and Im new to it. I've asked some questions about my problem on Corona forums but I don't have achieved exact answers that would help me, so I'm asking for your help. As I said im new, so it may be hard for me to crack out the needed code, but I know that you, more experienced Corona users, can easily do this.
I use this code for each key: (I know that media.playEventSound is pretty weak option to do that, I've seen some libraries about playing audio on Coronalabs like audio.loadSound etc. but if it is possible, of course, I'd like to stay with "media..."-based functions)
local widget = require("widget")
local C = media.newEventSound("C.mp3")
local button_C_Press = function(event)
media.playEventSound(C, button_C_Press)
end
local button_C = widget.newButton
{
defaultFile = "NewKey.png",
overFile = "NewKey2.png",
onPress = button_C_Press,
}
button_C.x = 20; button_C.y = 295
I want the piano to have 2 pedals that just switch its sound when they're pressed (I have in my project folder in total 3 different sound arragments - default and 2 pedal sustained audio files) and button that requires note letters on keys.
And here's my problem - how to get this all into one code?
I mean can you write me down there a code for one key like this sample I've posted below but including those features which I just mentioned please? I'd really love to have that solved..
Btw. I know soundTable/fileTable method, however it is called, but I think I have enough time to do each key individually - or use table method maybe - I only wish it was easy, beacuse it is my first project therefore should it be.
Sorry for my English and thanks!
You have asked for more code; I've got this recommended on Corona forums
Boolean variable:
local isPedalActive = false
And when they have touched the pedal button, then set it to true:
isPedalActive = true
And then add this to button_C_press function:
if event.phase == "began" then
if isPedalActive = true then
media.playEventSound(cPedal) --assuming you already loaded your audio above
end
end
Of course, if you have a large number of piano keys, it's better to don't do this individually for each function, rather:
Set a specific id for each key, in the widget.newButton table.
In the if statement, load the sound there but instead you would retrieve the button's id and play that mp3 file.
(that supports only one pedal)
--create table of key button ids and mp3 files for their pedal noises
local keys = {
{buttonId = "C", pedalNoise = "Cpedal.mp3"},
{buttonId = "D", pedalNoise = "Dpedal.mp3"}
}
function pianoKeys(event)
for i = 1, #keys do -- for each table in the keys table, load the sound for each key
local keySound = media.newEventSound(keys[i].buttonId .. ".mp3") -- normal sound loaded
local keypedalSound = media.newEventSound(keys[i].pedalNoise) --pedal sound loaded
function buttonPress(event) --When they press the key, detect if the pedal is active
if event.phase == "began" then
if isPedalActive == true then
media.playEventSound(keyPedalSound) --is active, play pedal sound
else
media.playEventSound(keySound) -- is not active, play regular sound
end
end
end
local pianoKey = widget.newButton({
id = keys[i].buttonId, -- place appropriate id
defaultFile = "new" .. keys[i].buttonId .. "key.png", -- place appropriate defaultFile
overFile = "new" .. keys[i].buttonId .. "key2.png", -- place appropriate overFile
onPress = buttonPress -- apply above function to each key
})
end
end
My problem - I dont't want to make sound table. I'd rather to do each key individually. Like that sample of one key's code I've posted below. But how? I dont know how to get everything into one valid thing :/ ( 2 pedals + note button)

Loading a movie clip using SharedObject/AS3

Ok, so I'm working on a quiz game for work. I have each question on its own movie clip (I know that's not the preferred method, but it's what I'm most familiar with and a compressed project timeline kinda forced my hand).
Because players will only be able to play the game once (there's a prize involved), I'm attempting to implement a "save/load" system which will allow players to pickup where they left off, in case their browser crashes, they accidentally close the game window, etc. I already have a SO setup to accept save data. So for example, I have the following code on frame 1 of the Q1 scene:
var currentLevel = "Q1"; //first time the var is defined. "Q1" is the name of the scene
answersSO.data.currentLevel = currentLevel;
answersSO.flush();
And I have the following code on frame 1 of the very first scene of the movie:
function checkProgress() {
if(answersSO.data.currentLevel != undefined) {
currentLevel = answersSO.data.currentLevel;
MovieClip(this.root).gotoAndPlay(1, currentLevel);
} else {
gotoAndPlay(2);
}
}
checkProgress();
First, I gotta say that I'm a real nub at AS. I test play the game up to the Q1 scene, then close the window. I restart the game and it instantly skips all of scene 1 and proceeds to scene 2 (which is an intro to the game, not Q1). No error is thrown.
What I'm looking to do is save some data to the currentLevel variable, and save that variable to the SO. At the start of the game, the script should check if the SO has any data in it. If not, then there is no save data—proceed as normal. If there is data, load it and play the last recorded scene the player was at.
I can't figure out (1) how to get this working and (2), of somewhat less importance, why no error is being thrown.
EDIT!
This is my updated code:
stop();
import flash.net.SharedObject;
var answersSO:SharedObject = SharedObject.getLocal("PWFGame"); //DECLARE SO VARIABLE
var currentProgress = "";
//CHECK SO FOR PROGRESS
checkProgress();
function checkProgress() {
if(answersSO.data.currentLevel == null) {
nameField.text = "Enter Name Here";
gotoAndPlay(2);
} else {
currentProgress = answersSO.data.currentLevel;
MovieClip(this.root).gotoAndPlay(1, currentProgress);
}
}
It does work, but the last line in the else statement is acting strangely. It skips over the first scene completely and plays the next scene from frame 1 (which is called "Intro"). Even if I change currentProgress to "Q1" it does the same thing. Why would this line of code work elsewhere and not here?
SharedObjects can be deleted by the user. A player could delete that file and start again.
If there is a login name, you should store that data on the server using a server side script (php, asp, etc.)
So add a check at the beginning and let the user play just if his name has not been stored on the server. Than call this list form flash at the beginning of the game.
For the browser crash, you can store the data only when the game is ended. So when you refresh the page you can start it again.
If there is no username, you should get other data, but it isn't so simple as an IP could change and more important data can't be retrieved by the flash player (you can do it with a desktop application made with AIR).
At the and...
.gotoAndPlay(1, currentLevel);
Remeber that the first value is the scene and the second is the frame.
Nadia
Ok, after much digging, I've discovered that gotoAndPlay() on frame 1 can cause issues. I moved the updated code block (seen above) to frame 2, and everything works.

SampleDataEvent.data.writeFloat() at at 5kHz, 8kHz,11kHz or 22kHz

How many times should I execute SampleDataEvent.data.writeFloat
when data has been recorded at 5kHz, 8kHz,11kHz or 22kHz ?
The voice has been recorded at 5kHz, 8kHz,11kHz or 22kHz with flash.media.Microphone.
I refered that
SampleDataEvent.data.writeFloat() - Why call it twice?
I've found this page and they describe frequency shifting which may give you some idea about your problem dynamic audio in as3 part 3

Actionscript 3.0, using FlashDevelop: local variables. Can they be mistakenly created ad infinitum?

Riddle me this: I have my MouseEvent.MOUSE_DOWN which calls mouseHandler. The latter looks something like this:
public function mouseHandler(evt:MouseEvent):void
{
var p:Point = new Point(mouseX, mouseY);
var objs:Array = new Array(getObjectsUnderPoint(p));
}
Now what I want to know is thusly: will the objs array and p point be overwritten every time, simply causing the previous objs array and p point to be wiped and a new one generated, or...does it just create a new array and point over and over and over? Of course if I trace(objs) it gives me the expected results, but am I chocking up the system in the background without realising? Your expertise would be appreciated.
EDIT: well after learning a fair bit from the answerers -thanks btw- that made me think of something else and, a quick search later, found a way to theoretically reliably remove the references:
var a = null;
Now I appreciate that this is probably not needed as they'll be GCed at the end of the function, but considering it takes two ticks to write, better safe than sorry, no?
It works like this from what I understand - references for these variables will be lost after function will end. The values will be GC'ed then eventually.
If you will call the function second time, the new references will be created, and filled with new data, the values of previous references hovewer, may still exist in memory, and wait for Garbage Collector, but that may not necessarily happen! If they have attached listeners, the Flash Player will think that they are still useful, so they will exist in the memory to the end of the application run and listen, and even react to events - even if you theoretically cannot access them anymore.
Edit:
In your case whats happening is that you are creating two references that will disappear at the end of the function. They are not related to event listener, the listener creates them, but is not attached to them so it won't stop GC from collecting them after function will end. You creates an array of references, but that are just references to other objects that values are referred in other places (like the display list), if the array alone is not referred anywhere outside of this function, it should be GCted.
Since p is an object, not a primitive, the memory allocation for it will come from the Heap (and therefore need to be garbage collected) instead of the stack like local primitives (and are wiped once the function ends.
So new memory will be allocated every time this function is called, which will temporarily increase memory usage until they get GC'd, but the amount is probably insignificant (assuming that array isn't massive!).