I m trying to loop time in minutes and seconds to display them as a list on the widget as shown on the picture below. It might be my math problem that causing this or lack of a better way of achieving this, but I have tried and I m stack.
My problem was on capturing the minutes and seconds, like e.g you have 15minutes.
and you want then to be displayed like this.
[00:00, 00:30, 1:00, 1:30, 2:00, 2:30,3:00, 3:30....15:00],
So the issue is only achieving that.
here the image
void addTime() {
const addSeconds = 1;
setState(() {
int s = 0;
for(int i = 0; i <= Duration(minutes: 15).inMinutes; i++){
timelines.add(buildTime(minute:(i * 60) % 1 * 60.floor(),
sec: i > 0 ? (i * 60).floor() : 0));
}
});
}
So once the app is open then addTime will be called to fill the timelines List[],
Then the timelines will be rendered on the build.
Kindly assist in any way possible for me to get this done.
I manage to solve the problem by looping the seconds inside the minutes loop, here the code.
void addTime() {
setState(() {
for (int i = 0; i <= 15; i++) {
for (int j = 0; j < 60; j++) {
if (j % 30 == 0) {
String minutes = i.toString().padLeft(2, '0');
String seconds = j.toString().padLeft(2, '0');
timelines.add(buildTime(minute: minutes,
sec: seconds));
}
}
}
});
}
Related
Is there a better way to calculate a moving sum of a list?
List<double?> rollingSum({int window = 3, List data = const []}) {
List<double?> sum = [];
int i = 0;
int maxLength = data.length - window + 1;
while (i < maxLength) {
List tmpData = data.getRange(i, i + window).toList();
double tmpSum = tmpData.reduce((a, b) => a + b);
sum.add(tmpSum);
i++;
}
// filling the first n values with null
i = 0;
while (i < window - 1) {
sum.insert(0, null);
i++;
}
return sum;
}
Well, the code is already clean for what you need. Maybe just some improvements like:
Use a for loop
You can use the method sublist which creates a "view" of a list, which is more efficient
To insert some values in the left/right of a list, there is a specific Dart method called padLeft, where you specify the lenght of the list which you want it to become (first parameter), then the value you want to use to fill it (second parameter). For example, if you have an array of N elements, and you want to fill it with X "null"s to the left, use padLeft(N+X, null).
List<double?> rollingSum({int window = 3, List data = const []}) {
List<double?> sum = [];
for (int i = 0; i < data.length - window + 1; i++) {
List tmpData = data.sublist(i, i + window);
double tmpSum = tmpData.reduce((a, b) => a + b);
sum.add(tmpSum);
}
sum.padLeft(window - 1, null);
return sum;
}
if I understand your problem correctly you can just calculate the window one time and in one loop you can for each iteration you can add the current element to the sum and subtract i - (window - 1)
so for an input like this
data = [1,2,3,4,5,6]
window = 3
the below code will result in [6,9,12,15]
int sum = 0;
List<double> res = [];
for (int i = 0;i<data.length;i++) {
sum += data[i];
if (i < window - 1) {
continue;
}
res.add(sum);
sum -= data[i - (window - 1)]; // remove element that got out of the window size
}
this way you won't have to use getRange nor sublist nor reduce as all of those are expensive functions in terms of time and space complexity
Write a program that prints all numbers from 1 to 1000 in a large to small (descending) order.
Expected Output:
Each line will have a total of five (5) numbers and each number will be separated with a '\t' (Tab) character.
void main() {
final output = StringBuffer();
final columns = 5;
final maxInt = 1000;
var index =1;
final values = List.generate(maxInt, (index) => index+1).reversed;
while(index <= maxInt) {
output.write('${values.elementAt(index - 1)}\t');
if (index % columns == 0) {
output.writeln();
}
index++;
}
print(output);
}
Her you go.
void main() {
for (int i = 1000; i >= 1; i-=5) {
print('${i} ${i-1} ${i-2} ${i-3} ${i-4}');
}
}
I am working with the flutter_sound in Flutter. I simply want to fade in and fade out sound file in flutter
I have created a method that allows you to fade in or fade out.
If you want to fade you must enter this:
3 seconds to increase the volume from 0.0 to 1.0.
Fade in:
fade (1.0, 0.0, 3 * 1000);
Fade out:
fade (0.0, 1.0, 3 * 1000);
If it works for you, don't forget to rate my answer, regards.
void fade( double to, double from, int len ) {
double vol = from;
double diff = to - from;
double steps = (diff / 0.01).abs() ;
int stepLen = Math.max(4, (steps > 0) ? len ~/ steps : len);
int lastTick = DateTime.now().millisecondsSinceEpoch ;
// // Update the volume value on each interval ticks
Timer.periodic(new Duration(milliseconds: stepLen), ( Timer t ) {
var now = DateTime.now().millisecondsSinceEpoch;
var tick = (now - lastTick) / len;
lastTick = now;
vol += diff * tick;
vol = Math.max(0, vol);
vol = Math.min(1, vol);
vol = (vol * 100).round() / 100;
player.setVolume(vol); // change this
if ( (to < from && vol <= to) || (to > from && vol >= to) ) {
if (t != null) {
t.cancel() ;
t = null;
}
player.setVolume(vol); // change this
}
});
}
I make code to get and set alsa mixer volume:
snd_mixer_elem_t *elem = NULL;
long alsa_min, alsa_max, alsa_vol;
int alsa_get_volume( void )
{
long val;
assert (elem);
if (snd_mixer_selem_is_playback_mono(elem)) {
snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_MONO, &val);
return val;
} else {
int c, n = 0;
long sum = 0;
for (c = 0; c <= SND_MIXER_SCHN_LAST; c++) {
if (snd_mixer_selem_has_playback_channel(elem, c)) {
snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &val);
sum += val;
n++;
}
}
if (! n) {
return 0;
}
val = sum / n;
sum = (long)((double)(alsa_vol * (alsa_max - alsa_min)) / 100. + 0.5);
if (sum != val) {
alsa_vol = (long)(((val * 100.) / (alsa_max - alsa_min)) + 0.5);
}
return alsa_vol;
}
}
int alsa_set_volume( int percentdiff )
{
long volume;
alsa_get_volume();
alsa_vol += percentdiff;
if( alsa_vol > 100 ) alsa_vol = 100;
if( alsa_vol < 0 ) alsa_vol = 0;
volume = (long)((alsa_vol * (alsa_max - alsa_min) / 100.) + 0.5);
snd_mixer_selem_set_playback_volume_all(elem, volume + alsa_min);
snd_mixer_selem_set_playback_switch_all(elem, 1);
muted = 0;
mutecount = 0;
return alsa_vol;
}
I wont to make alsa mixer volume to changed by GtkVolumeButton. Tried this but when value from gtk button is changed up or down, alsa mixer always jumps to 100 %:
int gtk_volume_button_get_value (GtkWidget *button)
{
return (int) (gtk_scale_button_get_value(GTK_SCALE_BUTTON(button)) * 100);
}
void gtk_volume_button_set_value (GtkWidget *button, int value)
{
gtk_scale_button_set_value(GTK_SCALE_BUTTON(button), (gdouble) value / 100);
}
void volume_value_changed_cb(GtkVolumeButton *button, gpointer user_data)
{
int vol = (int)(gtk_volume_button_get_value(volume_button) + 0.5);
alsa_set_volume(vol);
}
Please help me to write a corect code for GtkVolumeButton.
Your problem has nothing to do with GtkVolume. In fact, it comes from you using two different approaches to handle volume. alsa_get_volume gives you an absolute sound level, which is an integer. One would expect alsa_set_volume to accept the same kind of value range. And that's how you use it in volume_value_changed_cb: « get the volume level of the volume control, between 0 and 100, and set it as current volume. ».
However, the implementation is completely different. It's implemented as if you wanted to tell it « add or substract x% of the current sound volume ». You get the current volume level and add that percentage, thus you're computing a relative sound level, not an absolute one. So, if your initial sound level is 50%, and you want to lower it to 45%, one would expect you'd call alsa_set_volume (45) to do it. But currently, calling alsa_set_volume (45) will set alsa_vol to 50 + 45 = 95%.
So you need to use absolute volume, not relative.
/* newvol: Desired volume level in the [0;100] range */
int alsa_set_volume (int newvol)
{
long volume;
alsa_vol = CLAMP(absvol, 0, 100);
volume = (long)((alsa_vol * (alsa_max - alsa_min) / 100.) + alsa_min);
snd_mixer_selem_set_playback_volume_all(elem, volume);
snd_mixer_selem_set_playback_switch_all(elem, 1);
muted = 0;
mutecount = 0;
return alsa_vol;
}
I am taking about 50 times as long as expected to loop through a simple assignment. My first reaction was that I had disordered my memory access in the arrays, resulting in cache misses. This doesn't seem the case, however.
The pixel value assignment and updating the arrays takes a dogs age. Do any one of you folks have an inclining as to why this is happening? (I am compiling for an iPod with an A4)
memset(columnSumsCurrentFrameA, 0, sizeof(unsigned int) * (_validImageWidth/numSubdivisions) );
memset(rowSumsCurrentFrameA, 0, sizeof(unsigned int) * (_validImageHeight/numSubdivisions) );
int pixelValue = 0;
int startingRow = 0;
int startingColumn = 0;
for (int i = 0; i < _validImageHeight/numSubdivisions; i++)
{
int index = (i + startingRow) * _imageWidth;
for( int j = 0; j < (_validImageWidth/numSubdivisions); j++)
{
pixelValue = imageData[index + startingColumn + j];
columnSumsCurrentFrameA[j] += pixelValue;
rowSumsCurrentFrameA[i] += pixelValue;
}
}
The result of _validImageWidth/numSubdivisions must be an integer, are you sure that is always the case?
Also, you should calculate _validImageWidth/numSubdivisions before entering the double loops, it's not safe to assume your compiler takes care of it.
int limit = _validImageHeight/numSubdivisions;
for (int i = 0; i < limit; i++)
{
int index = (i + startingRow) * _imageWidth;
for( int j = 0; j < limit; j++)
{
pixelValue = imageData[index + startingColumn + j];
columnSumsCurrentFrameA[j] += pixelValue;
rowSumsCurrentFrameA[i] += pixelValue;
}
}