Frequencies - From fft to file to list using processing - processing

I'm doing a project where I'm outputting the frequencies from real time mic input through fft to a txt doc and then retrieving (or trying to retrieve) them to a list of 4 frequencies. My list array is turning out empty, ie the console prints [] and no numbers in them. Pl tell me what is wrong with the logic/code. This is within the void draw()
for (int i = 0; i<fft.specSize(); i++) {
float freq = fft.getFreq(i);
int freqint = (int) freq;
//println(freqint);
output.println(freqint);}
Scanner input = new Scanner("...\\list.txt");
while (input.hasNextInt()) {
list.get(input.nextInt(4));
}
println(list);
input.close();

Split your taks into subtasks:
get FFT data (and 4 frequencies)
Save/Load float values to disk
Put the 1 and 2 together
It looks like you already have the first part done.
It's unclear what the 4 frequencies are, but you can figure that out on your own.
The part that is confusing is that you call the get FFT data once then try to save it straight to disk. I'm not 100% that's what you mean to do.
Double check if you need to save few samples/seconds worth of FFT data first.
I would imagine a more generic scenario like this:
load previously saved FFT data (if any)
process FFT data (for as long as needed - might need a start/stop boolean) and append
save current FFT data
Moving on to saving and loading data.
You've got a few of options build into Processing for storing data:
Strings via saveStrings()/loadStrings()
CSV Table via saveTable()/loadTable()/Table
JSON via JSONObject/JSONArray and available load/save functions
XML
I recommend reading Daniel Shiffman's Data Tutorial
Dealing with saving/loading floating point values to disk alone,
here's a basic proof of concept snippet using Strings:
int fftSpecSize = 10;//this will be fft.specSize() in your case
String values = "";
for(int i = 0 ; i < fftSpecSize; i++){
//random(1) is a placeholder for fft.getFreq(i);
values += random(1);
//if it's not the last value, add a separator character (in this case space)
if(i < fftSpecSize-1){
values += " ";
}
}
println("values to save:");
println(values);
println();
//save data
saveStrings("fftSingleRead.txt",values.split(" "));
//load data
String[] readValues = loadStrings("fftSingleRead.txt");
//print raw loaded data
println("readValues from .txt file:");
println(readValues);
println();
//parse values:
for(int i = 0 ; i < readValues.length; i++){
float value = float(readValues[i]);
println("readValues[",i,"] = ",value);
}
additionally here's a Table example too:
Table fftValues;
int specSize = 10;
//create a new table
fftValues = new Table();
//add columns - one per FFT bin
for(int i = 0 ; i < specSize; i++){
fftValues.addColumn();
}
//add some data, a row per reading
//create a new row
TableRow newRow = fftValues.addRow();
//add each fft value to the row
for(int fftCount = 0 ; fftCount < specSize; fftCount++){
//placeholder for newRow.setFloat(fftCount,fft.getFreq(fftCount));
newRow.setFloat(fftCount,random(1));
}
//add the row to the table
fftValues.addRow(newRow);
//save to disk
saveTable(fftValues,"fftValues.csv","csv");
//load from disk
Table readValues = loadTable("fftValues.csv","csv");
//access the data that has been saved in the table
for(int rowCount = 0; rowCount < readValues.getRowCount(); rowCount++){
TableRow currentRow = readValues.getRow(rowCount);
print("row[",rowCount,"] = ");
for(int columnCount = 0; columnCount < currentRow.getColumnCount(); columnCount++){
float value = currentRow.getFloat(columnCount);
print(value);
if(columnCount < currentRow.getColumnCount() - 1){
print(",");
}
}
println();
}
Try the code, see the output, read the comments, read the reference, tweak/retry/understand and adapt to your problem.

Related

Itext7 - How to create pdf with 2 columns and 4 rows per page with images in java

I have following code to create a single pdf with 2 columns and 4 rows. Every cell contains an image.
int labelCount = x;
int columns = 2;
int labelsPerPage = 8;
int rows = labelCount/columns;
int resto = labelCount%columns;
if(resto>0) rows++;
String dest = "path_to_pdf_file";
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
Document doc = new Document(pdfDoc);
doc.setMargins(0, 0, 0, 0);
Table table = new Table(UnitValue.createPercentArray(columns)).useAllAvailableWidth();
Integer iCount = 0;
for (int i = 1; i <= rows; i++) {
for (int y = 1; y <= columns; y++) {
if(iCount<labelCount) {
String fileName = "name_of_image";
Cell cell = new Cell();
cell.add(new com.itextpdf.layout.element.Image(ImageDataFactory.create("full_path_to_image")).setAutoScale(true));
cell.setBorder(Border.NO_BORDER);
table.addCell(cell);
iCount++;
if(iCount==labelsPerPage-1) {
doc.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
}
}
}
}
doc.add(table);
doc.close();
If number of labels is bigger than defined limit (8 per page), I want a new page to be created with the following labels.
In my code I used
doc.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
but it generate (I don't know why) a blank page at the beginning. In the second page there are labels.
Which is the right way to add a new page dynamically and put remaining content into it?
Thanks
Essentially in your code you add AreaBreak to the document before you add the table, that's why the blank page is inserted before the table. iText 7 does not allow you to insert page breaks within tables at this point.
To achieve the desired result you need to flush the existing table to the document before moving on to the next page, and create a new table for the next page. Essentially you will be adding a bunch of tables separated with AreaBreak.
The pseudocode which does not require a lot of modifications to your code could look as follows:
Table table = new Table();
for (...) {
// populate table
if ("it's time to insert a page break") {
doc.add(table);
doc.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
table = new Table(); // create new table
}
}
doc.add(table);

Copying rendered value instead of the data value

I use Handsontable and in one column, the data type is an integer that is an index of a vector of strings v. So, instead of showing the integer index i, I have to show v[i]. I do so by declaring a custom renderer in handsontable:
var annotationTableSettings = {
data: componentAnnotation,
columns: [
{renderer: annotationId2StringRenderer},
...
However, when I copy the value of the cell (Ctrl+c in windows/linux or cmd+c in mac), the integer is copied instead of the rendered value. Does anyone know how to copy the rendered value (I would like to keep the integer data type and the custom renderer).
An example can be seen here: http://leoisl.gitlab.io/DBGWAS_support/full_dataset_visualization_0_4_6/components/comp_2.html
Just copy the first cell of the first line of the first table (in the north panel) - the cell with value "(Phe)CML" and you will copy the value 3, instead of "(Phe)CML" itself.
Thanks in advance!
you can use the beforeCopy hook.
var annotationTableSettings = {
data: componentAnnotation,
beforeCopy: data => {
for (let i = 0; i < data.length; i++) {
for (let j = 0; j < data[i].length; j++) {
if (!isNaN(data[i][j])) {
data[i][j] = v[data[i][j]]
}
}
}
}
columns: [
{renderer: annotationId2StringRenderer},
...

How can I hide selected ranges AND sort the displayed results (Aspose Cells)?

I can sort (descending) my displayed results by a selected value using this code:
PivotField field = pivotTable.RowFields[0];
field.IsAutoSort = true;
field.IsAscendSort = false;
field.AutoSortField = 1;
This is what I see (Total Purchases displayed are indeed shown from most to least):
Or, I can only display Description ranges whose "Percentage of Total" value is at least 1% with this code:
private void HideItemsWithFewerThan1PercentOfSales()
{
int FIRST_TOTAL_PRICE_ROW = 8;
int ROWS_BETWEEN_PERCENTAGES = 4;
var pivot = pivotTableSheet.PivotTables[0];
var dataBodyRange = pivot.DataBodyRange;
int currentRowBeingExamined = FIRST_TOTAL_PRICE_ROW;
int rowsUsed = dataBodyRange.EndRow;
pivot.RefreshData();
pivot.CalculateData();
// Get grand total of purchases for all items and months, and calculate what 1% of that is
Cell totalTotalPurchasesCell = pivotTableSheet.Cells[rowsUsed - 2, _grandTotalsColumnPivotTable + 1];
double totalTotalPurchases = Convert.ToDouble(totalTotalPurchasesCell.Value);
var onePercentOfTotalPurchases = totalTotalPurchases / 100;
// Loop through PivotTable data, hiding where percentage < 0.01 (1%)
while (currentRowBeingExamined < rowsUsed)
{
Cell priceCell = pivotTableSheet.Cells[currentRowBeingExamined, _grandTotalsColumnPivotTable + 1];
String priceStr = priceCell.Value.ToString();
Double price = Convert.ToDouble(priceStr);
if (price < onePercentOfTotalPurchases)
{
pivotTableSheet.Cells.HideRows(currentRowBeingExamined - 1, ROWS_BETWEEN_PERCENTAGES);
}
currentRowBeingExamined = currentRowBeingExamined + ROWS_BETWEEN_PERCENTAGES;
}
}
...like so:
...but I can't get them both to work at the same time. So I can either hide the Descriptions with less than 1% of the percntage OR I can sort by Total Purchases descending, but I'm not able to accomplish both at the same time. My code to try to accomplish both is as follows:
. . .
pivotTable.AddFieldToArea(PivotFieldType.Row, DESCRIPTION_COLUMN);
pivotTable.RowHeaderCaption = "Description";
// Dragging the second field to the column area.
pivotTable.AddFieldToArea(PivotFieldType.Column, MONTHYR_COLUMN);
pivotTable.ColumnHeaderCaption = "Months";
// Dragging the third field to the data area.
pivotTable.AddFieldToArea(PivotFieldType.Data, TOTALQTY_COLUMN);
pivotTable.DataFields[0].DisplayName = "Total Packages";
pivotTable.AddFieldToArea(PivotFieldType.Data, TOTALPRICE_COLUMN);
pivotTable.DataFields[1].DisplayName = "Total Purchases";
. . .
// Sort by "Total Purchases" descending
PivotField field = pivotTable.RowFields[0];
field.IsAutoSort = true;
field.IsAscendSort = false;
field.AutoSortField = 1; // This is the "Total Purchases" field
pivotTable.PivotTableStyleType = PivotTableStyleType.PivotTableStyleLight16;
pivotTable.RefreshDataFlag = true;
pivotTable.RefreshData();
pivotTable.CalculateData();
pivotTable.RefreshDataFlag = false;
List<String> contractItemDescs = GetContractItemDescriptions();
ColorizeContractItemBlocks(contractItemDescs);
HideItemsWithFewerThan1PercentOfSales();
FreezePanePivotTable(HEADER_ROW, 2);
FormatPivotTableNumbers();
ConfigureForPrinting(pivotTableSheet.Cells.Rows.Count);
It's as if the sorting order is not being respected when HideItemsWithFewerThan1PercentOfSales() is called - the row numbers that method "sees" is not the row numbers according to the sorting that has been established.
How can I get both the sorting AND the hiding to work?
NOTE: Calling HideItemsWithFewerThan1PercentOfSales(); prior to the sorting code does NOT work - it still shows/hides some of the wrong things.
Please check the reply in this thread in Aspose.Cells forum.
Note: I am working as Developer Evangelist at Aspose

Java JLabel.getLocation() always returning 0

I'm studying Java so I'm pretty new.
I'm creating a simple 'maze' type game using GUI layouts, images, labels ect..
To create my maze layouts I used an array of strings;
mazeLayout[0] = "WWWWWWWWWW";
mazeLayout[1] = "WSSSWWSWWW";
mazeLayout[2] = "WSWSWWSSSW";
mazeLayout[3] = "WSWSWWWWSW";
mazeLayout[4] = "WSWSWWWWSW";
mazeLayout[5] = "WSWSWSSSSW";
mazeLayout[6] = "WSWSWSWWWW";
mazeLayout[7] = "WSWSWSWWWW";
mazeLayout[8] = "WSWSSSWWWW";
mazeLayout[9] = "WWWWWWWWWW";
and then converted this into a 2d array and placed a label with in image icon in it depending on the string being 'W' for wall or 'S' for space. Also the labels are an array, my thoughts behind this was for restricting movement of the player so they can't walk though walls.
int mw = 0;
int mf = 0;
for(int y = 0; y < 10; y++){
for(int x = 0; x < 10; x++){
mazeLayout2d[y][x] = mazeLayout[y].substring(x, x+1);
if (mazeLayout2d[y][x].equals("W")){
lblmazewall[mw] = new JLabel();
mazewall = new ImageIcon("mazewall.png");
lblmazewall[mw].setIcon(mazewall);
pCenter.add(lblmazewall[mw]);
mw++;
pCenter.revalidate();
}
if (mazeLayout2d[y][x].equals("S")){
lblmazefloor[mf] = new JLabel();
mazefloor = new ImageIcon("mazefloor.png");
lblmazefloor[mf].setIcon(mazefloor);
pCenter.add(lblmazefloor[mf]);
mf++;
pCenter.revalidate();
}
}
}
My problem is when i run this line
System.out.println(lblmazewall[x].getLocation()); //x being any number
I always get java.awt.Point[x=0,y=0]
I would like to know how to get the location of each wall label so i can check it against my player movement.
Is this even a valid way to do something like this?
Could someone teach me a more efficient way?
Sorry for my crude snippets and or bad programming
Thankyou Niall.
public Point getLocation()
Due to the asynchronous nature of native event handling, this method can return outdated values (for instance, after several calls of setLocation() in rapid succession). For this reason, the recommended method of obtaining a component's position is within java.awt.event.ComponentListener.componentMoved(), which is called after the operating system has finished moving the component.
The layout might not have used setLocation() internally. So that getLocation() does not return the value as expected.

BIRT Palette scripting: How to access dataset row

If I want to change the color of circles in scatter chart based on a field not being used in the chart, then how do i use that column in script. I mean how can i get the that data...for example
If (row[v_count])>2
fill red color...
The exact code is below
function beforeDrawDataPoint(dph, fill, icsc)
{
//Fill implements Fill interface
//ImageImpl
//ColorDefinitionImpl
//GradientImpl
//MultipleFillImpl
//EmbeddedImageImpl
//PatternImageImpl
importPackage( Packages.org.eclipse.birt.chart.model.attribute.impl );
val = dph.getOrthogonalValue();
if( fill.getClass().isAssignableFrom(ColorDefinitionImpl)){
if (row[v_count]>2){
fill.set(255, 0, 0);
}
}
}
but i dont know do i get that v_count column in the script. is there some function to get that column ?
I mean if we are making some calculations based on a column from databinding columns..that is not being used in x or y axis, then how do we access that column in the script..is there some kind of function for that.. I tried row["v_count"], but it is not working.
Arif
You could use "persistent global variables". In any place of your report you can write the following to store and load a global variable. Note that you cannot store Integers but only Strings (but after loading you can cast your Strings back to other types). You could store the Value of your column in the Script of an invisible data field located above your chart, so inside your chart you can read the value.
//store a value
reportContext.setPersistentGlobalVariable("varName", "value");
//load the value
var load = reportContext.getPersistentGlobalVariable("varName");
I spend my day look but I did not find the solution, this is my colleague who give me :)
So I share.
in my example I had to create a vertical marker for every new year
function beforeGeneration(chart, icsc)
{
importPackage(Packages.org.eclipse.birt.chart.model.component.impl);
importPackage(Packages.org.eclipse.birt.chart.model.data.impl);
importPackage(Packages.org.eclipse.birt.chart.model.attribute);
importPackage(Packages.org.eclipse.birt.chart.model.attribute.impl);
var chart = icsc.getChartInstance();
var yAxis = chart.getBaseAxes()[0];
//get date series for my case
series = yAxis.getRuntimeSeries();
// but if you have multiple series ... (for exemple xaxis)
for (i = 0; i < series.length; i++){
var values = series[i].getDataSet().getValues();
for (j = 0; j < values.length; j++){
if(j > 1){
var date1 = values[j-1];
var date2 = values[j];
if(date1.getYear() < date2.getYear()){
min_ml = MarkerLineImpl.create(yAxis, NumberDataElementImpl.create(j));
min_ml.getLabel().getCaption().setValue("Nouveau boitier");
min_ml.getLineAttributes().getColor().set(255,0,0);
}
}
}
}
}

Resources